Updating shims for constrained environments (#944, #993).

This commit is contained in:
Richard Moore 2020-08-27 14:22:58 -04:00
parent 5fcd03f27e
commit 8abdbbbf63
No known key found for this signature in database
GPG Key ID: 665176BE8E9DC651
4 changed files with 161 additions and 2578 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -1,80 +1,123 @@
'use strict'; 'use strict';
var shims = []; (function() {
// Shim String.prototype.normalize var shims = [];
try {
var missing = [];
// Some platforms are missing certain normalization forms // Shim String.prototype.normalize
var forms = ["NFD", "NFC", "NFKD", "NFKC"]; try {
for (var i = 0; i < forms.length; i++) { var missing = [];
try {
if ("test".normalize(forms[i]) !== "test") { // Some platforms are missing certain normalization forms
throw new Error("failed to normalize"); var forms = ["NFD", "NFC", "NFKD", "NFKC"];
for (var i = 0; i < forms.length; i++) {
try {
if ("test".normalize(forms[i]) !== "test") {
throw new Error("failed to normalize");
}
} catch(error) {
missing.push(forms[i]);
} }
} catch(error) { }
missing.push(forms[i]);
if (missing.length) {
shims.push("String.prototype.normalize (missing: " + missing.join(", ") + ")");
throw new Error('bad normalize');
}
// Some platforms have a native normalize, but it is broken; so we force our shim
if (String.fromCharCode(0xe9).normalize('NFD') !== String.fromCharCode(0x65, 0x0301)) {
shims.push("String.prototype.normalize (broken)");
throw new Error('bad normalize');
}
} catch (error) {
var unorm = require('./unorm.js');
String.prototype.normalize = function(form) {
var func = unorm[(form || 'NFC').toLowerCase()];
if (!func) { throw new RangeError('invalid form - ' + form); }
return func(this);
} }
} }
if (missing.length) { // Shim atob and btoa
shims.push("String.prototype.normalize (missing: " + missing.join(", ") + ")"); var base64 = require('./base64.js');
throw new Error('bad normalize'); if (!global.atob) {
shims.push("atob");
global.atob = base64.atob;
}
if (!global.btoa) {
shims.push("btoa");
global.btoa = base64.btoa;
} }
// Some platforms have a native normalize, but it is broken; so we force our shim // Shim ArrayBuffer.isView
if (String.fromCharCode(0xe9).normalize('NFD') !== String.fromCharCode(0x65, 0x0301)) { if (!ArrayBuffer.isView) {
shims.push("String.prototype.normalize (broken)"); shims.push("ArrayBuffer.isView");
throw new Error('bad normalize'); ArrayBuffer.isView = function(obj) {
// @TODO: This should probably check various instanceof aswell
return !!(obj.buffer);
}
} }
} catch (error) {
var unorm = require('./unorm.js'); // Shim nextTick
String.prototype.normalize = function(form) { if (!global.nextTick) {
var func = unorm[(form || 'NFC').toLowerCase()]; shims.push("nextTick");
if (!func) { throw new RangeError('invalid form - ' + form); } global.nextTick = function (callback) { setTimeout(callback, 0); }
return func(this);
} }
}
// Shim atob and btoa // Shim crypto.getRandomValues
var base64 = require('./base64.js'); // @TOOD: Investigate: https://github.com/brix/crypto-js/issues/7
if (!global.atob) { if (!global.crypto) { global.crypto = { }; }
shims.push("atob"); if (!global.crypto.getRandomValues) {
global.atob = base64.atob; shims.push("crypto.getRandomValues");
} console.log("WARNING: This environment is missing a secure random source; generated private keys may be at risk, think VERY carefully about not adding a better secure source.");
if (!global.btoa) { global.crypto.getRandomValues = function(buffer) {
shims.push("btoa"); var start = Math.floor((new Date()).getTime()) % buffer.length;
global.btoa = base64.btoa; for (var i = 0; i < buffer.length; i++) {
} buffer[(start + i) % buffer.length] = Math.floor(Math.random() * 256);
}
// Shim Promise }
// @TODO: Check first?
if (window.Promise == null) {
var promise = require('./es6-promise.auto.js');
}
// Shim ArrayBuffer.isView
if (!ArrayBuffer.isView) {
shims.push("ArrayBuffer.isView");
ArrayBuffer.isView = function(obj) {
// @TODO: This should probably check various instanceof aswell
return !!(obj.buffer);
} }
}
// Shim nextTick // Shim FileReader.readAsArrayBuffer
if (!global.nextTick) { // https://github.com/facebook/react-native/issues/21209
shims.push("nextTick"); try {
global.nextTick = function (callback) { setTimeout(callback, 0); } var fr = new FileReader();
} try {
fr.readAsArrayBuffer(new Blob([ "hello" ], { type: "text/plain" }));
return;
} catch (error) { }
if (shims.length) { shims.push("FileReader.prototype.readAsArrayBuffer");
console.log("Shims Injected:"); FileReader.prototype.readAsArrayBuffer = function (blob) {
for (var i = 0; i < shims.length; i++) { if (this.readyState === this.LOADING) throw new Error("InvalidStateError");
console.log(' - ' + shims[i]); this._setReadyState(this.LOADING);
this._result = null;
this._error = null;
var fr = new FileReader();
fr.onloadend = () => {
var content = atob(fr.result.split(",").pop().trim());
var buffer = new ArrayBuffer(content.length);
var view = new Uint8Array(buffer);
view.set(Array.from(content).map(c => c.charCodeAt(0)));
this._result = buffer;
this._setReadyState(this.DONE);
};
fr.readAsDataURL(blob);
}
} catch (error) {
console.log("Missing FileReader; unsupported platform");
} }
}
// @TOOD: Add crypto.rand? if (shims.length) {
// - https://github.com/brix/crypto-js/issues/7 console.log("Shims Injected:");
for (var i = 0; i < shims.length; i++) {
console.log(' - ' + shims[i]);
}
}
})();