{"record":{"id":"d58409f167c8da6b","repo":"skylot/jadx","slug":"no-data-can-t-skip-bytes","errorCode":null,"errorMessage":"No data, can't skip {} bytes","messagePattern":"No data, can't skip (.+?) bytes","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java","lineNumber":98,"sourceCode":"\t\tint pos = input.read(arr, 0, count);\n\t\twhile (pos < count) {\n\t\t\tint read = input.read(arr, pos, count - pos);\n\t\t\tif (read == -1) {\n\t\t\t\tthrow new IOException(\"No data, can't read \" + count + \" bytes\");\n\t\t\t}\n\t\t\tpos += read;\n\t\t}\n\t\treturn arr;\n\t}\n\n\t@Override\n\tpublic long skip(long count) throws IOException {\n\t\treadPos += count;\n\t\tlong pos = input.skip(count);\n\t\twhile (pos < count) {\n\t\t\tlong skipped = input.skip(count - pos);\n\t\t\tif (skipped == 0) {\n\t\t\t\tthrow new IOException(\"No data, can't skip \" + count + \" bytes\");\n\t\t\t}\n\t\t\tpos += skipped;\n\t\t}\n\t\treturn pos;\n\t}\n\n\tpublic void checkInt8(int expected, String error) throws IOException {\n\t\tint v = readInt8();\n\t\tif (v != expected) {\n\t\t\tthrowException(error, expected, v);\n\t\t}\n\t}\n\n\tpublic void checkInt16(int expected, String error) throws IOException {\n\t\tint v = readInt16();\n\t\tif (v != expected) {\n\t\t\tthrowException(error, expected, v);\n\t\t}","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java#L80-L116","documentation":"ParserStream.skip attempts to skip a number of bytes in the underlying stream. If repeated input.skip() calls return 0 (indicating no more bytes can be skipped, typically EOF) before the requested count is reached, an IOException is thrown. This guards against silently advancing past valid data when the stream is exhausted.","triggerScenarios":"Invoked by skipToPos and checkInt8-style flows while navigating Android binary chunks. skip(count) is called to align the read position to a declared offset; if the stream reports 0 bytes skipped (usually EOF or unsupported skip on a custom InputStream), the exception is raised.","commonSituations":"Truncated resources.arsc where offsets point past end of file. A wrapped InputStream whose skip() always returns 0 for some implementations (e.g., certain FilterInputStream subclasses). Malformed chunk sizes from obfuscation or packing tools.","solutions":["Confirm the APK/resource file is not truncated or partially written","Test the same file with a recent jadx release","Report the file to jadx maintainers if it decompiles in Android Asset Packaging Tool but not jadx","Avoid passing custom InputStream wrappers that do not implement skip correctly — pass the raw file stream"],"exampleFix":"// Ensure the raw file stream is used, not a wrapper that breaks skip():\ntry (InputStream raw = Files.newInputStream(apkEntryPath)) {\n    parser.decode(raw);\n}","handlingStrategy":"try-catch","validationCode":"// Verify the stream supports skip before parsing:\nif (!inputStream.markSupported()) {\n    LOG.warn(\"Stream may not support skip reliably\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    parser.decode(stream);\n} catch (IOException e) {\n    LOG.warn(\"Resource skip failed, falling back to no-res mode\", e);\n    jadxArgs.setSkipResources(true);\n}","preventionTips":["Pass the raw FileInputStream/BufferedInputStream, not custom wrappers","Verify the APK is complete before parsing","Catch IOException and degrade gracefully to code-only decompilation"],"tags":["android","binary-parsing","io","resource-table","corrupt-input"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}