1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 21:50:00 -05:00

Make atob follow the spec (#2242)

This commit is contained in:
迷渡 2019-05-01 02:25:37 +08:00 committed by Ryan Dahl
parent a217e55fec
commit bbeb30fc5e
2 changed files with 53 additions and 8 deletions

View file

@ -176,20 +176,28 @@ class UTF8Encoder implements Encoder {
/** Decodes a string of data which has been encoded using base-64. */
export function atob(s: string): string {
const rem = s.length % 4;
// base64-js requires length exactly times of 4
if (rem > 0) {
s = s.padEnd(s.length + (4 - rem), "=");
s = String(s);
s = s.replace(/[\t\n\f\r ]/g, "");
if (s.length % 4 === 0) {
s = s.replace(/==?$/, "");
}
let byteArray;
try {
byteArray = base64.toByteArray(s);
} catch (_) {
const rem = s.length % 4;
if (rem === 1 || /[^+/0-9A-Za-z]/.test(s)) {
// TODO: throw `DOMException`
throw new DenoError(
ErrorKind.InvalidInput,
"The string to be decoded is not correctly encoded"
);
}
// base64-js requires length exactly times of 4
if (rem > 0) {
s = s.padEnd(s.length + (4 - rem), "=");
}
const byteArray: Uint8Array = base64.toByteArray(s);
let result = "";
for (let i = 0; i < byteArray.length; i++) {
result += String.fromCharCode(byteArray[i]);

View file

@ -13,6 +13,43 @@ test(function atobSuccess(): void {
assertEquals(decoded, "hello world");
});
test(function atobWithAsciiWhitespace(): void {
const encodedList = [
" aGVsbG8gd29ybGQ=",
" aGVsbG8gd29ybGQ=",
"aGVsbG8gd29ybGQ= ",
"aGVsbG8gd29ybGQ=\n",
"aGVsbG\t8gd29ybGQ=",
`aGVsbG\t8g
d29ybGQ=`
];
for (let encoded of encodedList) {
let decoded = atob(encoded);
assertEquals(decoded, "hello world");
}
});
test(function atobThrows(): void {
let threw = false;
try {
atob("aGVsbG8gd29ybGQ==");
} catch (e) {
threw = true;
}
assert(threw);
});
test(function atobThrows2(): void {
let threw = false;
try {
atob("aGVsbG8gd29ybGQ===");
} catch (e) {
threw = true;
}
assert(threw);
});
test(function btoaFailed(): void {
const text = "你好";
let err;