Skip to content

Commit 653c3b1

Browse files
XadillaXdanielleadams
authored andcommitted
buffer,lib: update atob to align wpt's base64.json
Refs: https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob-dev Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode PR-URL: #43901 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent ddb5402 commit 653c3b1

File tree

7 files changed

+330
-5
lines changed

7 files changed

+330
-5
lines changed

lib/buffer.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,8 @@ const kForgivingBase64AllowedChars = [
12561256
0x2F, // /
12571257
0x3D, // =
12581258
];
1259+
const kEqualSignIndex = ArrayPrototypeIndexOf(kForgivingBase64AllowedChars,
1260+
0x3D);
12591261

12601262
function atob(input) {
12611263
// The implementation here has not been performance optimized in any way and
@@ -1267,6 +1269,7 @@ function atob(input) {
12671269

12681270
input = `${input}`;
12691271
let nonAsciiWhitespaceCharCount = 0;
1272+
let equalCharCount = 0;
12701273

12711274
for (let n = 0; n < input.length; n++) {
12721275
const index = ArrayPrototypeIndexOf(
@@ -1277,13 +1280,36 @@ function atob(input) {
12771280
// The first 5 elements of `kForgivingBase64AllowedChars` are
12781281
// ASCII whitespace char codes.
12791282
nonAsciiWhitespaceCharCount++;
1283+
1284+
if (index === kEqualSignIndex) {
1285+
equalCharCount++;
1286+
} else if (equalCharCount) {
1287+
// The `=` char is only allowed at the end.
1288+
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
1289+
}
1290+
1291+
if (equalCharCount > 2) {
1292+
// Only one more `=` is permitted after the first equal sign.
1293+
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
1294+
}
12801295
} else if (index === -1) {
12811296
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
12821297
}
12831298
}
12841299

1300+
let reminder = nonAsciiWhitespaceCharCount % 4;
1301+
1302+
// See #2, #3, #4 - https://infra.spec.whatwg.org/#forgiving-base64
1303+
if (!reminder) {
1304+
// Remove all trailing `=` characters and get the new reminder.
1305+
reminder = (nonAsciiWhitespaceCharCount - equalCharCount) % 4;
1306+
} else if (equalCharCount) {
1307+
// `=` should not in the input if there's a reminder.
1308+
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
1309+
}
1310+
12851311
// See #3 - https://infra.spec.whatwg.org/#forgiving-base64
1286-
if (nonAsciiWhitespaceCharCount % 4 === 1) {
1312+
if (reminder === 1) {
12871313
throw lazyDOMException(
12881314
'The string to be decoded is not correctly encoded.',
12891315
'InvalidCharacterError');
@@ -1298,6 +1324,7 @@ module.exports = {
12981324
Buffer,
12991325
SlowBuffer,
13001326
transcode,
1327+
13011328
// Legacy
13021329
kMaxLength,
13031330
kStringMaxLength,

test/fixtures/wpt/LICENSE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# The 3-Clause BSD License
22

3-
Copyright © web-platform-tests contributors
3+
Copyright 2019 web-platform-tests contributors
44

55
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
66

test/fixtures/wpt/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Last update:
1515
- dom/abort: https://github.com/web-platform-tests/wpt/tree/c49cafb491/dom/abort
1616
- dom/events: https://github.com/web-platform-tests/wpt/tree/f8821adb28/dom/events
1717
- encoding: https://github.com/web-platform-tests/wpt/tree/c1b24fce6e/encoding
18+
- fetch/data-urls/resources: https://github.com/web-platform-tests/wpt/tree/7c79d998ff/fetch/data-urls/resources
1819
- FileAPI: https://github.com/web-platform-tests/wpt/tree/3b279420d4/FileAPI
1920
- hr-time: https://github.com/web-platform-tests/wpt/tree/34cafd797e/hr-time
2021
- html/webappapis/atob: https://github.com/web-platform-tests/wpt/tree/f267e1dca6/html/webappapis/atob
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
[
2+
["", []],
3+
["abcd", [105, 183, 29]],
4+
[" abcd", [105, 183, 29]],
5+
["abcd ", [105, 183, 29]],
6+
[" abcd===", null],
7+
["abcd=== ", null],
8+
["abcd ===", null],
9+
["a", null],
10+
["ab", [105]],
11+
["abc", [105, 183]],
12+
["abcde", null],
13+
["𐀀", null],
14+
["=", null],
15+
["==", null],
16+
["===", null],
17+
["====", null],
18+
["=====", null],
19+
["a=", null],
20+
["a==", null],
21+
["a===", null],
22+
["a====", null],
23+
["a=====", null],
24+
["ab=", null],
25+
["ab==", [105]],
26+
["ab===", null],
27+
["ab====", null],
28+
["ab=====", null],
29+
["abc=", [105, 183]],
30+
["abc==", null],
31+
["abc===", null],
32+
["abc====", null],
33+
["abc=====", null],
34+
["abcd=", null],
35+
["abcd==", null],
36+
["abcd===", null],
37+
["abcd====", null],
38+
["abcd=====", null],
39+
["abcde=", null],
40+
["abcde==", null],
41+
["abcde===", null],
42+
["abcde====", null],
43+
["abcde=====", null],
44+
["=a", null],
45+
["=a=", null],
46+
["a=b", null],
47+
["a=b=", null],
48+
["ab=c", null],
49+
["ab=c=", null],
50+
["abc=d", null],
51+
["abc=d=", null],
52+
["ab\u000Bcd", null],
53+
["ab\u3000cd", null],
54+
["ab\u3001cd", null],
55+
["ab\tcd", [105, 183, 29]],
56+
["ab\ncd", [105, 183, 29]],
57+
["ab\fcd", [105, 183, 29]],
58+
["ab\rcd", [105, 183, 29]],
59+
["ab cd", [105, 183, 29]],
60+
["ab\u00a0cd", null],
61+
["ab\t\n\f\r cd", [105, 183, 29]],
62+
[" \t\n\f\r ab\t\n\f\r cd\t\n\f\r ", [105, 183, 29]],
63+
["ab\t\n\f\r =\t\n\f\r =\t\n\f\r ", [105]],
64+
["A", null],
65+
["/A", [252]],
66+
["//A", [255, 240]],
67+
["///A", [255, 255, 192]],
68+
["////A", null],
69+
["/", null],
70+
["A/", [3]],
71+
["AA/", [0, 15]],
72+
["AAAA/", null],
73+
["AAA/", [0, 0, 63]],
74+
["\u0000nonsense", null],
75+
["abcd\u0000nonsense", null],
76+
["YQ", [97]],
77+
["YR", [97]],
78+
["~~", null],
79+
["..", null],
80+
["--", null],
81+
["__", null]
82+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
[
2+
["data://test/,X",
3+
"text/plain;charset=US-ASCII",
4+
[88]],
5+
["data://test:test/,X",
6+
null],
7+
["data:,X",
8+
"text/plain;charset=US-ASCII",
9+
[88]],
10+
["data:",
11+
null],
12+
["data:text/html",
13+
null],
14+
["data:text/html ;charset=x ",
15+
null],
16+
["data:,",
17+
"text/plain;charset=US-ASCII",
18+
[]],
19+
["data:,X#X",
20+
"text/plain;charset=US-ASCII",
21+
[88]],
22+
["data:,%FF",
23+
"text/plain;charset=US-ASCII",
24+
[255]],
25+
["data:text/plain,X",
26+
"text/plain",
27+
[88]],
28+
["data:text/plain ,X",
29+
"text/plain",
30+
[88]],
31+
["data:text/plain%20,X",
32+
"text/plain%20",
33+
[88]],
34+
["data:text/plain\f,X",
35+
"text/plain%0c",
36+
[88]],
37+
["data:text/plain%0C,X",
38+
"text/plain%0c",
39+
[88]],
40+
["data:text/plain;,X",
41+
"text/plain",
42+
[88]],
43+
["data:;x=x;charset=x,X",
44+
"text/plain;x=x;charset=x",
45+
[88]],
46+
["data:;x=x,X",
47+
"text/plain;x=x",
48+
[88]],
49+
["data:text/plain;charset=windows-1252,%C2%B1",
50+
"text/plain;charset=windows-1252",
51+
[194, 177]],
52+
["data:text/plain;Charset=UTF-8,%C2%B1",
53+
"text/plain;charset=UTF-8",
54+
[194, 177]],
55+
["data:text/plain;charset=windows-1252,áñçə💩",
56+
"text/plain;charset=windows-1252",
57+
[195, 161, 195, 177, 195, 167, 201, 153, 240, 159, 146, 169]],
58+
["data:text/plain;charset=UTF-8,áñçə💩",
59+
"text/plain;charset=UTF-8",
60+
[195, 161, 195, 177, 195, 167, 201, 153, 240, 159, 146, 169]],
61+
["data:image/gif,%C2%B1",
62+
"image/gif",
63+
[194, 177]],
64+
["data:IMAGE/gif,%C2%B1",
65+
"image/gif",
66+
[194, 177]],
67+
["data:IMAGE/gif;hi=x,%C2%B1",
68+
"image/gif;hi=x",
69+
[194, 177]],
70+
["data:IMAGE/gif;CHARSET=x,%C2%B1",
71+
"image/gif;charset=x",
72+
[194, 177]],
73+
["data: ,%FF",
74+
"text/plain;charset=US-ASCII",
75+
[255]],
76+
["data:%20,%FF",
77+
"text/plain;charset=US-ASCII",
78+
[255]],
79+
["data:\f,%FF",
80+
"text/plain;charset=US-ASCII",
81+
[255]],
82+
["data:%1F,%FF",
83+
"text/plain;charset=US-ASCII",
84+
[255]],
85+
["data:\u0000,%FF",
86+
"text/plain;charset=US-ASCII",
87+
[255]],
88+
["data:%00,%FF",
89+
"text/plain;charset=US-ASCII",
90+
[255]],
91+
["data:text/html ,X",
92+
"text/html",
93+
[88]],
94+
["data:text / html,X",
95+
"text/plain;charset=US-ASCII",
96+
[88]],
97+
["data:†,X",
98+
"text/plain;charset=US-ASCII",
99+
[88]],
100+
["data:†/†,X",
101+
"%e2%80%a0/%e2%80%a0",
102+
[88]],
103+
["data:X,X",
104+
"text/plain;charset=US-ASCII",
105+
[88]],
106+
["data:image/png,X X",
107+
"image/png",
108+
[88, 32, 88]],
109+
["data:application/javascript,X X",
110+
"application/javascript",
111+
[88, 32, 88]],
112+
["data:application/xml,X X",
113+
"application/xml",
114+
[88, 32, 88]],
115+
["data:text/javascript,X X",
116+
"text/javascript",
117+
[88, 32, 88]],
118+
["data:text/plain,X X",
119+
"text/plain",
120+
[88, 32, 88]],
121+
["data:unknown/unknown,X X",
122+
"unknown/unknown",
123+
[88, 32, 88]],
124+
["data:text/plain;a=\",\",X",
125+
"text/plain;a=\"\"",
126+
[34, 44, 88]],
127+
["data:text/plain;a=%2C,X",
128+
"text/plain;a=%2C",
129+
[88]],
130+
["data:;base64;base64,WA",
131+
"text/plain",
132+
[88]],
133+
["data:x/x;base64;base64,WA",
134+
"x/x",
135+
[88]],
136+
["data:x/x;base64;charset=x,WA",
137+
"x/x;charset=x",
138+
[87, 65]],
139+
["data:x/x;base64;charset=x;base64,WA",
140+
"x/x;charset=x",
141+
[88]],
142+
["data:x/x;base64;base64x,WA",
143+
"x/x",
144+
[87, 65]],
145+
["data:;base64,W%20A",
146+
"text/plain;charset=US-ASCII",
147+
[88]],
148+
["data:;base64,W%0CA",
149+
"text/plain;charset=US-ASCII",
150+
[88]],
151+
["data:x;base64x,WA",
152+
"text/plain;charset=US-ASCII",
153+
[87, 65]],
154+
["data:x;base64;x,WA",
155+
"text/plain;charset=US-ASCII",
156+
[87, 65]],
157+
["data:x;base64=x,WA",
158+
"text/plain;charset=US-ASCII",
159+
[87, 65]],
160+
["data:; base64,WA",
161+
"text/plain;charset=US-ASCII",
162+
[88]],
163+
["data:; base64,WA",
164+
"text/plain;charset=US-ASCII",
165+
[88]],
166+
["data: ;charset=x ; base64,WA",
167+
"text/plain;charset=x",
168+
[88]],
169+
["data:;base64;,WA",
170+
"text/plain",
171+
[87, 65]],
172+
["data:;base64 ,WA",
173+
"text/plain;charset=US-ASCII",
174+
[88]],
175+
["data:;base64 ,WA",
176+
"text/plain;charset=US-ASCII",
177+
[88]],
178+
["data:;base 64,WA",
179+
"text/plain",
180+
[87, 65]],
181+
["data:;BASe64,WA",
182+
"text/plain;charset=US-ASCII",
183+
[88]],
184+
["data:;%62ase64,WA",
185+
"text/plain",
186+
[87, 65]],
187+
["data:%3Bbase64,WA",
188+
"text/plain;charset=US-ASCII",
189+
[87, 65]],
190+
["data:;charset=x,X",
191+
"text/plain;charset=x",
192+
[88]],
193+
["data:; charset=x,X",
194+
"text/plain;charset=x",
195+
[88]],
196+
["data:;charset =x,X",
197+
"text/plain",
198+
[88]],
199+
["data:;charset= x,X",
200+
"text/plain;charset=\" x\"",
201+
[88]],
202+
["data:;charset=,X",
203+
"text/plain",
204+
[88]],
205+
["data:;charset,X",
206+
"text/plain",
207+
[88]],
208+
["data:;charset=\"x\",X",
209+
"text/plain;charset=x",
210+
[88]],
211+
["data:;CHARSET=\"X\",X",
212+
"text/plain;charset=X",
213+
[88]]
214+
]

test/fixtures/wpt/versions.json

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
"commit": "c1b24fce6e625c1b79124a58f27bf9adce02d5d7",
2020
"path": "encoding"
2121
},
22+
"fetch/data-urls/resources": {
23+
"commit": "7c79d998ff42e52de90290cb847d1b515b3b58f7",
24+
"path": "fetch/data-urls/resources"
25+
},
2226
"FileAPI": {
2327
"commit": "3b279420d40afea32506e823f9ac005448f4f3d8",
2428
"path": "FileAPI"
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
{
2-
"base64.any.js": {
3-
"skip": "no such file or directory fetch/data-urls/resources/base64.json"
4-
}
52
}

0 commit comments

Comments
 (0)