Skip to content

Commit b32424e

Browse files
doc and lint
1 parent 7bd6b76 commit b32424e

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. The format
55
## Table of Contents
66

77
- [Unreleased](#unreleased)
8+
- [1.9.16 - 2025-12-02](#1916---2025-12-02)
89
- [1.9.15 - 2025-12-01](#1915---2025-12-01)
910
- [1.9.14 - 2025-12-01](#1914---2025-12-01)
1011
- [1.9.13 - 2025-12-01](#1913---2025-12-01)
@@ -185,6 +186,13 @@ All notable changes to this project will be documented in this file. The format
185186
### Fixed
186187

187188
### Security
189+
---
190+
191+
### [1.9.16] - 2025-12-01
192+
193+
### Added
194+
195+
- Added bound checking in the toUTF8 function to prevent buffer overflows.
188196

189197
---
190198

docs/reference/primitives.md

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6099,32 +6099,39 @@ toUTF8 = (arr: number[]): string => {
60996099
}
61006100
if (byte <= 127) {
61016101
result += String.fromCharCode(byte);
6102+
continue;
61026103
}
6103-
else if (byte >= 192 && byte <= 223) {
6104-
const byte2 = arr[i + 1];
6105-
skip = 1;
6104+
if (byte >= 192 && byte <= 223) {
6105+
const avail = arr.length - (i + 1);
6106+
const byte2 = avail >= 1 ? arr[i + 1] : 0;
6107+
skip = Math.min(1, avail);
61066108
const codePoint = ((byte & 31) << 6) | (byte2 & 63);
61076109
result += String.fromCharCode(codePoint);
6110+
continue;
61086111
}
6109-
else if (byte >= 224 && byte <= 239) {
6110-
const byte2 = arr[i + 1];
6111-
const byte3 = arr[i + 2];
6112-
skip = 2;
6112+
if (byte >= 224 && byte <= 239) {
6113+
const avail = arr.length - (i + 1);
6114+
const byte2 = avail >= 1 ? arr[i + 1] : 0;
6115+
const byte3 = avail >= 2 ? arr[i + 2] : 0;
6116+
skip = Math.min(2, avail);
61136117
const codePoint = ((byte & 15) << 12) | ((byte2 & 63) << 6) | (byte3 & 63);
61146118
result += String.fromCharCode(codePoint);
6119+
continue;
61156120
}
6116-
else if (byte >= 240 && byte <= 247) {
6117-
const byte2 = arr[i + 1];
6118-
const byte3 = arr[i + 2];
6119-
const byte4 = arr[i + 3];
6120-
skip = 3;
6121+
if (byte >= 240 && byte <= 247) {
6122+
const avail = arr.length - (i + 1);
6123+
const byte2 = avail >= 1 ? arr[i + 1] : 0;
6124+
const byte3 = avail >= 2 ? arr[i + 2] : 0;
6125+
const byte4 = avail >= 3 ? arr[i + 3] : 0;
6126+
skip = Math.min(3, avail);
61216127
const codePoint = ((byte & 7) << 18) |
61226128
((byte2 & 63) << 12) |
61236129
((byte3 & 63) << 6) |
61246130
(byte4 & 63);
61256131
const surrogate1 = 55296 + ((codePoint - 65536) >> 10);
61266132
const surrogate2 = 56320 + ((codePoint - 65536) & 1023);
61276133
result += String.fromCharCode(surrogate1, surrogate2);
6134+
continue;
61286135
}
61296136
}
61306137
return result;

src/primitives/utils.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ function utf8ToArray (str: string): number[] {
232232
* @returns {string} - The UTF-8 encoded string.
233233
*/
234234
export const toUTF8 = (arr: number[]): string => {
235-
let result = ""
235+
let result = ''
236236
let skip = 0
237237

238238
for (let i = 0; i < arr.length; i++) {
@@ -292,8 +292,6 @@ export const toUTF8 = (arr: number[]): string => {
292292
result += String.fromCharCode(surrogate1, surrogate2)
293293
continue
294294
}
295-
296-
// If it's an invalid leading byte, keep prior behavior: do nothing / skip
297295
}
298296

299297
return result

0 commit comments

Comments
 (0)