-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add
Uint8Array.prototype.setFromBase64
and lastChunkHandling
option
- Loading branch information
Showing
18 changed files
with
259 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
packages/core-js-pure/override/modules/esnext.uint8-array.set-from-base64.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
// empty |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
'use strict'; | ||
require('../../modules/esnext.uint8-array.set-from-base64'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
'use strict'; | ||
var parent = require('../../actual/typed-array/set-from-base64'); | ||
|
||
module.exports = parent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
'use strict'; | ||
var globalThis = require('../internals/global-this'); | ||
var uncurryThis = require('../internals/function-uncurry-this'); | ||
var anObjectOrUndefined = require('../internals/an-object-or-undefined'); | ||
var aString = require('../internals/a-string'); | ||
var hasOwn = require('../internals/has-own-property'); | ||
var base64Map = require('../internals/base64-map'); | ||
var getAlphabetOption = require('../internals/get-alphabet-option'); | ||
var notDetached = require('../internals/array-buffer-not-detached'); | ||
|
||
var base64Alphabet = base64Map.c2i; | ||
var base64UrlAlphabet = base64Map.c2iUrl; | ||
|
||
var SyntaxError = globalThis.SyntaxError; | ||
var TypeError = globalThis.TypeError; | ||
var ASCII_WHITESPACE = /[\t\n\f\r ]/; | ||
var exec = uncurryThis(ASCII_WHITESPACE.exec); | ||
var at = uncurryThis(''.charAt); | ||
|
||
var skipAsciiWhitespace = function (string, index) { | ||
var length = string.length; | ||
for (;index < length; index++) { | ||
if (!exec(ASCII_WHITESPACE, at(string, index))) break; | ||
} return index; | ||
}; | ||
|
||
var decodeBase64Chunk = function (chunk, alphabet, throwOnExtraBits) { | ||
var chunkLength = chunk.length; | ||
|
||
if (chunkLength < 4) { | ||
chunk += chunkLength === 2 ? 'AA' : 'A'; | ||
} | ||
|
||
var triplet = (alphabet[at(chunk, 0)] << 18) | ||
+ (alphabet[at(chunk, 1)] << 12) | ||
+ (alphabet[at(chunk, 2)] << 6) | ||
+ alphabet[at(chunk, 3)]; | ||
|
||
var chunkBytes = [ | ||
(triplet >> 16) & 255, | ||
(triplet >> 8) & 255, | ||
triplet & 255 | ||
]; | ||
|
||
if (chunkLength === 2) { | ||
if (throwOnExtraBits && chunkBytes[1] !== 0) { | ||
throw new SyntaxError('Extra bits'); | ||
} | ||
return [chunkBytes[0]]; | ||
} | ||
|
||
if (chunkLength === 3) { | ||
if (throwOnExtraBits && chunkBytes[2] !== 0) { | ||
throw new SyntaxError('Extra bits'); | ||
} | ||
return [chunkBytes[0], chunkBytes[1]]; | ||
} | ||
|
||
return chunkBytes; | ||
}; | ||
|
||
var writeBytes = function (bytes, elements, written) { | ||
var elementsLength = elements.length; | ||
for (var index = 0; index < elementsLength; index++) { | ||
bytes[written + index] = elements[index]; | ||
} | ||
return written + elementsLength; | ||
}; | ||
|
||
/* eslint-disable max-statements, max-depth -- TODO */ | ||
module.exports = function (string, options, into, maxLength) { | ||
aString(string); | ||
anObjectOrUndefined(options); | ||
var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; | ||
var lastChunkHandling = options ? options.lastChunkHandling : undefined; | ||
|
||
if (lastChunkHandling === undefined) lastChunkHandling = 'loose'; | ||
|
||
if (lastChunkHandling !== 'loose' && lastChunkHandling !== 'strict' && lastChunkHandling !== 'stop-before-partial') { | ||
throw new TypeError('Incorrect `lastChunkHandling` option'); | ||
} | ||
|
||
if (into) notDetached(into.buffer); | ||
|
||
var bytes = into || []; | ||
var written = 0; | ||
var read = 0; | ||
var chunk = ''; | ||
var index = 0; | ||
|
||
if (maxLength) while (true) { | ||
index = skipAsciiWhitespace(string, index); | ||
if (index === string.length) { | ||
if (chunk.length > 0) { | ||
if (lastChunkHandling === 'stop-before-partial') { | ||
break; | ||
} | ||
if (lastChunkHandling === 'loose') { | ||
if (chunk.length === 1) { | ||
throw new SyntaxError('Malformed padding: exactly one additional character'); | ||
} | ||
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); | ||
} else { | ||
throw new SyntaxError('Missing padding'); | ||
} | ||
} | ||
read = string.length; | ||
break; | ||
} | ||
var chr = at(string, index); | ||
++index; | ||
if (chr === '=') { | ||
if (chunk.length < 2) { | ||
throw new SyntaxError('Padding is too early'); | ||
} | ||
index = skipAsciiWhitespace(string, index); | ||
if (chunk.length === 2) { | ||
if (index === string.length) { | ||
if (lastChunkHandling === 'stop-before-partial') { | ||
break; | ||
} | ||
throw new SyntaxError('Malformed padding: only one ='); | ||
} | ||
if (at(string, index) === '=') { | ||
++index; | ||
index = skipAsciiWhitespace(string, index); | ||
} | ||
} | ||
if (index < string.length) { | ||
throw new SyntaxError('Unexpected character after padding'); | ||
} | ||
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, lastChunkHandling === 'strict'), written); | ||
read = string.length; | ||
break; | ||
} | ||
if (!hasOwn(alphabet, chr)) { | ||
throw new SyntaxError('Unexpected character'); | ||
} | ||
var remainingBytes = maxLength - written; | ||
if (remainingBytes === 1 && chunk.length === 2 || remainingBytes === 2 && chunk.length === 3) { | ||
// special case: we can fit exactly the number of bytes currently represented by chunk, so we were just checking for `=` | ||
break; | ||
} | ||
|
||
chunk += chr; | ||
if (chunk.length === 4) { | ||
written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); | ||
chunk = ''; | ||
read = index; | ||
if (written === maxLength) { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
return { bytes: bytes, read: read, written: written }; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 3 additions & 62 deletions
65
packages/core-js/modules/esnext.uint8-array.from-base64.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,16 @@ | ||
'use strict'; | ||
var $ = require('../internals/export'); | ||
var globalThis = require('../internals/global-this'); | ||
var uncurryThis = require('../internals/function-uncurry-this'); | ||
var anObjectOrUndefined = require('../internals/an-object-or-undefined'); | ||
var aString = require('../internals/a-string'); | ||
var hasOwn = require('../internals/has-own-property'); | ||
var arrayFromConstructorAndList = require('../internals/array-from-constructor-and-list'); | ||
var base64Map = require('../internals/base64-map'); | ||
var getAlphabetOption = require('../internals/get-alphabet-option'); | ||
|
||
var base64Alphabet = base64Map.c2i; | ||
var base64UrlAlphabet = base64Map.c2iUrl; | ||
var $fromBase64 = require('../internals/uint8-from-base64'); | ||
|
||
var Uint8Array = globalThis.Uint8Array; | ||
var SyntaxError = globalThis.SyntaxError; | ||
var charAt = uncurryThis(''.charAt); | ||
var replace = uncurryThis(''.replace); | ||
var stringSlice = uncurryThis(''.slice); | ||
var push = uncurryThis([].push); | ||
var SPACES = /[\t\n\f\r ]/g; | ||
var EXTRA_BITS = 'Extra bits'; | ||
|
||
// `Uint8Array.fromBase64` method | ||
// https://github.com/tc39/proposal-arraybuffer-base64 | ||
if (Uint8Array) $({ target: 'Uint8Array', stat: true }, { | ||
fromBase64: function fromBase64(string /* , options */) { | ||
aString(string); | ||
var options = arguments.length > 1 ? anObjectOrUndefined(arguments[1]) : undefined; | ||
var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; | ||
var strict = options ? !!options.strict : false; | ||
|
||
var input = strict ? string : replace(string, SPACES, ''); | ||
|
||
if (input.length % 4 === 0) { | ||
if (stringSlice(input, -2) === '==') input = stringSlice(input, 0, -2); | ||
else if (stringSlice(input, -1) === '=') input = stringSlice(input, 0, -1); | ||
} else if (strict) throw new SyntaxError('Input is not correctly padded'); | ||
|
||
var lastChunkSize = input.length % 4; | ||
|
||
switch (lastChunkSize) { | ||
case 1: throw new SyntaxError('Bad input length'); | ||
case 2: input += 'AA'; break; | ||
case 3: input += 'A'; | ||
} | ||
|
||
var bytes = []; | ||
var i = 0; | ||
var inputLength = input.length; | ||
|
||
var at = function (shift) { | ||
var chr = charAt(input, i + shift); | ||
if (!hasOwn(alphabet, chr)) throw new SyntaxError('Bad char in input: "' + chr + '"'); | ||
return alphabet[chr] << (18 - 6 * shift); | ||
}; | ||
|
||
for (; i < inputLength; i += 4) { | ||
var triplet = at(0) + at(1) + at(2) + at(3); | ||
push(bytes, (triplet >> 16) & 255, (triplet >> 8) & 255, triplet & 255); | ||
} | ||
|
||
var byteLength = bytes.length; | ||
|
||
if (lastChunkSize === 2) { | ||
if (strict && bytes[byteLength - 2] !== 0) throw new SyntaxError(EXTRA_BITS); | ||
byteLength -= 2; | ||
} else if (lastChunkSize === 3) { | ||
if (strict && bytes[byteLength - 1] !== 0) throw new SyntaxError(EXTRA_BITS); | ||
byteLength--; | ||
} | ||
|
||
return arrayFromConstructorAndList(Uint8Array, bytes, byteLength); | ||
var result = $fromBase64(string, arguments.length > 1 ? arguments[1] : undefined, null, 0x1FFFFFFFFFFFFF); | ||
return arrayFromConstructorAndList(Uint8Array, result.bytes); | ||
} | ||
}); |
19 changes: 19 additions & 0 deletions
19
packages/core-js/modules/esnext.uint8-array.set-from-base64.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
'use strict'; | ||
var $ = require('../internals/export'); | ||
var globalThis = require('../internals/global-this'); | ||
var $fromBase64 = require('../internals/uint8-from-base64'); | ||
var anUint8Array = require('../internals/an-uint8-array'); | ||
|
||
var Uint8Array = globalThis.Uint8Array; | ||
|
||
// `Uint8Array.prototype.setFromBase64` method | ||
// https://github.com/tc39/proposal-arraybuffer-base64 | ||
if (Uint8Array) $({ target: 'Uint8Array', proto: true }, { | ||
setFromBase64: function setFromBase64(string /* , options */) { | ||
anUint8Array(this); | ||
|
||
var result = $fromBase64(string, arguments.length > 1 ? arguments[1] : undefined, this, this.length); | ||
|
||
return { read: result.read, written: result.written }; | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.