{"record":{"id":"eb438acb7212e6c0","repo":"MuntashirAkon/AppManager","slug":"detect-premature-eof","errorCode":null,"errorMessage":"Detect premature EOF","messagePattern":"Detect premature EOF","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/IoUtils.java","lineNumber":55,"sourceCode":"    public static byte[] readFully(@NonNull InputStream is, int length, boolean readAll)\n            throws IOException {\n        byte[] output = {};\n        if (length == -1) length = Integer.MAX_VALUE;\n        int pos = 0;\n        while (pos < length) {\n            int bytesToRead;\n            if (pos >= output.length) {\n                bytesToRead = Math.min(length - pos, output.length + 1024);\n                if (output.length < pos + bytesToRead) {\n                    output = Arrays.copyOf(output, pos + bytesToRead);\n                }\n            } else {\n                bytesToRead = output.length - pos;\n            }\n            int cc = is.read(output, pos, bytesToRead);\n            if (cc < 0) {\n                if (readAll && length != Integer.MAX_VALUE) {\n                    throw new EOFException(\"Detect premature EOF\");\n                } else {\n                    if (output.length != pos) {\n                        output = Arrays.copyOf(output, pos);\n                    }\n                    break;\n                }\n            }\n            pos += cc;\n        }\n        return output;\n    }\n\n    @AnyThread\n    @NonNull\n    public static String getInputStreamContent(@NonNull InputStream inputStream) throws IOException {\n        return new String(IoUtils.readFully(inputStream, -1, true), Charset.defaultCharset());\n    }\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/IoUtils.java#L37-L73","documentation":"IoUtils.readFully() reads an InputStream fully into a byte array, growing it as needed. When the caller demands the entire stream (readAll true and a known finite length) but the stream ends before delivering that many bytes, it throws EOFException(\"Detect premature EOF\") rather than silently returning a short buffer. This protects against truncated or corrupted sources.","triggerScenarios":"Reading a stream whose declared/expected length is larger than the actual bytes available: truncated files, interrupted transfers, a remote file shrinking mid-read, or a content-length mismatch on streamed reads where readAll is set.","commonSituations":"Partially downloaded files; files modified/truncated by another process during read; network-backed streams cut short; reading through remote file providers whose source changed.","solutions":["Verify the source file/stream is complete (compare sizes/checksums) before readFully","Retry the read or re-fetch the content if the source may be transiently truncated","If a short read is acceptable, use a read variant/API that doesn't set readAll (or catch EOFException and use whatever bytes were read)"],"exampleFix":"// before\nbyte[] data = IoUtils.readFully(in, true); // EOFException on truncation\n// after\ntry {\n    data = IoUtils.readFully(in, true);\n} catch (EOFException e) {\n    data = /* fallback: re-fetch or accept partial */ refetchOrPartial();\n}","handlingStrategy":"try-catch","validationCode":"long expected = source.length(); long actual = countAvailable(source); if (actual < expected) throw new IOException(\"source truncated before read\");","typeGuard":null,"tryCatchPattern":"try { data = IoUtils.readFully(in, true); } catch (EOFException e) { /* re-fetch, retry, or accept partial bytes */ }","preventionTips":["Verify file size/checksum before full reads","Retry reads of network-backed or mutable files","Use non-strict read variants when truncation is tolerable"],"tags":["io","stream","eof","truncated-data"],"backgroundTag":"file-read-failed","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}