Future proof against array modules
This commit is contained in:
parent
50415a949d
commit
4d8c56689c
|
@ -42,20 +42,29 @@ const define: Define = (target, p, attributes) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// wreq.m is the Webpack object containing module factories.
|
// wreq.O is the Webpack onChunksLoaded function.
|
||||||
// We wrap it with our proxy, which is responsible for patching the module factories when they are set, or definining getters for the patched versions.
|
// It is pretty likely that all important Discord Webpack instances will have this property set,
|
||||||
// If this is the main Webpack, we also set up the internal references to WebpackRequire.
|
// because Discord bundled code is chunked.
|
||||||
|
// As of the time of writing, only the main and sentry Webpack instances have this property, and they are the only ones we care about.
|
||||||
|
|
||||||
|
// We use this setter to intercept when wreq.O is defined, and apply the patching in the modules factories (wreq.m).
|
||||||
// wreq.m is pre-populated with module factories, and is also populated via webpackGlobal.push
|
// wreq.m is pre-populated with module factories, and is also populated via webpackGlobal.push
|
||||||
// The sentry module also has their own Webpack with a pre-populated wreq.m, so this also patches the sentry module factories.
|
// The sentry module also has their own Webpack with a pre-populated wreq.m, so this also patches the sentry module factories.
|
||||||
define(Function.prototype, "m", {
|
// We wrap wreq.m with our proxy, which is responsible for patching the module factories when they are set, or definining getters for the patched versions.
|
||||||
|
|
||||||
|
// If this is the main Webpack, we also set up the internal references to WebpackRequire.
|
||||||
|
define(Function.prototype, "O", {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
|
|
||||||
set(this: WebpackRequire, moduleFactories: PatchedModuleFactories) {
|
set(this: WebpackRequire, onChunksLoaded: WebpackRequire["O"]) {
|
||||||
// When using React DevTools or other extensions, we may also catch their Webpack here.
|
define(this, "O", { value: onChunksLoaded });
|
||||||
// This ensures we actually got the right ones.
|
|
||||||
const { stack } = new Error();
|
const { stack } = new Error();
|
||||||
if (!(stack?.includes("discord.com") || stack?.includes("discordapp.com")) || Array.isArray(moduleFactories)) {
|
if (!stack?.includes("discord.com") && !stack?.includes("discordapp.com")) {
|
||||||
define(this, "m", { value: moduleFactories });
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.m == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,24 +90,24 @@ define(Function.prototype, "m", {
|
||||||
// If this is the main Webpack, wreq.m will always be set before the timeout runs.
|
// If this is the main Webpack, wreq.m will always be set before the timeout runs.
|
||||||
const setterTimeout = setTimeout(() => Reflect.deleteProperty(this, "p"), 0);
|
const setterTimeout = setTimeout(() => Reflect.deleteProperty(this, "p"), 0);
|
||||||
|
|
||||||
define(moduleFactories, Symbol.toStringTag, {
|
// Patch the pre-populated factories
|
||||||
|
for (const id in this.m) {
|
||||||
|
defineModulesFactoryGetter(id, Settings.eagerPatches ? patchFactory(id, this.m[id]) : this.m[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
define(this.m, Symbol.toStringTag, {
|
||||||
value: "ModuleFactories",
|
value: "ModuleFactories",
|
||||||
enumerable: false
|
enumerable: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// The proxy responsible for patching the module factories when they are set, or definining getters for the patched versions
|
// The proxy responsible for patching the module factories when they are set, or definining getters for the patched versions
|
||||||
const proxiedModuleFactories = new Proxy(moduleFactories, moduleFactoriesHandler);
|
const proxiedModuleFactories = new Proxy(this.m, moduleFactoriesHandler);
|
||||||
/*
|
/*
|
||||||
If Discord ever decides to set module factories using the variable of the modules object directly, instead of wreq.m, switch the proxy to the prototype
|
If Discord ever decides to set module factories using the variable of the modules object directly, instead of wreq.m, switch the proxy to the prototype
|
||||||
Reflect.setPrototypeOf(moduleFactories, new Proxy(moduleFactories, moduleFactoriesHandler));
|
Reflect.setPrototypeOf(moduleFactories, new Proxy(moduleFactories, moduleFactoriesHandler));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define(this, "m", { value: proxiedModuleFactories });
|
define(this, "m", { value: proxiedModuleFactories });
|
||||||
|
|
||||||
// Patch the pre-populated factories
|
|
||||||
for (const id in moduleFactories) {
|
|
||||||
defineModulesFactoryGetter(id, Settings.eagerPatches ? patchFactory(id, moduleFactories[id]) : moduleFactories[id]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue