{"record":{"id":"f3f0b5d1605825f3","repo":"iBotPeaches/Apktool","slug":"mark-not-supported","errorCode":null,"errorMessage":"Mark not supported","messagePattern":"Mark not supported","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"brut.j.util/src/main/java/brut/util/BinaryDataInputStream.java","lineNumber":342,"sourceCode":"        return skipped;\n    }\n\n    @Override\n    public int available() throws IOException {\n        return (int) Math.min(in.available(), remaining());\n    }\n\n    @Override\n    public synchronized void mark(int readlimit) {\n        // We can't throw an exception here, so mark even if mark isn't supported, since reset won't work anyway.\n        in.mark(readlimit);\n        mMark = mPosition;\n    }\n\n    @Override\n    public synchronized void reset() throws IOException {\n        if (!markSupported()) {\n            throw new IOException(\"Mark not supported\");\n        }\n        if (mMark == -1) {\n            throw new IOException(\"Mark not set\");\n        }\n        in.reset();\n        mPosition = mMark;\n    }\n}\n","sourceCodeStart":324,"sourceCodeEnd":351,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.j.util/src/main/java/brut/util/BinaryDataInputStream.java#L324-L351","documentation":"BinaryDataInputStream.reset() checks markSupported() and throws when the wrapped stream cannot support mark/reset. The class itself tracks a logical mark position, but it delegates the actual rewind to the underlying InputStream — if that stream lacks mark support, rewinding is impossible.","triggerScenarios":"Calling reset() on a BinaryDataInputStream wrapping a raw FileInputStream, Socket stream, or other non-buffering InputStream after a mark() call; mark() silently records the position but reset() cannot honor it.","commonSituations":"Parsing code that worked with a buffered or byte-array stream being pointed at a file/socket stream; refactoring parsers to read straight from channels; testing with ByteArrayInputStream (works) then failing in production with FileInputStream.","solutions":["Wrap the source in a BufferedInputStream (or push the data into a byte[] and use ByteArrayInputStream) before constructing BinaryDataInputStream","Check markSupported() before mark()/reset() and fail early with a clear message","If random access is needed, prefer a RandomAccessFile/seek-based reader instead of mark/reset","Size the buffer >= the maximum bytes you will read between mark and reset"],"exampleFix":"// before\nBinaryDataInputStream in = new BinaryDataInputStream(new FileInputStream(file), ...);\nin.mark(1024);\n... in.read ... ;\nin.reset(); // Mark not supported\n\n// after\nBinaryDataInputStream in = new BinaryDataInputStream(\n    new BufferedInputStream(new FileInputStream(file), 1 << 16), ...);\nin.mark(1 << 16);\nin.reset(); // works","handlingStrategy":"validation","validationCode":"InputStream src = new FileInputStream(file);\nif (!src.markSupported()) {\n    src = new BufferedInputStream(src, 1 << 16); // now markSupported() == true\n}\nBinaryDataInputStream in = new BinaryDataInputStream(src, ...);\nassert in.markSupported();","typeGuard":"boolean canMarkReset(BinaryDataInputStream in) {\n    return in.markSupported();\n}","tryCatchPattern":"try {\n    in.reset();\n} catch (IOException e) {\n    if (\"Mark not supported\".equals(e.getMessage())) {\n        // rewrap source with BufferedInputStream and restart the parse; retrying reset() is pointless\n    } else { throw e; }\n}","preventionTips":["Always wrap file/socket streams in BufferedInputStream before parsing","Check markSupported() once at construction and fail fast","Prefer seek-based (RandomAccessFile) access when you need arbitrary rewinds"],"tags":["java","stream","mark-reset","io"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}