Skip to content

Commit

Permalink
buffer,lib: update atob to align wpt's base64.json
Browse files Browse the repository at this point in the history
  • Loading branch information
XadillaX committed Oct 9, 2022
1 parent 6831e2f commit 3a7fcdc
Show file tree
Hide file tree
Showing 7 changed files with 330 additions and 5 deletions.
29 changes: 28 additions & 1 deletion lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,8 @@ const kForgivingBase64AllowedChars = [
0x2F, // /
0x3D, // =
];
const kEqualSignIndex = ArrayPrototypeIndexOf(kForgivingBase64AllowedChars,
0x3D);

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

input = `${input}`;
let nonAsciiWhitespaceCharCount = 0;
let equalCharCount = 0;

for (let n = 0; n < input.length; n++) {
const index = ArrayPrototypeIndexOf(
Expand All @@ -1277,13 +1280,36 @@ function atob(input) {
// The first 5 elements of `kForgivingBase64AllowedChars` are
// ASCII whitespace char codes.
nonAsciiWhitespaceCharCount++;

if (index === kEqualSignIndex) {
equalCharCount++;
} else if (equalCharCount) {
// The `=` char is only allowed at the end.
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
}

if (equalCharCount > 2) {
// Only one more `=` is permitted after the first equal sign.
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
}
} else if (index === -1) {
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
}
}

let reminder = nonAsciiWhitespaceCharCount % 4;

// See #2, #3, #4 - https://infra.spec.whatwg.org/#forgiving-base64
if (!reminder) {
// Remove all trailing `=` characters and get the new reminder.
reminder = (nonAsciiWhitespaceCharCount - equalCharCount) % 4;
} else if (equalCharCount) {
// `=` should not in the input if there's a reminder.
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
}

// See #3 - https://infra.spec.whatwg.org/#forgiving-base64
if (nonAsciiWhitespaceCharCount % 4 === 1) {
if (reminder === 1) {
throw lazyDOMException(
'The string to be decoded is not correctly encoded.',
'InvalidCharacterError');
Expand All @@ -1298,6 +1324,7 @@ module.exports = {
Buffer,
SlowBuffer,
transcode,

// Legacy
kMaxLength,
kStringMaxLength,
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/wpt/LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The 3-Clause BSD License

Copyright © web-platform-tests contributors
Copyright 2019 web-platform-tests contributors

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

Expand Down
1 change: 1 addition & 0 deletions test/fixtures/wpt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Last update:
- dom/abort: https://github.com/web-platform-tests/wpt/tree/c49cafb491/dom/abort
- dom/events: https://github.com/web-platform-tests/wpt/tree/f8821adb28/dom/events
- encoding: https://github.com/web-platform-tests/wpt/tree/c1b24fce6e/encoding
- fetch/data-urls/resources: https://github.com/web-platform-tests/wpt/tree/7c79d998ff/fetch/data-urls/resources
- FileAPI: https://github.com/web-platform-tests/wpt/tree/3b279420d4/FileAPI
- hr-time: https://github.com/web-platform-tests/wpt/tree/34cafd797e/hr-time
- html/webappapis/atob: https://github.com/web-platform-tests/wpt/tree/f267e1dca6/html/webappapis/atob
Expand Down
82 changes: 82 additions & 0 deletions test/fixtures/wpt/fetch/data-urls/resources/base64.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
[
["", []],
["abcd", [105, 183, 29]],
[" abcd", [105, 183, 29]],
["abcd ", [105, 183, 29]],
[" abcd===", null],
["abcd=== ", null],
["abcd ===", null],
["a", null],
["ab", [105]],
["abc", [105, 183]],
["abcde", null],
["𐀀", null],
["=", null],
["==", null],
["===", null],
["====", null],
["=====", null],
["a=", null],
["a==", null],
["a===", null],
["a====", null],
["a=====", null],
["ab=", null],
["ab==", [105]],
["ab===", null],
["ab====", null],
["ab=====", null],
["abc=", [105, 183]],
["abc==", null],
["abc===", null],
["abc====", null],
["abc=====", null],
["abcd=", null],
["abcd==", null],
["abcd===", null],
["abcd====", null],
["abcd=====", null],
["abcde=", null],
["abcde==", null],
["abcde===", null],
["abcde====", null],
["abcde=====", null],
["=a", null],
["=a=", null],
["a=b", null],
["a=b=", null],
["ab=c", null],
["ab=c=", null],
["abc=d", null],
["abc=d=", null],
["ab\u000Bcd", null],
["ab\u3000cd", null],
["ab\u3001cd", null],
["ab\tcd", [105, 183, 29]],
["ab\ncd", [105, 183, 29]],
["ab\fcd", [105, 183, 29]],
["ab\rcd", [105, 183, 29]],
["ab cd", [105, 183, 29]],
["ab\u00a0cd", null],
["ab\t\n\f\r cd", [105, 183, 29]],
[" \t\n\f\r ab\t\n\f\r cd\t\n\f\r ", [105, 183, 29]],
["ab\t\n\f\r =\t\n\f\r =\t\n\f\r ", [105]],
["A", null],
["/A", [252]],
["//A", [255, 240]],
["///A", [255, 255, 192]],
["////A", null],
["/", null],
["A/", [3]],
["AA/", [0, 15]],
["AAAA/", null],
["AAA/", [0, 0, 63]],
["\u0000nonsense", null],
["abcd\u0000nonsense", null],
["YQ", [97]],
["YR", [97]],
["~~", null],
["..", null],
["--", null],
["__", null]
]
214 changes: 214 additions & 0 deletions test/fixtures/wpt/fetch/data-urls/resources/data-urls.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
[
["data://test/,X",
"text/plain;charset=US-ASCII",
[88]],
["data://test:test/,X",
null],
["data:,X",
"text/plain;charset=US-ASCII",
[88]],
["data:",
null],
["data:text/html",
null],
["data:text/html ;charset=x ",
null],
["data:,",
"text/plain;charset=US-ASCII",
[]],
["data:,X#X",
"text/plain;charset=US-ASCII",
[88]],
["data:,%FF",
"text/plain;charset=US-ASCII",
[255]],
["data:text/plain,X",
"text/plain",
[88]],
["data:text/plain ,X",
"text/plain",
[88]],
["data:text/plain%20,X",
"text/plain%20",
[88]],
["data:text/plain\f,X",
"text/plain%0c",
[88]],
["data:text/plain%0C,X",
"text/plain%0c",
[88]],
["data:text/plain;,X",
"text/plain",
[88]],
["data:;x=x;charset=x,X",
"text/plain;x=x;charset=x",
[88]],
["data:;x=x,X",
"text/plain;x=x",
[88]],
["data:text/plain;charset=windows-1252,%C2%B1",
"text/plain;charset=windows-1252",
[194, 177]],
["data:text/plain;Charset=UTF-8,%C2%B1",
"text/plain;charset=UTF-8",
[194, 177]],
["data:text/plain;charset=windows-1252,áñçə💩",
"text/plain;charset=windows-1252",
[195, 161, 195, 177, 195, 167, 201, 153, 240, 159, 146, 169]],
["data:text/plain;charset=UTF-8,áñçə💩",
"text/plain;charset=UTF-8",
[195, 161, 195, 177, 195, 167, 201, 153, 240, 159, 146, 169]],
["data:image/gif,%C2%B1",
"image/gif",
[194, 177]],
["data:IMAGE/gif,%C2%B1",
"image/gif",
[194, 177]],
["data:IMAGE/gif;hi=x,%C2%B1",
"image/gif;hi=x",
[194, 177]],
["data:IMAGE/gif;CHARSET=x,%C2%B1",
"image/gif;charset=x",
[194, 177]],
["data: ,%FF",
"text/plain;charset=US-ASCII",
[255]],
["data:%20,%FF",
"text/plain;charset=US-ASCII",
[255]],
["data:\f,%FF",
"text/plain;charset=US-ASCII",
[255]],
["data:%1F,%FF",
"text/plain;charset=US-ASCII",
[255]],
["data:\u0000,%FF",
"text/plain;charset=US-ASCII",
[255]],
["data:%00,%FF",
"text/plain;charset=US-ASCII",
[255]],
["data:text/html ,X",
"text/html",
[88]],
["data:text / html,X",
"text/plain;charset=US-ASCII",
[88]],
["data:†,X",
"text/plain;charset=US-ASCII",
[88]],
["data:†/†,X",
"%e2%80%a0/%e2%80%a0",
[88]],
["data:X,X",
"text/plain;charset=US-ASCII",
[88]],
["data:image/png,X X",
"image/png",
[88, 32, 88]],
["data:application/javascript,X X",
"application/javascript",
[88, 32, 88]],
["data:application/xml,X X",
"application/xml",
[88, 32, 88]],
["data:text/javascript,X X",
"text/javascript",
[88, 32, 88]],
["data:text/plain,X X",
"text/plain",
[88, 32, 88]],
["data:unknown/unknown,X X",
"unknown/unknown",
[88, 32, 88]],
["data:text/plain;a=\",\",X",
"text/plain;a=\"\"",
[34, 44, 88]],
["data:text/plain;a=%2C,X",
"text/plain;a=%2C",
[88]],
["data:;base64;base64,WA",
"text/plain",
[88]],
["data:x/x;base64;base64,WA",
"x/x",
[88]],
["data:x/x;base64;charset=x,WA",
"x/x;charset=x",
[87, 65]],
["data:x/x;base64;charset=x;base64,WA",
"x/x;charset=x",
[88]],
["data:x/x;base64;base64x,WA",
"x/x",
[87, 65]],
["data:;base64,W%20A",
"text/plain;charset=US-ASCII",
[88]],
["data:;base64,W%0CA",
"text/plain;charset=US-ASCII",
[88]],
["data:x;base64x,WA",
"text/plain;charset=US-ASCII",
[87, 65]],
["data:x;base64;x,WA",
"text/plain;charset=US-ASCII",
[87, 65]],
["data:x;base64=x,WA",
"text/plain;charset=US-ASCII",
[87, 65]],
["data:; base64,WA",
"text/plain;charset=US-ASCII",
[88]],
["data:; base64,WA",
"text/plain;charset=US-ASCII",
[88]],
["data: ;charset=x ; base64,WA",
"text/plain;charset=x",
[88]],
["data:;base64;,WA",
"text/plain",
[87, 65]],
["data:;base64 ,WA",
"text/plain;charset=US-ASCII",
[88]],
["data:;base64 ,WA",
"text/plain;charset=US-ASCII",
[88]],
["data:;base 64,WA",
"text/plain",
[87, 65]],
["data:;BASe64,WA",
"text/plain;charset=US-ASCII",
[88]],
["data:;%62ase64,WA",
"text/plain",
[87, 65]],
["data:%3Bbase64,WA",
"text/plain;charset=US-ASCII",
[87, 65]],
["data:;charset=x,X",
"text/plain;charset=x",
[88]],
["data:; charset=x,X",
"text/plain;charset=x",
[88]],
["data:;charset =x,X",
"text/plain",
[88]],
["data:;charset= x,X",
"text/plain;charset=\" x\"",
[88]],
["data:;charset=,X",
"text/plain",
[88]],
["data:;charset,X",
"text/plain",
[88]],
["data:;charset=\"x\",X",
"text/plain;charset=x",
[88]],
["data:;CHARSET=\"X\",X",
"text/plain;charset=X",
[88]]
]
4 changes: 4 additions & 0 deletions test/fixtures/wpt/versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
"commit": "c1b24fce6e625c1b79124a58f27bf9adce02d5d7",
"path": "encoding"
},
"fetch/data-urls/resources": {
"commit": "7c79d998ff42e52de90290cb847d1b515b3b58f7",
"path": "fetch/data-urls/resources"
},
"FileAPI": {
"commit": "3b279420d40afea32506e823f9ac005448f4f3d8",
"path": "FileAPI"
Expand Down
3 changes: 0 additions & 3 deletions test/wpt/status/html/webappapis/atob.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
{
"base64.any.js": {
"skip": "no such file or directory fetch/data-urls/resources/base64.json"
}
}

0 comments on commit 3a7fcdc

Please sign in to comment.