{"record":{"id":"7f4568c3140e3e2c","repo":"MuntashirAkon/AppManager","slug":"negative-position","errorCode":null,"errorMessage":"Negative position","messagePattern":"Negative position","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/RemoteFileChannel.java","lineNumber":330,"sourceCode":"        long bytes = 0;\n        while (count > bytes) {\n            int limit = (int) Math.min(b.capacity(), count - bytes);\n            b.limit(limit);\n            if (src.read(b) <= 0)\n                break;\n            b.flip();\n            int len = write0(b, position);\n            position += len;\n            bytes += len;\n            b.clear();\n        }\n        return bytes;\n    }\n\n    @Override\n    public int read(ByteBuffer dst, long position) throws IOException {\n        if (position < 0)\n            throw new IllegalArgumentException(\"Negative position\");\n        ensureOpen();\n        return read0(dst, position);\n    }\n\n    @Override\n    public int write(ByteBuffer src, long position) throws IOException {\n        if (position < 0)\n            throw new IllegalArgumentException(\"Negative position\");\n        ensureOpen();\n        return write0(src, position);\n    }\n\n    @Override\n    protected void implCloseChannel() {\n        try { fs.close(handle); } catch (RemoteException ignored) {}\n        synchronized (fdLock) {\n            try { Os.close(read); } catch (ErrnoException ignored) {}\n            try { Os.close(write); } catch (ErrnoException ignored) {}","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/RemoteFileChannel.java#L312-L348","documentation":"RemoteFileChannel.read(ByteBuffer, long position) throws IllegalArgumentException(\"Negative position\") when the absolute read position is negative, per the FileChannel positional-read contract. The check runs before ensureOpen and any remote IPC.","triggerScenarios":"Calling read(dst, position) with position < 0, e.g. from cursor arithmetic like position - skip where skip exceeded position, or a parsed offset that failed.","commonSituations":"Chunked readers computing offsets with off-by-one/negative deltas; restoring a saved read position from corrupted state; using Long.MIN_VALUE sentinels.","solutions":["Validate/clamp position to >= 0 before the call (Math.max(0, position)).","Fix the offset computation so the saved/derived position cannot go negative.","Check state-restore code that loads positions from storage for corruption handling.","Assert position >= 0 in the reader loop for early, clear failures."],"exampleFix":"// before\nchannel.read(buffer, lastPos - chunkSize);\n// after\nlong pos = Math.max(0, lastPos - chunkSize);\nchannel.read(buffer, pos);","handlingStrategy":"validation","validationCode":"if (position < 0) {\n    throw new IllegalArgumentException(\"read position must be >= 0, got \" + position);\n}\nchannel.read(dst, position);","typeGuard":null,"tryCatchPattern":"try {\n    channel.read(dst, position);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"Bad read position {}\", position, e);\n}","preventionTips":["Clamp offsets with Math.max(0, position).","Audit subtraction-based cursor arithmetic.","Validate restored/cached positions before use."],"tags":["illegal-argument","file-channel","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}