This file is indexed.

/usr/include/android/libdex/DexUtf.h is in android-libdex-dev 7.0.0+r33-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Validate and manipulate MUTF-8 (modified UTF-8) encoded string data.
 */

#ifndef LIBDEX_DEXUTF_H_
#define LIBDEX_DEXUTF_H_

#include "DexFile.h"

/*
 * Retrieve the next UTF-16 character from a UTF-8 string.
 *
 * Advances "*pUtf8Ptr" to the start of the next character.
 *
 * WARNING: If a string is corrupted by dropping a '\0' in the middle
 * of a 3-byte sequence, you can end up overrunning the buffer with
 * reads (and possibly with the writes if the length was computed and
 * cached before the damage). For performance reasons, this function
 * assumes that the string being parsed is known to be valid (e.g., by
 * already being verified). Most strings we process here are coming
 * out of dex files or other internal translations, so the only real
 * risk comes from the JNI NewStringUTF call.
 */
DEX_INLINE u2 dexGetUtf16FromUtf8(const char** pUtf8Ptr)
{
    unsigned int one, two, three;

    one = *(*pUtf8Ptr)++;
    if ((one & 0x80) != 0) {
        /* two- or three-byte encoding */
        two = *(*pUtf8Ptr)++;
        if ((one & 0x20) != 0) {
            /* three-byte encoding */
            three = *(*pUtf8Ptr)++;
            return ((one & 0x0f) << 12) |
                   ((two & 0x3f) << 6) |
                   (three & 0x3f);
        } else {
            /* two-byte encoding */
            return ((one & 0x1f) << 6) |
                   (two & 0x3f);
        }
    } else {
        /* one-byte encoding */
        return one;
    }
}

/* Compare two '\0'-terminated modified UTF-8 strings, using Unicode
 * code point values for comparison. This treats different encodings
 * for the same code point as equivalent, except that only a real '\0'
 * byte is considered the string terminator. The return value is as
 * for strcmp(). */
int dexUtf8Cmp(const char* s1, const char* s2);

/* for dexIsValidMemberNameUtf8(), a bit vector indicating valid low ascii */
extern u4 DEX_MEMBER_VALID_LOW_ASCII[4];

/* Helper for dexIsValidMemberUtf8(); do not call directly. */
bool dexIsValidMemberNameUtf8_0(const char** pUtf8Ptr);

/* Return whether the pointed-at modified-UTF-8 encoded character is
 * valid as part of a member name, updating the pointer to point past
 * the consumed character. This will consume two encoded UTF-16 code
 * points if the character is encoded as a surrogate pair. Also, if
 * this function returns false, then the given pointer may only have
 * been partially advanced. */
DEX_INLINE bool dexIsValidMemberNameUtf8(const char** pUtf8Ptr) {
    u1 c = (u1) **pUtf8Ptr;
    if (c <= 0x7f) {
        // It's low-ascii, so check the table.
        u4 wordIdx = c >> 5;
        u4 bitIdx = c & 0x1f;
        (*pUtf8Ptr)++;
        return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0;
    }

    /*
     * It's a multibyte encoded character. Call a non-inline function
     * for the heavy lifting.
     */
    return dexIsValidMemberNameUtf8_0(pUtf8Ptr);
}

/* Return whether the given string is a valid field or method name. */
bool dexIsValidMemberName(const char* s);

/* Return whether the given string is a valid type descriptor. */
bool dexIsValidTypeDescriptor(const char* s);

/* Return whether the given string is a valid internal-form class
 * name, with components separated either by dots or slashes as
 * specified. A class name is like a type descriptor, except that it
 * can't name a primitive type (including void). In terms of syntax,
 * the form is either (a) the name of the class without adornment
 * (that is, not bracketed by "L" and ";"); or (b) identical to the
 * type descriptor syntax for array types. */
bool dexIsValidClassName(const char* s, bool dotSeparator);

/* Return whether the given string is a valid reference descriptor. This
 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
 * is for a class or array and not a primitive type. */
bool dexIsReferenceDescriptor(const char* s);

/* Return whether the given string is a valid class descriptor. This
 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
 * is for a class and not an array or primitive type. */
bool dexIsClassDescriptor(const char* s);

/* Return whether the given string is a valid field type descriptor. This
 * is true if dexIsValidTypeDescriptor() returns true and the descriptor
 * is for anything but "void". */
bool dexIsFieldDescriptor(const char* s);

#endif  // LIBDEX_DEXUTF_H_