diff --git a/src/node_dotenv.cc b/src/node_dotenv.cc index 0c6fa30a41d..6e07460dac0 100644 --- a/src/node_dotenv.cc +++ b/src/node_dotenv.cc @@ -151,6 +151,12 @@ void Dotenv::ParseContent(const std::string_view input) { lines.erase(std::remove(lines.begin(), lines.end(), '\r'), lines.end()); std::string_view content = lines; + + // Strip leading UTF-8 Byte Order Mark (BOM) if present + if (content.rfind("\xEF\xBB\xBF", 0) == 0) { + content = content.substr(3); + } + content = trim_spaces(content); std::string_view key; diff --git a/test/parallel/test-util-parse-env.js b/test/parallel/test-util-parse-env.js index e932a31f683..e110cf5aed8 100644 --- a/test/parallel/test-util-parse-env.js +++ b/test/parallel/test-util-parse-env.js @@ -65,6 +65,8 @@ const fs = require('node:fs'); assert.deepStrictEqual(util.parseEnv(''), { __proto__: null }); assert.deepStrictEqual(util.parseEnv('FOO=bar\nFOO=baz\n'), { __proto__: null, FOO: 'baz' }); +assert.deepStrictEqual(util.parseEnv('\uFEFFA=1\r\nB=2\r\n'), + { __proto__: null, A: '1', B: '2' }); // Test for invalid input. assert.throws(() => {