{"record":{"id":"d062d6a3337eccc2","repo":"Eugeny/tabby","slug":"invalid-code-point","errorCode":null,"errorMessage":"Invalid code point","messagePattern":"Invalid code point","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web/polyfills.buffer.ts","lineNumber":204,"sourceCode":"                codePoint & 0x3F | 0x80\n            )\n        } else if (codePoint < 0x10000) {\n            if ((units -= 3) < 0) {break}\n            bytes.push(\n                codePoint >> 0xC | 0xE0,\n                codePoint >> 0x6 & 0x3F | 0x80,\n                codePoint & 0x3F | 0x80\n            )\n        } else if (codePoint < 0x110000) {\n            if ((units -= 4) < 0) {break}\n            bytes.push(\n                codePoint >> 0x12 | 0xF0,\n                codePoint >> 0xC & 0x3F | 0x80,\n                codePoint >> 0x6 & 0x3F | 0x80,\n                codePoint & 0x3F | 0x80\n            )\n        } else {\n            throw new Error('Invalid code point')\n        }\n    }\n    return bytes\n}\n\n// Create lookup table for `toString('hex')`\n// See: https://github.com/feross/buffer/issues/219\nconst hexSliceLookupTable = (function () {\n    const alphabet = '0123456789abcdef'\n    const table = new Array(256)\n    for (let i = 0; i < 16; ++i) {\n        const i16 = i * 16\n        for (let j = 0; j < 16; ++j) {\n            table[i16 + j] = alphabet[i] + alphabet[j]\n        }\n    }\n    return table\n})()","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/Eugeny/tabby/blob/14e2d60b9b6dee84a53c37f05eefeb803787de04/web/polyfills.buffer.ts#L186-L222","documentation":"Thrown by the utf8ToBytes() helper in the buffer polyfill (web/polyfills.buffer.ts), which implements Buffer.prototype.utf8Write. It encodes a JS string to UTF-8 bytes and rejects any code point >= 0x110000 (i.e. outside the valid Unicode range up to U+10FFFF). This is a defensive guard carried over from the feross/buffer polyfill.","triggerScenarios":"utf8ToBytes reaches the final else branch when, after surrogate-pair combining, codePoint is >= 0x110000. With well-formed JS strings and charCodeAt this is effectively unreachable (valid surrogate pairs max out at 0x10FFFF). It can be hit by feeding malformed input, a corrupted/mutated string, or by calling the internal helper directly with out-of-range numeric values instead of a real string.","commonSituations":"Corrupt binary data being treated as a string and then written via Buffer(buf).write(str, 0, length, 'utf8'); a polyfill version mismatch after a webpack/buffer upgrade; manually constructed string-like inputs with invalid surrogate sequences in edge-case locales; fuzzed or attacker-controlled text reaching a buffer write path.","solutions":["Sanitize the input string before writing: strip or replace lone/out-of-range surrogates (e.g. U+FFFD replacement).","Ensure you pass a real JS string (not a number/Buffer) to Buffer write methods that route through utf8Write.","Update the buffer polyfill (and @types/node 'buffer') to a current version; this guard is standard and stable but depend on a maintained fork.","Reproduce with a minimal input and confirm whether the data is genuinely corrupt upstream (logging the string's code units)."],"exampleFix":"// before\nbuf.write(maybeCorruptString, 0, len, 'utf8') // may throw 'Invalid code point'\n// after: normalize the string first\nconst safe = maybeCorruptString.normalize('NFC').replace(/[�-�](?![�-�])|[^�-�][�-�]/g, '\\uFFFD')\nbuf.write(safe, 0, safe.length, 'utf8')","handlingStrategy":"validation","validationCode":"function sanitizeForUtf8 (s: string): string {\n    // replace lone surrogates / out-of-range code units with U+FFFD\n    return s.replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|[^\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g, '\\uFFFD')\n}\nconst safe = sanitizeForUtf8(input)\nbuf.write(safe, 0, safe.length, 'utf8')","typeGuard":"function isValidUtf8String (s: string): boolean {\n    // no lone surrogates -> cannot produce a code point >= 0x110000\n    return !/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|[^\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/.test(s)\n}","tryCatchPattern":"try {\n    buf.write(input, 0, input.length, 'utf8')\n} catch (e) {\n    if (e.message === 'Invalid code point') {\n        buf.write(input.replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|[^\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g, '\\uFFFD'), 0, input.length, 'utf8')\n    } else throw e\n}","preventionTips":["Never pass non-string data to Buffer write methods expecting utf8.","Sanitize strings arriving from untrusted/binary sources before encoding.","Keep the buffer polyfill and 'buffer' types in sync after upgrades.","Reproduce with the exact input to confirm upstream data corruption."],"tags":["buffer","polyfill","utf8","encoding","data-corruption"],"backgroundTag":null,"analyzedSha":"14e2d60b9b6dee84a53c37f05eefeb803787de04","analyzedAt":"2026-08-12T11:46:48.773Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}