{"record":{"id":"41c35db2addfdd8b","repo":"oracle/graal","slug":"value-is-larger-than-32-bits","errorCode":null,"errorMessage":"Value is larger than 32-bits","messagePattern":"Value is larger than 32-bits","errorType":"exception","errorClass":"ArithmeticException","httpStatus":null,"severity":"error","filePath":"espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/cds/LEB128.java","lineNumber":38,"sourceCode":" * or visit www.oracle.com if you need additional information or have any\n * questions.\n */\npackage com.oracle.truffle.espresso.cds;\n\nimport java.util.function.IntConsumer;\nimport java.util.function.IntSupplier;\n\npublic final class LEB128 {\n\n    public static int readUnsignedInt(IntSupplier readByte) {\n        int result = 0;\n        for (int i = 0;; ++i) {\n            byte b = (byte) readByte.getAsInt();\n            result |= (b & 0x7F) << (i * 7);\n            // The first 4 groups of 7 bits are guaranteed to fit (4 * 7 = 28 bits).\n            // That leaves room for only the 4 low-order bits from the 5th group (which has index 4)\n            if (i == 4 && (b & 0xF0) != 0) {\n                throw new ArithmeticException(\"Value is larger than 32-bits\");\n            }\n            if ((b & 0x80) == 0) {\n                return result;\n            }\n        }\n    }\n\n    public static void writeUnsignedInt(IntConsumer writeByte, int value) {\n        int tmp = value;\n        do {\n            int b = tmp & 0x7F;\n            tmp >>>= 7;\n            if (tmp != 0) {\n                b |= 0x80;\n            }\n            writeByte.accept(b & 0xFF);\n        } while (tmp != 0);\n    }","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/cds/LEB128.java#L20-L56","documentation":"LEB128.readUnsignedInt decodes an unsigned LEB128 varint and refuses values that do not fit in 32 bits: the 5th 7-bit group must contribute at most 4 bits (bits 28..31). If the 5th byte has any of bits 4-7 set (b & 0xF0 != 0), the encoded value exceeds Integer.MAX_VALUE and an ArithmeticException is thrown. In the CDS reader this indicates a malformed or corrupted variable-length integer in the archive stream.","triggerScenarios":"Any CDS archive read that decodes a varint (lengths, refIds, counts) where the byte stream is truncated, shifted, or corrupt so that the 5th continuation group carries high bits. Also any direct use of LEB128.readUnsignedInt on data encoded by a 64-bit varint writer (values >= 2^32).","commonSituations":"Truncated CDS archive (partial download, interrupted write, disk filling up mid-write); archive written by a different/newer format that encodes 64-bit lengths; byte-order or offset bug in custom code feeding the decoder; archive regenerated on a machine with a much larger heap producing sizes > 2GB encoded as 64-bit.","solutions":["Regenerate the CDS archive from scratch with the current Espresso version so the varint stream is self-consistent.","Verify archive integrity (file size, checksum) after copying/downloading it; a truncated tail commonly lands exactly here.","Check that the archive was produced by the same CDSArchiveFormat version (see the header version checks in Reader.readHeader).","If you call LEB128.readUnsignedInt on your own data, ensure the encoder (LEB128.writeUnsignedInt) only ever receives values that fit in an int."],"exampleFix":"// before\nint v = LEB128.readUnsignedInt(in); // throws for values >= 2^32\n\n// after\n// encode with the matching int-width writer\nLEB128.writeUnsignedInt(out, value); // value always < 2^31","handlingStrategy":"validation","validationCode":"static boolean fitsUnsigned32(long v) { return (v & 0xFFFFFFFFL) == v && (v >>> 28) == 0 || Long.compareUnsigned(v, 1L << 28) < 0 || (v >>> 28) <= 0xF; }\n// simpler: check before writing\nif (Integer.toUnsignedLong(value) >= (1L << 32)) throw new IllegalArgumentException(\"value exceeds 32-bit unsigned\");","typeGuard":null,"tryCatchPattern":"try {\n    int v = LEB128.readUnsignedInt(readByte);\n} catch (ArithmeticException e) {\n    // stream corrupt or 64-bit varint: fail the whole read, do not resync\n    throw new IllegalArgumentException(\"Corrupt varint in stream\", e);\n}","preventionTips":["Only pair readUnsignedInt with writeUnsignedInt (never a 64-bit varint writer).","Checksum CDS archives after generation and verify before reading to catch truncation.","Never attempt to resync a LEB128 stream mid-value; treat any ArithmeticException as fatal corruption."],"tags":["cds","leb128","varint","corrupt-data","arithmetic-exception"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}