Skip to content

Commit adb5284

Browse files
authored
fix: handle __proto__ as a computed property in exports and add tests for special names (#4163)
1 parent 0aa9f7b commit adb5284

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

internal/bundler_tests/bundler_default_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,44 @@ func TestExportWildcardFSNodeCommonJS(t *testing.T) {
16731673
})
16741674
}
16751675

1676+
func TestExportSpecialName(t *testing.T) {
1677+
default_suite.expectBundled(t, bundled{
1678+
files: map[string]string{
1679+
"/entry.mjs": `
1680+
export const __proto__ = 123;
1681+
`,
1682+
},
1683+
entryPaths: []string{"/entry.mjs"},
1684+
options: config.Options{
1685+
Mode: config.ModeConvertFormat,
1686+
OutputFormat: config.FormatCommonJS,
1687+
AbsOutputFile: "/out.js",
1688+
Platform: config.PlatformNode,
1689+
},
1690+
})
1691+
}
1692+
1693+
func TestExportSpecialNameBundle(t *testing.T) {
1694+
default_suite.expectBundled(t, bundled{
1695+
files: map[string]string{
1696+
"/entry.js": `
1697+
const lib = require('./lib.mjs');
1698+
console.log(lib.__proto__);
1699+
`,
1700+
"/lib.mjs": `
1701+
export const __proto__ = 123;
1702+
`,
1703+
},
1704+
entryPaths: []string{"/entry.js"},
1705+
options: config.Options{
1706+
Mode: config.ModeBundle,
1707+
OutputFormat: config.FormatCommonJS,
1708+
AbsOutputFile: "/out.js",
1709+
Platform: config.PlatformNode,
1710+
},
1711+
})
1712+
}
1713+
16761714
// https://github.com/evanw/esbuild/issues/3544
16771715
func TestNodeAnnotationFalsePositiveIssue3544(t *testing.T) {
16781716
default_suite.expectBundled(t, bundled{

internal/bundler_tests/snapshots/snapshots_default.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,39 @@ export default class {
15631563
export default class o {
15641564
}
15651565

1566+
================================================================================
1567+
TestExportSpecialName
1568+
---------- /out.js ----------
1569+
var entry_exports = {};
1570+
__export(entry_exports, {
1571+
["__proto__"]: () => __proto__
1572+
});
1573+
module.exports = __toCommonJS(entry_exports);
1574+
const __proto__ = 123;
1575+
// Annotate the CommonJS export names for ESM import in node:
1576+
0 && (module.exports = {
1577+
__proto__
1578+
});
1579+
1580+
================================================================================
1581+
TestExportSpecialNameBundle
1582+
---------- /out.js ----------
1583+
// lib.mjs
1584+
var lib_exports = {};
1585+
__export(lib_exports, {
1586+
["__proto__"]: () => __proto__
1587+
});
1588+
var __proto__;
1589+
var init_lib = __esm({
1590+
"lib.mjs"() {
1591+
__proto__ = 123;
1592+
}
1593+
});
1594+
1595+
// entry.js
1596+
var lib = (init_lib(), __toCommonJS(lib_exports));
1597+
console.log(lib.__proto__);
1598+
15661599
================================================================================
15671600
TestExportWildcardFSNodeCommonJS
15681601
---------- /out.js ----------

internal/linker/linker.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,10 +2293,20 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) {
22932293
} else {
22942294
getter = js_ast.Expr{Data: &js_ast.EArrow{PreferExpr: true, Body: body}}
22952295
}
2296-
properties = append(properties, js_ast.Property{
2297-
Key: js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(alias)}},
2298-
ValueOrNil: getter,
2299-
})
2296+
2297+
// Special case for __proto__ property - use computed property name to avoid it being treated as the object's prototype
2298+
if alias == "__proto__" {
2299+
properties = append(properties, js_ast.Property{
2300+
Flags: js_ast.PropertyIsComputed,
2301+
Key: js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(alias)}},
2302+
ValueOrNil: getter,
2303+
})
2304+
} else {
2305+
properties = append(properties, js_ast.Property{
2306+
Key: js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(alias)}},
2307+
ValueOrNil: getter,
2308+
})
2309+
}
23002310
nsExportSymbolUses[export.Ref] = js_ast.SymbolUse{CountEstimate: 1}
23012311

23022312
// Make sure the part that declares the export is included

0 commit comments

Comments
 (0)