|
@@ -2,29 +2,39 @@ const escapeStringRegexp = require('escape-string-regexp');
|
|
|
const webpack = require('webpack');
|
|
|
|
|
|
const G = webpack.RuntimeGlobals;
|
|
|
-const OPTIONAL = false;
|
|
|
const OBJ_RULE = [
|
|
|
/([[(,=:]\s*{)(?!__proto__:)\s*(.)/g,
|
|
|
- (_, str, next) => `${str}__proto__: null${next === '}' ? '' : ','}${next}`
|
|
|
+ (_, str, next) => `${str}__proto__: null${next === '}' ? '' : ','}${next}`,
|
|
|
];
|
|
|
const BOOTSTRAP_RULES = [
|
|
|
OBJ_RULE,
|
|
|
- ["typeof Symbol !== 'undefined' && Symbol.toStringTag",
|
|
|
- 'true'],
|
|
|
- ['Symbol.toStringTag',
|
|
|
- 'toStringTagSym'],
|
|
|
- ['Object.defineProperty(',
|
|
|
- 'defineProperty('],
|
|
|
- ['Object.prototype.hasOwnProperty.call(',
|
|
|
- 'safeCall(hasOwnProperty, '],
|
|
|
- [`${G.hasOwnProperty}(definition, key) && !${G.hasOwnProperty}(exports, key)`,
|
|
|
- '!(key in exports)'], // these objects have null proto
|
|
|
+ [
|
|
|
+ "typeof Symbol !== 'undefined' && Symbol.toStringTag",
|
|
|
+ 'true',
|
|
|
+ G.makeNamespaceObject,
|
|
|
+ ], [
|
|
|
+ 'Symbol.toStringTag',
|
|
|
+ 'toStringTagSym',
|
|
|
+ G.makeNamespaceObject,
|
|
|
+ ], [
|
|
|
+ 'Object.defineProperty(',
|
|
|
+ 'defineProperty(',
|
|
|
+ G.definePropertyGetters,
|
|
|
+ ], [
|
|
|
+ `${G.hasOwnProperty}(definition, key) && !${G.hasOwnProperty}(exports, key)`,
|
|
|
+ '!(key in exports)',
|
|
|
+ G.definePropertyGetters,
|
|
|
+ ], [
|
|
|
+ 'Object.prototype.hasOwnProperty.call(',
|
|
|
+ 'safeCall(hasOwnProperty, ',
|
|
|
+ G.hasOwnProperty,
|
|
|
+ ],
|
|
|
];
|
|
|
const MAIN_RULES = [
|
|
|
[
|
|
|
/(__webpack_modules__\[moduleId])\.call\(/g,
|
|
|
'safeCall($1, ',
|
|
|
- OPTIONAL,
|
|
|
+ false,
|
|
|
], [
|
|
|
new RegExp(`var (__webpack_module_cache__|${G.require}) = {};.*?var ${G.exports} =`, 's'),
|
|
|
patchBootstrap,
|
|
@@ -62,19 +72,21 @@ function patchBootstrap(src) {
|
|
|
? `for (let i = 0, props=${JSON.stringify(uniq)}; i < props.length; i++)
|
|
|
defineProperty(${G.require}, props[i], {__proto__: null, value: 0, writable: 1});\n`
|
|
|
: '';
|
|
|
- const rules = uniq ? BOOTSTRAP_RULES : [OBJ_RULE];
|
|
|
- return guard + replace(rules, src, this);
|
|
|
+ return guard + replace(BOOTSTRAP_RULES, src, this);
|
|
|
}
|
|
|
|
|
|
function replace(rules, src, info) {
|
|
|
src = src.source?.() || src;
|
|
|
let res = src;
|
|
|
for (const rule of rules) {
|
|
|
- const [from, to, mandatory = true] = rule;
|
|
|
+ const [from, to, test = true] = rule;
|
|
|
const fromRe = typeof from === 'string'
|
|
|
? new RegExp(escapeStringRegexp(from), 'g')
|
|
|
: from;
|
|
|
const dst = res.replace(fromRe, to.bind?.(info) || to);
|
|
|
+ const mandatory = test === true
|
|
|
+ || test.test?.(src)
|
|
|
+ || typeof test === 'string' && src.includes(test);
|
|
|
if (dst === res && mandatory) {
|
|
|
const err = `[${WebpackProtectBootstrapPlugin.name}] `
|
|
|
+ `"${from}" not found in ${info.chunk.name || 'bootstrap'}`;
|