Exemple #1
0
/* Return whether the given string is a valid field or method name. */
bool dexIsValidMemberName(const char* s) {
    bool angleName = false;

    switch (*s) {
        case '\0': {
            // The empty string is not a valid name.
            return false;
        }
        case '<': {
            /*
             * '<' is allowed only at the start of a name, and if present,
             * means that the name must end with '>'.
             */
            angleName = true;
            s++;
            break;
        }
    }

    for (;;) {
        switch (*s) {
            case '\0': {
                return !angleName;
            }
            case '>': {
                return angleName && s[1] == '\0';
            }
        }
        if (!dexIsValidMemberNameUtf8(&s)) {
            return false;
        }
    }
}
Exemple #2
0
/* Return whether the given string is a valid type descriptor. */
bool dexIsValidTypeDescriptor(const char* s) {
    int arrayCount = 0;

    while (*s == '[') {
        arrayCount++;
        s++;
    }

    if (arrayCount > 255) {
        // Arrays may have no more than 255 dimensions.
        return false;
    }

    switch (*(s++)) {
        case 'B':
        case 'C':
        case 'D':
        case 'F':
        case 'I':
        case 'J':
        case 'S':
        case 'Z': {
            // These are all single-character descriptors for primitive types.
            return (*s == '\0');
        }
        case 'V': {
            // You can't have an array of void.
            return (arrayCount == 0) && (*s == '\0');
        }
        case 'L': {
            // Break out and continue below.
            break;
        }
        default: {
            // Oddball descriptor character.
            return false;
        }
    }

    // We just consumed the 'L' that introduces a class name.

    bool slashOrFirst = true; // first character or just encountered a slash
    for (;;) {
        u1 c = (u1) *s;
        switch (c) {
            case '\0': {
                // Premature end.
                return false;
            }
            case ';': {
                /*
                 * Make sure that this is the end of the string and that
                 * it doesn't end with an empty component (including the
                 * degenerate case of "L;").
                 */
                return (s[1] == '\0') && !slashOrFirst;
            }
            case '/': {
                if (slashOrFirst) {
                    // Slash at start or two slashes in a row.
                    return false;
                }
                slashOrFirst = true;
                s++;
                break;
            }
            default: {
                if (!dexIsValidMemberNameUtf8(&s)) {
                    return false;
                }
                slashOrFirst = false;
                break;
            }
        }
    }
}
Exemple #3
0
/* Helper for validating type descriptors and class names, which is parametric
 * with respect to type vs. class and dot vs. slash. */
static bool isValidTypeDescriptorOrClassName(const char* s, bool isClassName,
        bool dotSeparator) {
    int arrayCount = 0;

    while (*s == '[') {
        arrayCount++;
        s++;
    }

    if (arrayCount > 255) {
        // Arrays may have no more than 255 dimensions.
        return false;
    }

    if (arrayCount != 0) {
        /*
         * If we're looking at an array of some sort, then it doesn't
         * matter if what is being asked for is a class name; the
         * format looks the same as a type descriptor in that case, so
         * treat it as such.
         */
        isClassName = false;
    }

    if (!isClassName) {
        /*
         * We are looking for a descriptor. Either validate it as a
         * single-character primitive type, or continue on to check the
         * embedded class name (bracketed by "L" and ";").
         */
        switch (*(s++)) {
            case 'B':
            case 'C':
            case 'D':
            case 'F':
            case 'I':
            case 'J':
            case 'S':
            case 'Z': {
                // These are all single-character descriptors for primitive types.
                return (*s == '\0');
            }
            case 'V': {
                // Non-array void is valid, but you can't have an array of void.
                return (arrayCount == 0) && (*s == '\0');
            }
            case 'L': {
                // Class name: Break out and continue below.
                break;
            }
            default: {
                // Oddball descriptor character.
                return false;
            }
        }
    }

    /*
     * We just consumed the 'L' that introduces a class name as part
     * of a type descriptor, or we are looking for an unadorned class
     * name.
     */

    bool sepOrFirst = true; // first character or just encountered a separator.
    for (;;) {
        u1 c = (u1) *s;
        switch (c) {
            case '\0': {
                /*
                 * Premature end for a type descriptor, but valid for
                 * a class name as long as we haven't encountered an
                 * empty component (including the degenerate case of
                 * the empty string "").
                 */
                return isClassName && !sepOrFirst;
            }
            case ';': {
                /*
                 * Invalid character for a class name, but the
                 * legitimate end of a type descriptor. In the latter
                 * case, make sure that this is the end of the string
                 * and that it doesn't end with an empty component
                 * (including the degenerate case of "L;").
                 */
                return !isClassName && !sepOrFirst && (s[1] == '\0');
            }
            case '/':
            case '.': {
                if (dotSeparator != (c == '.')) {
                    // The wrong separator character.
                    return false;
                }
                if (sepOrFirst) {
                    // Separator at start or two separators in a row.
                    return false;
                }
                sepOrFirst = true;
                s++;
                break;
            }
            default: {
                if (!dexIsValidMemberNameUtf8(&s)) {
                    return false;
                }
                sepOrFirst = false;
                break;
            }
        }
    }
}