{"record":{"id":"8e46a98fb92e901f","repo":"oracle/graal","slug":"array-type-with-more-than-255-dimensions","errorCode":null,"errorMessage":"Array type with more than 255 dimensions","messagePattern":"Array type with more than 255 dimensions","errorType":"exception","errorClass":"ParserException.ClassFormatError","httpStatus":null,"severity":"error","filePath":"espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/descriptors/TypeSymbols.java","lineNumber":260,"sourceCode":"            }\n        }\n        throw new ParserException.ClassFormatError(\"Invalid type descriptor \" + descriptor.subSequence(beginIndex));\n    }\n\n    /**\n     * Gets the type descriptor for the specified component type descriptor with the specified\n     * number of dimensions. For example if the number of dimensions is 1, then this method will\n     * return a descriptor for an array of the component type; if the number of dimensions is 2, it\n     * will return a descriptor for an array of an array of the component type, etc.\n     *\n     * @param type the type descriptor for the component type of the array\n     * @param dimensions the number of array dimensions\n     * @return the canonical type descriptor for the specified component type and dimensions\n     */\n    public Symbol<Type> arrayOf(Symbol<Type> type, int dimensions) {\n        assert dimensions > 0;\n        if (TypeSymbols.getArrayDimensions(type) + dimensions > 255) {\n            throw new ParserException.ClassFormatError(\"Array type with more than 255 dimensions\");\n        }\n        // Prepend #dimensions '[' to type descriptor.\n        byte[] bytes = new byte[type.length() + dimensions];\n        Arrays.fill(bytes, 0, dimensions, (byte) '[');\n        type.writeTo(bytes, dimensions);\n        return symbols.getOrCreate(ByteSequence.wrap(bytes));\n    }\n\n    public Symbol<Type> arrayOf(Symbol<Type> type) {\n        return arrayOf(type, 1);\n    }\n\n    private static int skipClassName(Symbol<? extends Descriptor> descriptor, int from, final char separator) throws ParserException.ClassFormatError {\n        assert separator == '.' || separator == '/';\n        int index = from;\n        final int length = descriptor.length();\n        while (index < length) {\n            // Safe cast, method returns only for ./;[ characters.","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/descriptors/TypeSymbols.java#L242-L278","documentation":"Espresso's TypeSymbols.arrayOf(Symbol<Type>, int) constructs an array type descriptor by prepending 'dimensions' '[' bytes to the component descriptor. The JVM class file format caps array types at 255 dimensions, so the factory throws ParserException.ClassFormatError when the component's existing dimension count plus the requested dimensions exceeds 255.","triggerScenarios":"Calling arrayOf(type, n) where TypeSymbols.getArrayDimensions(type) + n > 255, e.g. arrayOf(inner, 256) or arrayOf(existing200DimArray, 60). Also reached when parsing/loading a class whose descriptor string contains more than 255 consecutive '[' characters.","commonSituations":"Bytecode generators or class-file manipulators running on Espresso that build nested array descriptors in a loop; fuzzed or hostile class files; tests probing JVM array limits.","solutions":["If you generate descriptors in a loop, track dimensions and stop/cap at 255 before calling arrayOf.","If the error comes from loading a class, inspect the offending descriptor in the class file and fix the producer of that class.","Validate third-party/generated class files (e.g. with a verifier like ASM CheckClassAdapter) before feeding them to Espresso."],"exampleFix":"// before\nSymbol<Type> t = type;\nfor (int i = 0; i < 300; i++) { t = symbols.arrayOf(t); } // throws at 256th iteration\n\n// after\nSymbol<Type> t = type;\nfor (int i = 0; i < 300 && TypeSymbols.getArrayDimensions(t) < 255; i++) { t = symbols.arrayOf(t); }","handlingStrategy":"validation","validationCode":"static int dimsOf(Symbol<Type> t) { return TypeSymbols.getArrayDimensions(t); }\nstatic boolean canAddDimensions(Symbol<Type> t, int n) {\n    return n > 0 && dimsOf(t) + n <= 255;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Track dimension count in any loop that calls arrayOf and cap it at 255.","Verify generated class files with a descriptor-aware checker before loading them into Espresso.","Treat descriptors with 200+ '[' as hostile input in fuzzing/test harnesses."],"tags":["jvm","classfile","array","espresso","descriptor"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}