{"record":{"id":"010139140dc5359b","repo":"alibaba/Sentinel","slug":"maxsize-must-0","errorCode":null,"errorMessage":"maxSize must > 0","messagePattern":"maxSize must > 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/client/SimpleHttpResponseParser.java","lineNumber":44,"sourceCode":" * <p>\n * The parser provides functionality to parse raw bytes HTTP response to a {@link SimpleHttpResponse}.\n * </p>\n * <p>\n * Note that this is a very NAIVE parser, {@code Content-Length} must be specified in the\n * HTTP response header, otherwise, the body will be dropped. All other body type such as\n * {@code Transfer-Encoding: chunked}, {@code Transfer-Encoding: deflate} are not supported.\n * </p>\n *\n * @author leyou\n */\npublic class SimpleHttpResponseParser {\n\n    private static final int MAX_BODY_SIZE = 1024 * 1024 * 4;\n    private byte[] buf;\n\n    public SimpleHttpResponseParser(int maxSize) {\n        if (maxSize < 0) {\n            throw new IllegalArgumentException(\"maxSize must > 0\");\n        }\n        this.buf = new byte[maxSize];\n    }\n\n    public SimpleHttpResponseParser() {\n        this(1024 * 4);\n    }\n\n    /**\n     * Parse bytes from an input stream to a {@link SimpleHttpResponse}.\n     *\n     * @param in input stream\n     * @return parsed HTTP response entity\n     * @throws IOException when an IO error occurs\n     */\n    public SimpleHttpResponse parse(InputStream in) throws IOException {\n        int bg = 0;\n        int len;","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-transport/sentinel-transport-simple-http/src/main/java/com/alibaba/csp/sentinel/transport/heartbeat/client/SimpleHttpResponseParser.java#L26-L62","documentation":"SimpleHttpResponseParser reads an entire HTTP response (status line + headers + body) into a single pre-allocated byte buffer. Its constructor validates the buffer size and throws IllegalArgumentException(\"maxSize must > 0\") for a negative argument. Note the off-by-one in the guard: it checks maxSize < 0, so 0 is accepted (creating an empty buffer) even though the message demands > 0 — a known inconsistency in this utility.","triggerScenarios":"new SimpleHttpResponseParser(-1) or any negative maxSize; in practice a computed buffer size (e.g. from a config value or max-body arithmetic) that goes negative. Passing 0 does not throw but will immediately fail later with the buf-index IndexOutOfBoundsException.","commonSituations":"Custom heartbeat/HTTP client code parameterizing the parser with a configurable read buffer; subtraction-based size math (headerSize - overhead) that can go negative; tests passing sentinel values like -1 for \"default\".","solutions":["Pass a positive buffer size (default constructor uses 1024 * 4)","Clamp computed sizes: Math.max(defaultSize, computedSize)","Passing 0 'works' but is wrong — it creates an empty buffer; treat 0 as invalid at the call site too"],"exampleFix":"// before\nint size = cfg.getInt(\"parser.buf\", -1); // -1 sentinel\nparser = new SimpleHttpResponseParser(size);\n\n// after\nint size = cfg.getInt(\"parser.buf\", 1024 * 4);\nparser = new SimpleHttpResponseParser(Math.max(1, size));","handlingStrategy":"validation","validationCode":"int size = Math.max(1, configuredParserBufferSize);\nparser = new SimpleHttpResponseParser(size);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass -1 or 0 sentinels; use the default constructor for 4KB","Clamp computed buffer sizes to a positive minimum"],"tags":["sentinel","transport","http","constructor","validation"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}