avancement planning
This commit is contained in:
+35
-16
@@ -29,13 +29,6 @@ var sequentialMode = false
|
||||
var inlineObjectReadThreshold = 2
|
||||
var readStruct, onLoadedStructures, onSaveState
|
||||
var BlockedFunction // we use search and replace to change the next call to BlockedFunction to avoid CSP issues for
|
||||
// no-eval build
|
||||
try {
|
||||
new Function('')
|
||||
} catch(error) {
|
||||
// if eval variants are not supported, do not create inline object readers ever
|
||||
inlineObjectReadThreshold = Infinity
|
||||
}
|
||||
|
||||
export class Unpackr {
|
||||
constructor(options) {
|
||||
@@ -508,11 +501,18 @@ function createStructureReader(structure, firstId) {
|
||||
function readObject() {
|
||||
// This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
|
||||
if (readObject.count++ > inlineObjectReadThreshold) {
|
||||
let readObject = structure.read = (new Function('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
|
||||
'({' + structure.map(key => key === '__proto__' ? '__proto_:r()' : validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read)
|
||||
let optimizedReadObject
|
||||
try {
|
||||
optimizedReadObject = structure.read = (new Function('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
|
||||
'({' + structure.map(key => key === '__proto__' ? '__proto_:r()' : validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read)
|
||||
} catch(error) {
|
||||
// in CF workers, the new Function call could begin to fail at any point in time
|
||||
inlineObjectReadThreshold = Infinity // disable going forward
|
||||
return readObject(); // recursively try again
|
||||
}
|
||||
if (structure.highByte === 0)
|
||||
structure.read = createSecondByteReader(firstId, structure.read)
|
||||
return readObject() // second byte is already read, if there is one so immediately read object
|
||||
return optimizedReadObject() // second byte is already read, if there is one so immediately read object
|
||||
}
|
||||
let object = {}
|
||||
for (let i = 0, l = structure.length; i < l; i++) {
|
||||
@@ -621,26 +621,45 @@ function readStringJS(length) {
|
||||
} else if ((byte1 & 0xe0) === 0xc0) {
|
||||
// 2 bytes
|
||||
const byte2 = src[position++] & 0x3f
|
||||
units.push(((byte1 & 0x1f) << 6) | byte2)
|
||||
const codePoint = ((byte1 & 0x1f) << 6) | byte2
|
||||
// Reject overlong encoding: 2-byte sequences must encode values >= 0x80
|
||||
if (codePoint < 0x80) {
|
||||
units.push(0xFFFD) // replacement character
|
||||
} else {
|
||||
units.push(codePoint)
|
||||
}
|
||||
} else if ((byte1 & 0xf0) === 0xe0) {
|
||||
// 3 bytes
|
||||
const byte2 = src[position++] & 0x3f
|
||||
const byte3 = src[position++] & 0x3f
|
||||
units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3)
|
||||
const codePoint = ((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3
|
||||
// Reject overlong encoding: 3-byte sequences must encode values >= 0x800
|
||||
// Also reject surrogates (0xD800-0xDFFF)
|
||||
if (codePoint < 0x800 || (codePoint >= 0xD800 && codePoint <= 0xDFFF)) {
|
||||
units.push(0xFFFD) // replacement character
|
||||
} else {
|
||||
units.push(codePoint)
|
||||
}
|
||||
} else if ((byte1 & 0xf8) === 0xf0) {
|
||||
// 4 bytes
|
||||
const byte2 = src[position++] & 0x3f
|
||||
const byte3 = src[position++] & 0x3f
|
||||
const byte4 = src[position++] & 0x3f
|
||||
let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4
|
||||
if (unit > 0xffff) {
|
||||
// Reject overlong encoding: 4-byte sequences must encode values >= 0x10000
|
||||
// Also reject values > 0x10FFFF (maximum valid Unicode)
|
||||
if (unit < 0x10000 || unit > 0x10FFFF) {
|
||||
units.push(0xFFFD) // replacement character
|
||||
} else if (unit > 0xffff) {
|
||||
unit -= 0x10000
|
||||
units.push(((unit >>> 10) & 0x3ff) | 0xd800)
|
||||
unit = 0xdc00 | (unit & 0x3ff)
|
||||
units.push(unit)
|
||||
} else {
|
||||
units.push(unit)
|
||||
}
|
||||
units.push(unit)
|
||||
} else {
|
||||
units.push(byte1)
|
||||
units.push(0xFFFD) // replacement character for invalid lead byte
|
||||
}
|
||||
|
||||
if (units.length >= 0x1000) {
|
||||
@@ -1013,7 +1032,7 @@ currentExtensions[0x42] = data => {
|
||||
if (length <= 40) {
|
||||
let out = view.getBigUint64(start)
|
||||
for (let i = start + 8; i < end; i += 8) {
|
||||
out <<= BigInt(64n)
|
||||
out <<= BigInt(64)
|
||||
out |= view.getBigUint64(i)
|
||||
}
|
||||
return out
|
||||
|
||||
Reference in New Issue
Block a user