summaryrefslogtreecommitdiff
path: root/data/extensions/jsr@javascriptrestrictor/wrappingS-ECMA-ARRAY.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/jsr@javascriptrestrictor/wrappingS-ECMA-ARRAY.js')
-rw-r--r--data/extensions/jsr@javascriptrestrictor/wrappingS-ECMA-ARRAY.js694
1 files changed, 0 insertions, 694 deletions
diff --git a/data/extensions/jsr@javascriptrestrictor/wrappingS-ECMA-ARRAY.js b/data/extensions/jsr@javascriptrestrictor/wrappingS-ECMA-ARRAY.js
deleted file mode 100644
index b5f56b2..0000000
--- a/data/extensions/jsr@javascriptrestrictor/wrappingS-ECMA-ARRAY.js
+++ /dev/null
@@ -1,694 +0,0 @@
-/** \file
- * \brief Wrappers for arrays from the ECMA standard library
- *
- * \author Copyright (C) 2020 Peter Hornak
- *
- * \license SPDX-License-Identifier: GPL-3.0-or-later
- */
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-//
-
-/** \file
- * \ingroup wrappers
- *
- * This wrapper aims on prevention of microarchitectural attacks like Meltdown and Spectre. This
- * code was originally a part of [ChromeZero](https://github.com/IAIK/ChromeZero).
- *
- * \bug The `subarray()` method always ruturns the full array.
- *
- * The wrappers support the following behaviour:
- *
- * * Offset: The content of the buffer is shifted by a fix offset. This is a faster method but can
- * be removed.
- * * Random mapping: All items are mapped randomly. This is a slower method but more reliable.
- *
- * \see <https://www.fit.vut.cz/study/thesis/22374/?year=0&sup=Pol%C4%8D%C3%A1k>, especially Sect. 5.1
- */
-
-
-/// \see This function was adopted from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js under MIT licence.
-function packIEEE754(v, ebits, fbits) {
- var bias = (1 << (ebits - 1)) - 1;
-
- function roundToEven(n) {
- var w = Math.floor(n), f = n - w;
- if (f < 0.5)
- return w;
- if (f > 0.5)
- return w + 1;
- return w % 2 ? w + 1 : w;
- }
-
- // Compute sign, exponent, fraction
- var s, e, f;
- if (v !== v) {
- // NaN
- // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
- e = (1 << ebits) - 1;
- f = Math.pow(2, fbits - 1);
- s = 0;
- } else if (v === Infinity || v === -Infinity) {
- e = (1 << ebits) - 1;
- f = 0;
- s = (v < 0) ? 1 : 0;
- } else if (v === 0) {
- e = 0;
- f = 0;
- s = (1 / v === -Infinity) ? 1 : 0;
- } else {
- s = v < 0;
- v = Math.abs(v);
-
- if (v >= Math.pow(2, 1 - bias)) {
- // Normalized
- e = Math.min(Math.floor(Math.log(v) / Math.LN2), 1023);
- var significand = v / Math.pow(2, e);
- if (significand < 1) {
- e -= 1;
- significand *= 2;
- }
- if (significand >= 2) {
- e += 1;
- significand /= 2;
- }
- var d = Math.pow(2, fbits);
- f = roundToEven(significand * d) - d;
- e += bias;
- if (f / d >= 1) {
- e += 1;
- f = 0;
- }
- if (e > 2 * bias) {
- // Overflow
- e = (1 << ebits) - 1;
- f = 0;
- }
- } else {
- // Denormalized
- e = 0;
- f = roundToEven(v / Math.pow(2, 1 - bias - fbits));
- }
- }
-
- // Pack sign, exponent, fraction
- var bits = [], i;
- for (i = fbits; i; i -= 1) {
- bits.push(f % 2 ? 1 : 0);
- f = Math.floor(f / 2);
- }
- for (i = ebits; i; i -= 1) {
- bits.push(e % 2 ? 1 : 0);
- e = Math.floor(e / 2);
- }
- bits.push(s ? 1 : 0);
- bits.reverse();
- var str = bits.join('');
-
- // Bits to bytes
- var bytes = [];
- while (str.length) {
- bytes.unshift(parseInt(str.substring(0, 8), 2));
- str = str.substring(8);
- }
- return bytes;
-}
-
-/// \see This function was adopted from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js under MIT licence.
-function unpackIEEE754(bytes, ebits, fbits) {
- // Bytes to bits
- var bits = [], i, j, b, str,
- bias, s, e, f;
-
- for (i = 0; i < bytes.length; ++i) {
- b = bytes[i];
- for (j = 8; j; j -= 1) {
- bits.push(b % 2 ? 1 : 0);
- b = b >> 1;
- }
- }
- bits.reverse();
- str = bits.join('');
-
- // Unpack sign, exponent, fraction
- bias = (1 << (ebits - 1)) - 1;
- s = parseInt(str.substring(0, 1), 2) ? -1 : 1;
- e = parseInt(str.substring(1, 1 + ebits), 2);
- f = parseInt(str.substring(1 + ebits), 2);
-
- // Produce number
- if (e === (1 << ebits) - 1) {
- return f !== 0 ? NaN : s * Infinity;
- } else if (e > 0) {
- // Normalized
- return s * Math.pow(2, e - bias) * (1 + f / Math.pow(2, fbits));
- } else if (f !== 0) {
- // Denormalized
- return s * Math.pow(2, -(bias - 1)) * (f / Math.pow(2, fbits));
- } else {
- return s < 0 ? -0 : 0;
- }
-}
-
-/// \see Function was adopted from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js under MIT licence.
-function unpackF64(b) {
- return unpackIEEE754(b, 11, 52);
-}
-
-/// \see Function was adopted from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js under MIT licence.
-function packF64(v) {
- return packIEEE754(v, 11, 52);
-}
-
-/// \see Function was adopted from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js under MIT licence.
-function unpackF32(b) {
- return unpackIEEE754(b, 8, 23);
-}
-
-/// \see Function was adopted from https://github.com/inexorabletash/polyfill/blob/master/typedarray.js under MIT licence.
-function packF32(v) {
- return packIEEE754(v, 8, 23);
-}
-
-function constructDecorator(wrapped) {
- return function () {
- const res = wrapped.apply(originalF, arguments);
- return replacementF(res);
- }
-}
-
-function offsetDecorator(wrapped, type, proxyRef, offsetF) {
- return function () {
- var ref = proxyRef;
- let newArr = [];
- // Create a copy of array
- for (let i = 0; i < this.length; i++) {
- newArr[i] = this[offsetF(i)]
- }
- // Shift to original
- for (let i = 0; i < this.length; i++) {
- this[i] = newArr[i];
- }
- // Do func
- let res;
- if (type === 3) {
- res = new this.__proto__.constructor(this)[wrapped.name.split(' ')[1]]()
- } else {
- res = wrapped.apply(this, arguments);
- }
- // Create copy of new arr
- let secArr = [];
- for (let i = 0; i < this.length; i++) {
- secArr[i] = this[i];
- }
- for (let i = 0; i < this.length; i++) {
- this[offsetF(i)] = secArr[i];
- }
- switch (type) {
- case 0:
- return ref;
- case 1:
- return replacementF(res);
- case 2:
- return res;
- default:
- return res
- }
- }
-}
-
-function redefineNewArrayFunctions(target, offsetF) {
- target['sort'] = offsetDecorator(target['sort'], 0, target, offsetF);
- target['reverse'] = offsetDecorator(target['reverse'], 0, target, offsetF);
- target['fill'] = offsetDecorator(target['fill'], 0, target, offsetF);
- target['copyWithin'] = offsetDecorator(target['copyWithin'], 0, target, offsetF);
- target['subarray'] = offsetDecorator(target['subarray'], 0, target, offsetF);
- target['slice'] = offsetDecorator(target['slice'], 1, target, offsetF);
- target['map'] = offsetDecorator(target['map'], 1, target, offsetF);
- target['filter'] = offsetDecorator(target['filter'], 1, target, offsetF);
- target['set'] = offsetDecorator(target['set'], 2, target, offsetF);
- target['reduce'] = offsetDecorator(target['reduce'], 2, target, offsetF);
- target['reduceRight'] = offsetDecorator(target['reduceRight'], 2, target, offsetF);
- target['lastIndexOf'] = offsetDecorator(target['lastIndexOf'], 2, target, offsetF);
- target['indexOf'] = offsetDecorator(target['indexOf'], 2, target, offsetF);
- target['forEach'] = offsetDecorator(target['forEach'], 2, target, offsetF);
- target['find'] = offsetDecorator(target['find'], 2, target, offsetF);
- target['join'] = offsetDecorator(target['join'], 2, target, offsetF);
- target['entries'] = offsetDecorator(target['entries'], 3, target, offsetF);
- target['keys'] = offsetDecorator(target['keys'], 3, target, offsetF);
- target['values'] = offsetDecorator(target['values'], 3, target, offsetF);
-}
-
-function redefineNewArrayConstructors(target) {
- target['from'] = constructDecorator(originalF['from']);
- target['of'] = constructDecorator(originalF['of']);
-}
-
-/// Default proxy handler for Typed Arrays
-var proxyHandler = `{
- get(target, key, receiver) {
- var random_idx = Math.floor(Math.random() * target['length']);
- // Load random index from array
- var rand_val = target[random_idx];
- /*
- let proto_keys = ['buffer', 'byteLength', 'byteOffset', 'length'];
- if (proto_keys.indexOf(key) >= 0) {
- return target[key];
- }
- */
- // offsetF argument needs to be in array range
- if (typeof key !== 'symbol' && Number(key) >= 0 && Number(key) < target.length) {
- key = offsetF(key)
- }
- let value = target[key]
- return typeof value == 'function' ? value.bind(target) : value;
- },
- set(target, key, value) {
- var random_idx = Math.floor(Math.random() * (target['length']));
- // Load random index from array
- var rand_val = target[random_idx];
- rand_val = rand_val;
- if (typeof key !== 'symbol' && Number(key) >= 0 && Number(key) < target.length) {
- key = offsetF(key)
- }
- return target[key] = value;
- }
-}`;
-
-function getByteDecorator(wrapped, offsetF, name, doMapping) {
- return function () {
- const originalIdx = arguments[0];
- const endian = arguments[1];
- if (name === 'getUint8') {
- // Random access
- let ran = wrapped.apply(this, [Math.floor(Math.random() * (this.byteLength))]);
- // Call original func
- arguments[0] = offsetF(originalIdx);
- return wrapped.apply(this, arguments);
- }
- if (!doMapping){
- this.getUint8(0);
- return wrapped.apply(this, arguments);
- }
- const byteNumber = (parseInt(name[name.length - 2] + name[name.length - 1]) || parseInt(name[name.length - 1])) / 8;
- let res = 0;
- let swapNumber = byteNumber - 1;
- for (let i = 0; i < byteNumber; i++) {
- if (endian) {
- // Shift starting with 0,1,2
- swapNumber = i * 2;
- }
- res += this.getUint8(originalIdx + i) << ((swapNumber - i) * 8);
- }
- return res;
- }
-}
-
-function setByteDecorator(wrapped, offsetF, name, doMapping) {
- function toNBitBin(n, bits) {
- if (n < 0) {
- n = 0xFFFFFFFF + n + 1;
- }
- function makeString(n) {
- let s = "";
- for (let i = 0; i < n; i++) {
- s += "0";
- }
- return s;
- }
- return (makeString(bits) + parseInt(n, 10).toString(2)).substr(-bits);
- }
-
- return function () {
- if (!doMapping){
- this.getUint8(0);
- return wrapped.apply(this, arguments);
- }
- const originalIdx = arguments[0];
- const value = arguments[1];
- const endian = arguments[2];
- if (name === 'setUint8') {
- // Random access
- this.getUint8(0);
- // Call original func
- arguments[0] = offsetF(originalIdx);
- return wrapped.apply(this, arguments);
- }
- const byteNumber = (parseInt(name[name.length - 2] + name[name.length - 1]) || parseInt(name[name.length - 1])) / 8;
- const binNumber = toNBitBin(value, byteNumber * 8);
- let numberPart;
- for (let i = 0; i < byteNumber; i++) {
- numberPart = binNumber.substr(i * 8, 8);
- numberPart = parseInt(numberPart, 2);
- if (endian) {
- this.setUint8(originalIdx + byteNumber - i - 1, numberPart);
- } else {
- this.setUint8(originalIdx + i, numberPart);
- }
- }
- return undefined;
- }
-}
-
-function getFloatDecorator(wrapped, name, doMapping) {
- return function () {
- if (!doMapping){
- this.getUint8(0);
- return wrapped.apply(this, arguments);
- }
- const originalIdx = arguments[0];
- if (originalIdx === undefined) {
- wrapped.apply(this, arguments)
- }
- const endian = arguments[1];
- const byteNumber = (parseInt(name[name.length - 2] + name[name.length - 1]) || parseInt(name[name.length - 1])) / 8;
- let binArray = [];
- // Random access
- this.getUint8(0);
- for (let i = 0; i < byteNumber; i++) {
- binArray[binArray.length] = this.getUint8(originalIdx + i);
- }
- if (endian) {
- binArray = binArray.reverse()
- }
- if (byteNumber === 4) {
- return unpackF32(binArray);
- } else {
- return unpackF64(binArray);
- }
- }
-}
-
-function setFloatDecorator(wrapped, name, doMapping) {
- return function () {
- if (!doMapping){
- this.getUint8(0);
- return wrapped.apply(this, arguments);
- }
- const originalIdx = arguments[0];
- const value = arguments[1];
- if (originalIdx === undefined || value === undefined) {
- wrapped.apply(this, arguments)
- }
- const endian = arguments[2];
- const byteNumber = (parseInt(name[name.length - 2] + name[name.length - 1]) || parseInt(name[name.length - 1])) / 8;
- let binArray;
-
- // Random access
- this.getUint8(0);
- if (byteNumber === 4) {
- binArray = packF32(value);
- } else {
- binArray = packF64(value);
- }
- for (let i = 0; i < binArray.length; i++) {
- if (endian) {
- this.setUint8(originalIdx + byteNumber - i - 1, binArray[i]);
- } else {
- this.setUint8(originalIdx + i, binArray[i]);
- }
- }
- return undefined;
- }
-}
-
-function getBigIntDecorator(wrapped, doMapping) {
- return function () {
- if (!doMapping){
- this.getUint8(0);
- return wrapped.apply(this, arguments);
- }
- const originalIdx = arguments[0];
- if (originalIdx === undefined) {
- wrapped.apply(this, arguments)
- }
- const endian = arguments[1];
- let hex = [];
- let binArray = [];
- for (let i = 0; i < 8; i++) {
- binArray[binArray.length] = this.getUint8(originalIdx + i);
- }
- if (endian) {
- binArray = binArray.reverse();
- }
- for (let i of binArray) {
- let h = i.toString(16);
- if (h.length % 2) {
- h = '0' + h;
- }
- hex.push(h);
- }
- let result = BigInt('0x' + hex.join(''));
- if (binArray[0] >= 128) {
- return result - 18446744073709551615n - 1n;
- }
- return result
- }
-}
-
-function setBigIntDecorator(wrapped, doMapping) {
- return function () {
- if (!doMapping){
- this.getUint8(0);
- return wrapped.apply(this, arguments);
- }
- const originalIdx = arguments[0];
- let value = arguments[1];
- if (originalIdx === undefined || value === undefined || typeof value !== 'bigint') {
- return wrapped.apply(this, arguments)
- }
- const endian = arguments[2];
- if (value < 0n) {
- value = 18446744073709551615n + value + 1n;
- }
- let hex = BigInt(value).toString(16);
- if (hex.length % 2) {
- hex = '0' + hex;
- }
-
- const len = hex.length / 2;
- let binArray = [];
- let j = 0;
- // Random access
- this.getUint8(0);
- for (let i = 0; i < 8; i++) {
- if (i < 8 - len) {
- binArray[binArray.length] = 0;
- } else {
- binArray[binArray.length] = parseInt(hex.slice(j, j + 2), 16);
- j += 2;
- }
- }
- if (endian) {
- binArray.reverse();
- }
- for (let i in binArray) {
- this.setUint8(originalIdx + parseInt(i), binArray[i])
- }
- return undefined;
- }
-}
-
-function redefineDataViewFunctions(target, offsetF, doMapping) {
- // Replace functions working with Ints
- var dataViewTypes = ['getInt8', 'getInt16', 'getInt32', 'getUint8', 'getUint16', 'getUint32'];
- for (type of dataViewTypes) {
- target[type] = getByteDecorator(target[type], offsetF, type, doMapping);
- type = 's' + type.substr(1);
- target[type] = setByteDecorator(target[type], offsetF, type, doMapping);
- }
-
- var dataViewTypes2 = ['getFloat32', 'getFloat64'];
- for (type of dataViewTypes2) {
- target[type] = getFloatDecorator(target[type], type, doMapping);
- type = 's' + type.substr(1);
- target[type] = setFloatDecorator(target[type], type, doMapping);
- }
- var dataViewTypes3 = ['getBigInt64', 'getBigUint64'];
- for (type of dataViewTypes3) {
- target[type] = getBigIntDecorator(target[type], doMapping);
- type = 's' + type.substr(1);
- target[type] = setBigIntDecorator(target[type], doMapping);
- }
-
-};
-
-(function () {
- var common_function_body = `
- let _data;
- if (typeof target === 'object' && target !== null) {
- if (is_proxy in target){
- // If already Proxied array is passed as arg return it
- return target;
- }
- }
- _data = new originalF(...arguments);
- // No offset
- var offsetF = function(x) {
- return x;
- };
- if (doMapping) {
- // Random numbers for offset function
- let n = _data.length;
- let a;
- while (true){
- a = Math.floor(Math.random() * 4096);
- if (gcd(a,n) === 1){
- break;
- }
- }
- let b = Math.floor(Math.random() * 4096);
- // Define function to calculate offset;
- offsetF = function(x) {
- if (x === undefined){
- return x;
- }
- x = x < 0 ? n + x : x;
- return (a*x + b) % n ;
- };
- let arr = []
- for (let i = 0; i < _data.length; i++) {
- arr[i] = _data[i];
- }
-
- for (let i = 0; i < _data.length; i++) {
- _data[offsetF(i)] = arr[i];
- }
- }
- var proxy = new newProxy(_data, ${proxyHandler});
- // Proxy has to support all methods, original object supports.
- ${offsetDecorator};
- ${redefineNewArrayFunctions};
- if (doMapping) {
- // Methods have to work with offsets;
- redefineNewArrayFunctions(proxy, offsetF);
- }
- // Preload array
- let j;
- for (let i = 0; i < _data['length']; i++) {
- j = _data[i];
- }
- return proxy;
- `;
-
- var wrappers = [
- {
- parent_object: 'window',
- parent_object_property: 'DataView',
- original_function: 'window.DataView',
- wrapped_objects: [],
- wrapping_function_args: 'buffer, byteOffset, byteLength',
- helping_code: packIEEE754 + unpackIEEE754 + packF32 + unpackF32 + packF64 + unpackF64 + `
- function gcd(x, y) {
- while(y) {
- var t = y;
- y = x % y;
- x = t;
- }
- return x;
- }
- var doMapping = args[0];
- `,
- wrapping_function_body: `
- let _data = new originalF(...arguments);
- let n = _data.byteLength;
- let a;
- while (true){
- a = Math.floor(Math.random() * 4096);
- if (gcd(a,n) === 1){
- break;
- }
- }
- let b = Math.floor(Math.random() * 4096);
- // Define function to calculate offset;
- offsetF = function(x) {
- if (x === undefined){
- return x;
- }
- x = x < 0 ? n + x : x;
- return (a*x + b) % n ;
- };
- ${getByteDecorator}
- ${setByteDecorator}
- ${getFloatDecorator}
- ${setFloatDecorator}
- ${getBigIntDecorator}
- ${setBigIntDecorator}
- ${redefineDataViewFunctions}
- for (let i = 0; i < n; i++) {
- let random = _data.getUint8(i);
- }
- if (!doMapping){
- offsetF = function(x) {
- return x;
- }
- }
- redefineDataViewFunctions(_data, offsetF, doMapping);
- return _data;
- `,
- },
- ];
-
-
- let DEFAULT_TYPED_ARRAY_WRAPPER = {
- parent_object: 'window',
- parent_object_property: '_PROPERTY_',
- original_function: 'window._PROPERTY_',
- wrapped_objects: [],
- helping_code:`
- let doMapping = args[0];
- var proxyHandler = ${proxyHandler};
- function gcd(x, y) {
- while(y) {
- var t = y;
- y = x % y;
- x = t;
- }
- return x;
- }
-
- const is_proxy = Symbol('is_proxy');
- const originalProxy = Proxy;
- var proxyHandler = {
- has (target, key) {
- return (is_proxy === key) || (key in target);
- }
- };
- let newProxy = new originalProxy(originalProxy, {
- construct(target, args) {
- return new originalProxy(new target(...args), proxyHandler);
- }
- });
- `,
- wrapping_function_args: `target`,
- wrapping_function_body: common_function_body,
- post_replacement_code: `
- ${constructDecorator}
- ${redefineNewArrayConstructors}
- redefineNewArrayConstructors(window._PROPERTY_);
- `
- };
-
- var typedTypes = ['Uint8Array', 'Int8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array'];
- for (let p of typedTypes) {
- let wrapper = {...DEFAULT_TYPED_ARRAY_WRAPPER};
- wrapper.parent_object_property = wrapper.parent_object_property.replace('_PROPERTY_', p);
- wrapper.original_function = wrapper.original_function.replace('_PROPERTY_', p);
- wrapper.post_replacement_code = wrapper.post_replacement_code.split('_PROPERTY_').join(p);
- wrapper.wrapping_function_body += `// ${p};`;
- wrappers.push(wrapper);
- }
-
- add_wrappers(wrappers);
-})();