Skip to content

Commit 9a381cb

Browse files
authored
Merge pull request #5807 from prydt/main
Fix Buffer.toString encoding to match Node.js
2 parents faa576e + eaa8e20 commit 9a381cb

File tree

2 files changed

+63
-36
lines changed

2 files changed

+63
-36
lines changed

src/node/internal/internal_utils.ts

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -49,71 +49,75 @@ export function normalizeEncoding(enc?: string): Encoding | undefined {
4949
}
5050

5151
export function getEncodingOps(enc: unknown): Encoding | undefined {
52-
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
53-
enc += '';
54-
// @ts-expect-error TS18046 TS complains about unknown can not have length.
55-
switch (enc.length) {
52+
if (enc === undefined) return UTF8;
53+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
54+
let encoding = `${enc}`;
55+
switch (encoding.length) {
5656
case 4:
57-
if (enc === 'UTF8') return UTF8;
58-
if (enc === 'ucs2' || enc === 'UCS2') return UTF16LE;
59-
enc = `${enc}`.toLowerCase();
60-
if (enc === 'utf8') return UTF8;
61-
if (enc === 'ucs2') return UTF16LE;
57+
if (encoding === 'UTF8') return UTF8;
58+
if (encoding === 'ucs2' || encoding === 'UCS2') return UTF16LE;
59+
encoding = encoding.toLowerCase();
60+
if (encoding === 'utf8') return UTF8;
61+
if (encoding === 'ucs2') return UTF16LE;
6262
break;
6363
case 3:
64-
if (enc === 'hex' || enc === 'HEX' || `${enc}`.toLowerCase() === 'hex') {
64+
if (
65+
encoding === 'hex' ||
66+
encoding === 'HEX' ||
67+
encoding.toLowerCase() === 'hex'
68+
) {
6569
return HEX;
6670
}
6771
break;
6872
case 5:
69-
if (enc === 'ascii') return ASCII;
70-
if (enc === 'ucs-2') return UTF16LE;
71-
if (enc === 'UTF-8') return UTF8;
72-
if (enc === 'ASCII') return ASCII;
73-
if (enc === 'UCS-2') return UTF16LE;
74-
enc = `${enc}`.toLowerCase();
75-
if (enc === 'utf-8') return UTF8;
76-
if (enc === 'ascii') return ASCII;
77-
if (enc === 'ucs-2') return UTF16LE;
73+
if (encoding === 'ascii') return ASCII;
74+
if (encoding === 'ucs-2') return UTF16LE;
75+
if (encoding === 'UTF-8') return UTF8;
76+
if (encoding === 'ASCII') return ASCII;
77+
if (encoding === 'UCS-2') return UTF16LE;
78+
encoding = encoding.toLowerCase();
79+
if (encoding === 'utf-8') return UTF8;
80+
if (encoding === 'ascii') return ASCII;
81+
if (encoding === 'ucs-2') return UTF16LE;
7882
break;
7983
case 6:
80-
if (enc === 'base64') return BASE64;
81-
if (enc === 'latin1' || enc === 'binary') return LATIN1;
82-
if (enc === 'BASE64') return BASE64;
83-
if (enc === 'LATIN1' || enc === 'BINARY') return LATIN1;
84-
enc = `${enc}`.toLowerCase();
85-
if (enc === 'base64') return BASE64;
86-
if (enc === 'latin1' || enc === 'binary') return LATIN1;
84+
if (encoding === 'base64') return BASE64;
85+
if (encoding === 'latin1' || encoding === 'binary') return LATIN1;
86+
if (encoding === 'BASE64') return BASE64;
87+
if (encoding === 'LATIN1' || encoding === 'BINARY') return LATIN1;
88+
encoding = encoding.toLowerCase();
89+
if (encoding === 'base64') return BASE64;
90+
if (encoding === 'latin1' || encoding === 'binary') return LATIN1;
8791
break;
8892
case 7:
8993
if (
90-
enc === 'utf16le' ||
91-
enc === 'UTF16LE' ||
92-
`${enc}`.toLowerCase() === 'utf16le'
94+
encoding === 'utf16le' ||
95+
encoding === 'UTF16LE' ||
96+
encoding.toLowerCase() === 'utf16le'
9397
) {
9498
return UTF16LE;
9599
}
96100
break;
97101
case 8:
98102
if (
99-
enc === 'utf-16le' ||
100-
enc === 'UTF-16LE' ||
101-
`${enc}`.toLowerCase() === 'utf-16le'
103+
encoding === 'utf-16le' ||
104+
encoding === 'UTF-16LE' ||
105+
encoding.toLowerCase() === 'utf-16le'
102106
) {
103107
return UTF16LE;
104108
}
105109
break;
106110
case 9:
107111
if (
108-
enc === 'base64url' ||
109-
enc === 'BASE64URL' ||
110-
`${enc}`.toLowerCase() === 'base64url'
112+
encoding === 'base64url' ||
113+
encoding === 'BASE64URL' ||
114+
encoding.toLowerCase() === 'base64url'
111115
) {
112116
return BASE64URL;
113117
}
114118
break;
115119
default:
116-
if (enc === '') return UTF8;
120+
if (encoding === '') return UTF8;
117121
}
118122
return undefined;
119123
}

src/workerd/api/node/tests/buffer-nodejs-test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,29 @@ export const invalidEncodingForToString = {
147147
},
148148
};
149149

150+
export const toStringWithUndefinedEncoding = {
151+
test(ctrl, env, ctx) {
152+
// Test that Buffer.toString with undefined encoding defaults to utf8
153+
const buf = Buffer.from('hello world');
154+
strictEqual(buf.toString(undefined), 'hello world');
155+
strictEqual(buf.toString(undefined), buf.toString('utf8'));
156+
157+
// Test with UTF-8 characters
158+
const utf8Buf = Buffer.from('¡hέlló wôrld!');
159+
strictEqual(utf8Buf.toString(undefined), '¡hέlló wôrld!');
160+
strictEqual(utf8Buf.toString(undefined), utf8Buf.toString('utf8'));
161+
162+
// Test with start and end parameters
163+
const sliceBuf = Buffer.from('hello world');
164+
strictEqual(sliceBuf.toString(undefined, 0, 5), 'hello');
165+
strictEqual(sliceBuf.toString(undefined, 6), 'world');
166+
strictEqual(
167+
sliceBuf.toString(undefined, 0, 5),
168+
sliceBuf.toString('utf8', 0, 5)
169+
);
170+
},
171+
};
172+
150173
export const zeroLengthBuffers = {
151174
test(ctrl, env, ctx) {
152175
Buffer.from('');

0 commit comments

Comments
 (0)