{"record":{"id":"3ddbf31febd40521","repo":"apache/dubbo","slug":"negative-buffer-size","errorCode":null,"errorMessage":"Negative buffer size","messagePattern":"Negative buffer size","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/io/UnsafeStringWriter.java","lineNumber":34,"sourceCode":" */\npackage org.apache.dubbo.common.io;\n\nimport java.io.IOException;\nimport java.io.Writer;\n\n/**\n * Thread-unsafe StringWriter.\n */\npublic class UnsafeStringWriter extends Writer {\n    private final StringBuilder mBuffer;\n\n    public UnsafeStringWriter() {\n        lock = mBuffer = new StringBuilder();\n    }\n\n    public UnsafeStringWriter(int size) {\n        if (size < 0) {\n            throw new IllegalArgumentException(\"Negative buffer size\");\n        }\n\n        lock = mBuffer = new StringBuilder(size);\n    }\n\n    @Override\n    public void write(int c) {\n        mBuffer.append((char) c);\n    }\n\n    @Override\n    public void write(char[] cs) throws IOException {\n        mBuffer.append(cs, 0, cs.length);\n    }\n\n    @Override\n    public void write(char[] cs, int off, int len) throws IOException {\n        if ((off < 0) || (off > cs.length) || (len < 0) || ((off + len) > cs.length) || ((off + len) < 0)) {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/io/UnsafeStringWriter.java#L16-L52","documentation":"Thrown by the UnsafeStringWriter(int size) constructor when size < 0. The writer wraps a single StringBuilder; size is used only as the initial capacity hint passed to new StringBuilder(size). A negative capacity is invalid, so the constructor rejects it immediately rather than letting StringBuilder throw a misleading negative array size exception. The no-arg constructor UnsafeStringWriter() is unaffected.","triggerScenarios":"new UnsafeStringWriter(size) with a negative size argument, e.g. new UnsafeStringWriter(-1). Typically size comes from a computed capacity (estimated payload length, header content-length, buffer config) that underflows to negative.","commonSituations":"Capacity estimated from a subtraction that goes negative (e.g. totalLen - overhead when overhead > totalLen); reading an untrusted/misconfigured buffer-size property; arithmetic on a length that wraps because of an empty or missing field; defaulting size to -1 as 'unspecified'.","solutions":["Pass a non-negative size; if you only need default capacity, use new UnsafeStringWriter() (no size).","Clamp computed sizes: new UnsafeStringWriter(Math.max(0, estimatedSize)).","Validate the source config value and reject/repair negative sizes upstream.","Remember the size is only a capacity hint — the StringBuilder grows as needed, so 0 is always safe."],"exampleFix":"// before\nnew UnsafeStringWriter(contentLength - headerOverhead) // negative when header is larger\n// after\nnew UnsafeStringWriter(Math.max(0, contentLength - headerOverhead))","handlingStrategy":"validation","validationCode":"if (size < 0) {\n    size = 0; // capacity hint only; StringBuilder grows as needed\n}\nnew UnsafeStringWriter(size);","typeGuard":null,"tryCatchPattern":"UnsafeStringWriter w;\ntry {\n    w = new UnsafeStringWriter(size);\n} catch (IllegalArgumentException e) {\n    if (\"Negative buffer size\".equals(e.getMessage())) {\n        w = new UnsafeStringWriter(); // fall back to default capacity\n    } else {\n        throw e;\n    }\n}","preventionTips":["Prefer the no-arg UnsafeStringWriter() unless you have a real capacity estimate.","Clamp computed sizes with Math.max(0, estimated).","Validate externally-supplied size config before constructing the writer.","Remember the size is only a capacity hint — 0 is always safe."],"tags":["io","string-writer","argument-validation","dubbo-common"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}