{"record":{"id":"3af8ab97e0f0cdc5","repo":"chinabugotech/hutool","slug":"read-limit-exceeded","errorCode":null,"errorMessage":"Read limit exceeded","messagePattern":"Read limit exceeded","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/io/LimitedInputStream.java","lineNumber":60,"sourceCode":"\t\t\tcurrentPos += count;\n\t\t\tcheckPos();\n\t\t}\n\t\treturn count;\n\t}\n\n\t@Override\n\tpublic long skip(long n) throws IOException {\n\t\tfinal long skipped = super.skip(n);\n\t\tif (skipped != 0) {\n\t\t\tcurrentPos += skipped;\n\t\t\tcheckPos();\n\t\t}\n\t\treturn skipped;\n\t}\n\n\tprivate void checkPos() {\n\t\tif (currentPos > maxSize) {\n\t\t\tthrow new IllegalStateException(\"Read limit exceeded\");\n\t\t}\n\t}\n}\n","sourceCodeStart":42,"sourceCodeEnd":64,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/io/LimitedInputStream.java#L42-L64","documentation":"LimitedInputStream caps the total bytes read or skipped at maxSize. Every read/skip increments currentPos and calls checkPos(); once currentPos exceeds maxSize it throws IllegalStateException(\"Read limit exceeded\"). This is a deliberate DoS / decompression-bomb guard.","triggerScenarios":"Reading or skipping more than maxSize bytes in total through a LimitedInputStream — e.g. decompressing a zip bomb or reading an oversized upload.","commonSituations":"Decompressing an archive bomb; maxSize set below the legitimate content size; reading an unbounded network payload without a content-length check; forgetting to size the limit to expected data.","solutions":["Set maxSize to the largest legitimate payload you expect to handle.","Validate Content-Length / declared size before wrapping the stream.","Catch IllegalStateException and reject the input as too large rather than treating it as a bug."],"exampleFix":"// before: limit too small for real data\ntry (InputStream lim = new LimitedInputStream(in, 1024)) {\n    byte[] all = IoUtil.readBytes(lim); // throws if payload > 1024\n}\n\n// after: size to expected maximum, and treat overflow as bad input\nlong max = 16L * 1024 * 1024;\ntry (InputStream lim = new LimitedInputStream(in, max)) {\n    byte[] all = IoUtil.readBytes(lim);\n} catch (IllegalStateException e) {\n    throw new IllegalArgumentException(\"payload exceeds \" + max + \" bytes\", e);\n}","handlingStrategy":"try-catch","validationCode":"long declared = /* Content-Length or declared size */ -1;\nif (declared > maxAllowed) {\n    throw new IllegalArgumentException(\"payload too large: \" + declared);\n}\ntry (InputStream lim = new LimitedInputStream(in, maxAllowed)) {\n    return IoUtil.readBytes(lim);\n}","typeGuard":null,"tryCatchPattern":"try (InputStream lim = new LimitedInputStream(in, maxSize)) {\n    return IoUtil.readBytes(lim);\n} catch (IllegalStateException e) {\n    // read limit exceeded: input was larger than maxSize — reject as too large\n    throw new IllegalArgumentException(\"input exceeds size limit \" + maxSize, e);\n}","preventionTips":["Set maxSize to the largest legitimate payload, not an arbitrary small number.","Validate Content-Length before wrapping untrusted streams.","Treat 'Read limit exceeded' as bad input, not an internal bug."],"tags":["io","security","dos-protection","limits"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}