{"record":{"id":"f2b61dca18d1bd8a","repo":"TooTallNate/Java-WebSocket","slug":"cannot-have-length-offset","errorCode":null,"errorMessage":"Cannot have length offset: ","messagePattern":"Cannot have length offset: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/java_websocket/util/Base64.java","lineNumber":660,"sourceCode":"   * @throws IllegalArgumentException if source array is null, if source array, offset, or length\n   *                                  are invalid\n   * @see Base64#GZIP\n   * @see Base64#DO_BREAK_LINES\n   * @since 2.3.1\n   */\n  public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options)\n      throws java.io.IOException {\n\n    if (source == null) {\n      throw new IllegalArgumentException(\"Cannot serialize a null array.\");\n    }   // end if: null\n\n    if (off < 0) {\n      throw new IllegalArgumentException(\"Cannot have negative offset: \" + off);\n    }   // end if: off < 0\n\n    if (len < 0) {\n      throw new IllegalArgumentException(\"Cannot have length offset: \" + len);\n    }   // end if: len < 0\n\n    if (off + len > source.length) {\n      throw new IllegalArgumentException(\n          String\n              .format(\"Cannot have offset of %d and length of %d with array of length %d\", off, len,\n                  source.length));\n    }   // end if: off < 0\n\n    // Compress?\n    if ((options & GZIP) != 0) {\n      java.io.ByteArrayOutputStream baos = null;\n      java.util.zip.GZIPOutputStream gzos = null;\n      Base64.OutputStream b64os = null;\n\n      try {\n        // GZip -> Base64 -> ByteArray\n        baos = new java.io.ByteArrayOutputStream();","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/TooTallNate/Java-WebSocket/blob/afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d/src/main/java/org/java_websocket/util/Base64.java#L642-L678","documentation":"encodeBytesToBytes validates its (source, off, len) slice before Base64-encoding. A negative length is meaningless for an array slice, so the library fails fast with IllegalArgumentException. This is a caller-contract violation, not a data corruption issue.","triggerScenarios":"Calling encodeBytesToBytes(source, off, len) (or a wrapper like encoded()) with len < 0, typically when len comes from an unvalidated subtraction such as (end - start) or a computed size.","commonSituations":"Computing length as difference of two offsets where end < start; passing -1 as a sentinel 'unknown length'; integer arithmetic on parsed config values that can go negative.","solutions":["Check len >= 0 before calling encodeBytesToBytes and clamp or reject invalid values.","If len is computed as a difference, ensure the end offset is >= the start offset (e.g. Math.max(0, end - start)).","Catch IllegalArgumentException at the boundary if negative lengths are expected from untrusted input, and return a validation error to the caller instead."],"exampleFix":"// before\nint len = end - start;\nbyte[] out = Base64.encodeBytesToBytes(data, start, len);\n\n// after\nint len = Math.max(0, end - start);\nif (end < start) throw new IllegalArgumentException(\"end must be >= start\");\nbyte[] out = Base64.encodeBytesToBytes(data, start, len);","handlingStrategy":"validation","validationCode":"if (data == null || off < 0 || len < 0 || off + len > data.length) {\n    throw new IllegalArgumentException(\"invalid Base64 slice: off=\" + off + \" len=\" + len);\n}\nbyte[] out = Base64.encodeBytesToBytes(data, off, len);","typeGuard":"static boolean isValidSlice(byte[] a, int off, int len) {\n    return a != null && off >= 0 && len >= 0 && off + len <= a.length;\n}","tryCatchPattern":"try {\n    out = Base64.encodeBytesToBytes(data, off, len);\n} catch (IllegalArgumentException e) {\n    // reject request: bad offset/length\n    throw new BadRequestException(e.getMessage());\n}","preventionTips":["Never pass -1 as a sentinel length; use Optional or a separate presence flag.","Compute slice lengths with Math.max(0, end - start).","Centralize array-slice validation in one helper used by all encode calls."],"tags":["java","base64","illegal-argument","negative-length"],"backgroundTag":"invalid-argument-value","analyzedSha":"afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d","analyzedAt":"2026-09-09T14:39:47.546Z","contentChangedAt":"2026-09-09T14:39:47.546Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}