{"record":{"id":"e05447587da24e7c","repo":"iBotPeaches/Apktool","slug":"illegal-backwards-jump-from-s-to-s","errorCode":null,"errorMessage":"Illegal backwards jump from %s to %s","messagePattern":"Illegal backwards jump from (.+?) to (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"brut.j.util/src/main/java/brut/util/BinaryDataInputStream.java","lineNumber":86,"sourceCode":"    public long limit() {\n        return mLimit;\n    }\n\n    public long position() {\n        return mPosition;\n    }\n\n    public long remaining() {\n        return mLimit - mPosition;\n    }\n\n    public long jumpTo(long pos) throws IOException {\n        long expected = pos - mPosition;\n        if (expected == 0) {\n            return 0;\n        }\n        if (expected < 0) {\n            throw new IOException(String.format(\"Illegal backwards jump from %s to %s\", mPosition, pos));\n        }\n        long skipped = skip(expected);\n        if (skipped != expected) {\n            throw new IOException(String.format(\"Jump failed: skipped %s bytes (expected: %s)\", skipped, expected));\n        }\n        return skipped;\n    }\n\n    public void skipByte() throws IOException {\n        //noinspection ResultOfMethodCallIgnored\n        readByte();\n    }\n\n    public void skipShort() throws IOException {\n        //noinspection ResultOfMethodCallIgnored\n        readShort();\n    }\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.j.util/src/main/java/brut/util/BinaryDataInputStream.java#L68-L104","documentation":"BinaryDataInputStream.jumpTo(pos) only supports seeking forward over the underlying stream by skipping; requesting a position before the current one throws this IOException. It is a parser-level invariant violation, not a stream failure: the caller computed an offset that lies behind the read cursor.","triggerScenarios":"Parsing resources.arsc/AXML where a chunk length or string-pool offset points backwards past already-consumed bytes (malformed or hostile file), or a parser bug that mis-tracks mPosition after mark/reset.","commonSituations":"Decoding a hand-crafted or corrupted resources.arsc; files produced by packers/protectors that rewrite resource tables with unusual layouts; occasionally an apktool version's parser misreading a newer table format.","solutions":["Verify the file is an intact, original APK (`unzip -t`, re-download) — malformed tables are the usual cause","Update apktool; offset-handling fixes for new resources.arsc encodings land regularly","If you control the file, rebuild the resource table with aapt2 to normalize offsets","Reproduce with a minimal file and report to apktool if a genuine parser bug is suspected"],"exampleFix":"// before\nlong pos = stringPoolOffset; // may be < current position on odd files\nin.jumpTo(pos);\n\n// after\nif (pos < in.position()) {\n    throw new IOException(\"Chunk offset \" + pos + \" precedes current position \" + in.position()\n        + \" — resources.arsc is malformed\");\n}\nin.jumpTo(pos);","handlingStrategy":"validation","validationCode":"// Validate offsets before jumping during custom parsing\nlong target = chunkOffset;\nif (target < in.position()) {\n    throw new IOException(\"Malformed table: offset \" + target + \" < current \" + in.position());\n}\nin.jumpTo(target);","typeGuard":null,"tryCatchPattern":"try {\n    in.jumpTo(pos);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Illegal backwards jump\")) {\n        // file's chunk layout is inconsistent — abort parse with file context, do not retry\n        throw new ParseAbortException(\"Malformed resources.arsc\", e);\n    }\n    throw e;\n}","preventionTips":["Sanity-check chunk offsets against current position before jumpTo","Verify input integrity before parsing (CRC via unzip -t)","Stay on current apktool releases for new resources.arsc layouts"],"tags":["apktool","parsing","resources-arsc","stream"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}