mirror of https://github.com/webpack/webpack.git
fix: ability to use built-in properties in dotenv and define plugin (#20168)
This commit is contained in:
parent
9525f0a222
commit
5ce84ec8c8
|
|
@ -182,7 +182,7 @@ const stringifyObj = (
|
|||
code = `{${keys
|
||||
.map((key) => {
|
||||
const code = obj[key];
|
||||
return `${JSON.stringify(key)}:${toCode(
|
||||
return `${key === "__proto__" ? '["__proto__"]' : JSON.stringify(key)}:${toCode(
|
||||
code,
|
||||
parser,
|
||||
valueCacheVersions,
|
||||
|
|
@ -536,7 +536,7 @@ class DefinePlugin {
|
|||
return;
|
||||
}
|
||||
/** @type {Record<string, CodeValue>} */
|
||||
const obj = {};
|
||||
const obj = Object.create(null);
|
||||
const finalSet = finalByNestedKey.get(nested);
|
||||
for (const { id } of destructed) {
|
||||
const fullKey = `${nested}.${id}`;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ const validate = createSchemaValidation(
|
|||
* @returns {Env} parsed environment variables object
|
||||
*/
|
||||
function parse(src) {
|
||||
const obj = /** @type {Env} */ ({});
|
||||
const obj = /** @type {Env} */ (Object.create(null));
|
||||
|
||||
// Convert buffer to string
|
||||
let lines = src.toString();
|
||||
|
|
@ -174,7 +174,7 @@ function expandValue(value, processEnv, runningParsed) {
|
|||
*/
|
||||
function expand(options) {
|
||||
// for use with progressive expansion
|
||||
const runningParsed = /** @type {Env} */ ({});
|
||||
const runningParsed = /** @type {Env} */ (Object.create(null));
|
||||
const processEnv = options.processEnv;
|
||||
|
||||
// dotenv.config() ran before this so the assumption is process.env has already been set
|
||||
|
|
@ -183,7 +183,8 @@ function expand(options) {
|
|||
|
||||
// short-circuit scenario: process.env was already set prior to the file value
|
||||
value =
|
||||
processEnv[key] && processEnv[key] !== value
|
||||
Object.prototype.hasOwnProperty.call(processEnv, key) &&
|
||||
processEnv[key] !== value
|
||||
? /** @type {string} */ (processEnv[key])
|
||||
: expandValue(value, processEnv, runningParsed);
|
||||
|
||||
|
|
@ -332,7 +333,7 @@ class DotenvPlugin {
|
|||
|
||||
// Parse all files and merge (later files override earlier ones)
|
||||
// Similar to Vite's implementation
|
||||
const parsed = /** @type {Env} */ ({});
|
||||
const parsed = /** @type {Env} */ (Object.create(null));
|
||||
|
||||
for (const content of contents) {
|
||||
if (!content) continue;
|
||||
|
|
@ -422,7 +423,7 @@ class DotenvPlugin {
|
|||
// Make a copy of process.env so that dotenv-expand doesn't modify global process.env
|
||||
const processEnv = { ...process.env };
|
||||
expand({ parsed, processEnv });
|
||||
const env = /** @type {Env} */ ({});
|
||||
const env = /** @type {Env} */ (Object.create(null));
|
||||
|
||||
// Get all keys from parser and process.env
|
||||
const keys = [...Object.keys(parsed), ...Object.keys(process.env)];
|
||||
|
|
@ -430,7 +431,11 @@ class DotenvPlugin {
|
|||
// Prioritize actual env variables from `process.env`, fallback to parsed
|
||||
for (const key of keys) {
|
||||
if (prefixes.some((prefix) => key.startsWith(prefix))) {
|
||||
env[key] = process.env[key] ? process.env[key] : parsed[key];
|
||||
env[key] =
|
||||
Object.prototype.hasOwnProperty.call(process.env, key) &&
|
||||
process.env[key]
|
||||
? process.env[key]
|
||||
: parsed[key];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
"use strict";
|
||||
|
||||
it("should expose only APP_ and CONFIG_ prefixed vars", () => {
|
||||
it("should expose only APP_ and CONFIG_ prefixed vars and built-in properties", () => {
|
||||
expect(process.env.APP_NAME).toBe("MyApp");
|
||||
expect(process.env.CONFIG_TIMEOUT).toBe("5000");
|
||||
|
||||
|
||||
// WEBPACK_ prefixed should not be exposed
|
||||
expect(typeof process.env.WEBPACK_API_URL).toBe("undefined");
|
||||
|
||||
|
||||
// Non-prefixed should not be exposed
|
||||
expect(typeof process.env.SECRET_KEY).toBe("undefined");
|
||||
|
||||
expect(process.env.constructor).toBe("test");
|
||||
expect(process.env.__proto__).toBe("test");
|
||||
|
||||
const { __proto__ } = process.env;
|
||||
expect(__proto__).toBe("test");
|
||||
|
||||
const { constructor } = process.env;
|
||||
expect(constructor).toBe("test");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,3 +2,5 @@ APP_NAME=MyApp
|
|||
CONFIG_TIMEOUT=5000
|
||||
WEBPACK_API_URL=should-not-be-exposed
|
||||
SECRET_KEY=also-hidden
|
||||
__proto__=test
|
||||
constructor=test
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ module.exports = [
|
|||
entry: "./custom-prefixes.js",
|
||||
dotenv: {
|
||||
dir: path.resolve(__dirname, "./prefixes-env"),
|
||||
prefix: ["APP_", "CONFIG_"]
|
||||
prefix: ["APP_", "CONFIG_", "__proto__", "constructor"]
|
||||
}
|
||||
},
|
||||
// Test 5: Mode-specific - .env.[mode] overrides
|
||||
|
|
|
|||
Loading…
Reference in New Issue