{"record":{"id":"9130e6dbe468e377","repo":"pxb1988/dex2jar","slug":"bad-second-byte","errorCode":null,"errorMessage":"bad second byte","messagePattern":"bad second byte","errorType":"exception","errorClass":"UTFDataFormatException","httpStatus":null,"severity":"error","filePath":"dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java","lineNumber":48,"sourceCode":"    }\n\n    /**\n     * Decodes bytes from {@code in} into {@code sb} until a delimiter 0x00 is encountered. Returns a new string\n     * containing the decoded characters.\n     */\n    public static String decode(ByteBuffer in, StringBuilder sb) throws UTFDataFormatException {\n        while (true) {\n            char a = (char) (in.get() & 0xff);\n            if (a == 0) {\n                return sb.toString();\n            }\n\n            if (a < '\\u0080') {\n                sb.append(a);\n            } else if ((a & 0xe0) == 0xc0) {\n                int b = in.get() & 0xff;\n                if ((b & 0xC0) != 0x80) {\n                    throw new UTFDataFormatException(\"bad second byte\");\n                }\n                sb.append((char) (((a & 0x1F) << 6) | (b & 0x3F)));\n            } else if ((a & 0xf0) == 0xe0) {\n                int b = in.get() & 0xff;\n                int c = in.get() & 0xff;\n                if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {\n                    throw new UTFDataFormatException(\"bad second or third byte\");\n                }\n                sb.append((char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F)));\n            } else {\n                throw new UTFDataFormatException(\"bad byte\");\n            }\n        }\n    }\n\n    /**\n     * Returns the number of bytes the modified UTF8 representation of 's' would take.\n     */","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/pxb1988/dex2jar/blob/b5bda4fb4935ae8b3869b422454ae3b3896c7bc1/dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java#L30-L66","documentation":"Thrown by Mutf8.decode when decoding Modified UTF-8: a lead byte indicated a 2-byte sequence (0xC0-0xDF), but the next byte read from the ByteBuffer is not a continuation byte (top bits not 10). The input byte stream is not valid Modified UTF-8, so decoding aborts with UTFDataFormatException.","triggerScenarios":"Decoding a DEX string_data item (or other MUTF-8 blob) whose second byte of a 2-byte sequence is corrupted, misaligned, or the decoder is pointed at the wrong offset.","commonSituations":"Corrupted or hand-edited DEX files, wrong string offsets after incorrect parsing of string_ids/data offsets, truncated buffers where read position drifts into non-UTF data.","solutions":["Verify the string offset is correct: re-parse string_ids_off and ensure the decoder starts at the ULEB128 length prefix, not inside the data","Check the DEX file is not truncated or corrupted; re-obtain or rebuild it with dx/d8","Wrap decode in try-catch for UTFDataFormatException and treat the file as invalid rather than crashing"],"exampleFix":"// before\nString s = Mutf8.decode(buffer, new int[1]); // crashes on corrupt data\n// after\nint[] pos = new int[1];\ntry {\n    String s = Mutf8.decode(buffer, pos);\n} catch (UTFDataFormatException e) {\n    throw new IllegalStateException(\"corrupt DEX string at \" + pos[0], e);\n}","handlingStrategy":"validation","validationCode":"static boolean looksLikeMutf8(java.nio.ByteBuffer in, int start) {\n    for (int i = start; i < in.limit(); i++) {\n        int a = in.get(i) & 0xff;\n        if (a >= 0xF0) return false;\n        if ((a & 0xE0) == 0xC0 || (a & 0xF0) == 0xE0) {\n            if (i + 1 >= in.limit() || ((in.get(i + 1) & 0xC0) != 0x80)) return false;\n            i += 1;\n        }\n    }\n    return true;\n}","typeGuard":"boolean isValidMutf8Lead(int a) { return (a & 0x80) == 0 || (a & 0xE0) == 0xC0 || (a & 0xF0) == 0xE0; }","tryCatchPattern":"try { String s = Mutf8.decode(buf, pos); } catch (UTFDataFormatException e) { log.warn(\"bad MUTF-8 at \" + pos[0]); return null; }","preventionTips":["Always decode starting at the correct string_data offset (after the ULEB128 length)","Validate DEX checksum/signature before parsing strings","Treat decode failures as file corruption, not a library bug"],"tags":["utf-8","dex","decoding","corrupt-input"],"backgroundTag":"invalid-argument-format","analyzedSha":"b5bda4fb4935ae8b3869b422454ae3b3896c7bc1","analyzedAt":"2026-09-08T00:44:01.258Z","contentChangedAt":"2026-09-08T00:44:01.258Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}