diff options
-rw-r--r-- | src/bun.js/api/JSBundler.zig | 7 | ||||
-rw-r--r-- | src/bun.js/api/JSTranspiler.zig | 7 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 1 | ||||
-rw-r--r-- | src/bun_js.zig | 20 | ||||
-rw-r--r-- | src/bundler.zig | 1 | ||||
-rw-r--r-- | src/bundler/bundle_v2.zig | 1 | ||||
-rw-r--r-- | src/bunfig.zig | 9 | ||||
-rw-r--r-- | src/cli.zig | 9 | ||||
-rw-r--r-- | src/cli/build_command.zig | 10 | ||||
-rw-r--r-- | src/http.zig | 11 | ||||
-rw-r--r-- | src/js_parser.zig | 23 | ||||
-rw-r--r-- | src/options.zig | 1 | ||||
-rw-r--r-- | src/runtime.zig | 2 |
13 files changed, 91 insertions, 11 deletions
diff --git a/src/bun.js/api/JSBundler.zig b/src/bun.js/api/JSBundler.zig index 741d956bf..8e85f1190 100644 --- a/src/bun.js/api/JSBundler.zig +++ b/src/bun.js/api/JSBundler.zig @@ -61,6 +61,7 @@ pub const JSBundler = struct { code_splitting: bool = false, minify: Minify = .{}, server_components: ServerComponents = ServerComponents{}, + no_macros: bool = false, names: Names = .{}, external: bun.StringSet = bun.StringSet.init(bun.default_allocator), @@ -188,6 +189,12 @@ pub const JSBundler = struct { } } + if (config.getTruthy(globalThis, "macros")) |macros_flag| { + if (!macros_flag.coerce(bool, globalThis)) { + this.no_macros = true; + } + } + if (try config.getOptionalEnum(globalThis, "target", options.Target)) |target| { this.target = target; } diff --git a/src/bun.js/api/JSTranspiler.zig b/src/bun.js/api/JSTranspiler.zig index 8a59f59e7..c58029c5e 100644 --- a/src/bun.js/api/JSTranspiler.zig +++ b/src/bun.js/api/JSTranspiler.zig @@ -75,6 +75,7 @@ const TranspilerOptions = struct { minify_whitespace: bool = false, minify_identifiers: bool = false, minify_syntax: bool = false, + no_macros: bool = false, }; // Mimalloc gets unstable if we try to move this to a different thread @@ -479,6 +480,10 @@ fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std if (object.getIfPropertyExists(globalThis, "macro")) |macros| { macros: { if (macros.isUndefinedOrNull()) break :macros; + if (macros.isBoolean()) { + transpiler.no_macros = !macros.asBoolean(); + break :macros; + } const kind = macros.jsType(); const is_object = kind.isObject(); if (!(kind.isStringLike() or is_object)) { @@ -775,7 +780,7 @@ pub fn constructor( globalThis.throwError(err, "Error creating transpiler"); return null; }; - + bundler.options.no_macros = transpiler_options.no_macros; bundler.configureLinkerWithAutoJSX(false); bundler.options.env.behavior = .disable; bundler.configureDefines() catch |err| { diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 4a1fcbcb1..5c158a4fb 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -392,6 +392,7 @@ pub const VirtualMachine = struct { macros: MacroMap, macro_entry_points: std.AutoArrayHashMap(i32, *MacroEntryPoint), macro_mode: bool = false, + no_macros: bool = false, has_any_macro_remappings: bool = false, is_from_devserver: bool = false, diff --git a/src/bun_js.zig b/src/bun_js.zig index 12876cae8..fd124a8ac 100644 --- a/src/bun_js.zig +++ b/src/bun_js.zig @@ -90,8 +90,14 @@ pub const Run = struct { // b.options.minify_syntax = ctx.bundler_options.minify_syntax; - if (ctx.debug.macros) |macros| { - b.options.macro_remap = macros; + switch (ctx.debug.macros) { + .disable => { + b.options.no_macros = true; + }, + .map => |macros| { + b.options.macro_remap = macros; + }, + .unspecified => {}, } b.configureRouter(false) catch { @@ -175,8 +181,14 @@ pub const Run = struct { // b.options.minify_syntax = ctx.bundler_options.minify_syntax; - if (ctx.debug.macros) |macros| { - b.options.macro_remap = macros; + switch (ctx.debug.macros) { + .disable => { + b.options.no_macros = true; + }, + .map => |macros| { + b.options.macro_remap = macros; + }, + .unspecified => {}, } b.configureRouter(false) catch { diff --git a/src/bundler.zig b/src/bundler.zig index f3296134e..ea8222870 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -1388,6 +1388,7 @@ pub const Bundler = struct { opts.features.trim_unused_imports = bundler.options.trim_unused_imports orelse loader.isTypeScript(); opts.features.should_fold_typescript_constant_expressions = loader.isTypeScript() or target.isBun() or bundler.options.minify_syntax; opts.features.dynamic_require = target.isBun(); + opts.features.no_macros = bundler.options.no_macros; opts.transform_only = bundler.options.transform_only; // @bun annotation diff --git a/src/bundler/bundle_v2.zig b/src/bundler/bundle_v2.zig index 967bfaa36..2a97b98ed 100644 --- a/src/bundler/bundle_v2.zig +++ b/src/bundler/bundle_v2.zig @@ -1599,6 +1599,7 @@ pub const BundleV2 = struct { completion.env, ); bundler.options.jsx = config.jsx; + bundler.options.no_macros = config.no_macros; bundler.options.react_server_components = config.server_components.client.items.len > 0 or config.server_components.server.items.len > 0; bundler.options.loaders = try options.loadersFromTransformOptions(allocator, config.loaders, config.target); bundler.options.entry_naming = config.names.entry_point.data; diff --git a/src/bunfig.zig b/src/bunfig.zig index af3842451..9df2978b0 100644 --- a/src/bunfig.zig +++ b/src/bunfig.zig @@ -579,8 +579,13 @@ pub const Bunfig = struct { } if (json.get("macros")) |expr| { - // technical debt - this.ctx.debug.macros = PackageJSON.parseMacrosJSON(allocator, expr, this.log, this.source); + if (expr.data == .e_boolean) { + if (expr.data.e_boolean.value == false) { + this.ctx.debug.macros = .{ .disable = {} }; + } + } else { + this.ctx.debug.macros = .{ .map = PackageJSON.parseMacrosJSON(allocator, expr, this.log, this.source) }; + } Analytics.Features.macros = true; } diff --git a/src/cli.zig b/src/cli.zig index 0ad948ac7..dc1ae0cdc 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -157,6 +157,7 @@ pub const Arguments = struct { clap.parseParam("--minify-syntax Minify syntax and inline data (experimental)") catch unreachable, clap.parseParam("--minify-whitespace Minify whitespace (experimental)") catch unreachable, clap.parseParam("--minify-identifiers Minify identifiers") catch unreachable, + clap.parseParam("--no-macros Disable macros from being executed in the bundler, transpiler and runtime") catch unreachable, clap.parseParam("--target <STR> The intended execution environment for the bundle. \"browser\", \"bun\" or \"node\"") catch unreachable, clap.parseParam("<POS>... ") catch unreachable, }; @@ -744,6 +745,10 @@ pub const Arguments = struct { ctx.log.level = logger.Log.default_log_level; } + if (args.flag("--no-macros")) { + ctx.debug.macros = .{ .disable = {} }; + } + opts.output_dir = output_dir; if (output_file != null) ctx.debug.output_file = output_file.?; @@ -898,7 +903,7 @@ pub const Command = struct { loaded_bunfig: bool = false, // technical debt - macros: ?MacroMap = null, + macros: MacroOptions = MacroOptions.unspecified, editor: string = "", package_bundle_map: bun.StringArrayHashMapUnmanaged(options.BundlePackage) = bun.StringArrayHashMapUnmanaged(options.BundlePackage){}, @@ -906,6 +911,8 @@ pub const Command = struct { output_file: []const u8 = "", }; + pub const MacroOptions = union(enum) { unspecified: void, disable: void, map: MacroMap }; + pub const HotReload = enum { none, hot, diff --git a/src/cli/build_command.zig b/src/cli/build_command.zig index 52b45c493..14414c7de 100644 --- a/src/cli/build_command.zig +++ b/src/cli/build_command.zig @@ -207,8 +207,14 @@ pub const BuildCommand = struct { this_bundler.options.jsx.development = !this_bundler.options.production; this_bundler.resolver.opts.jsx.development = this_bundler.options.jsx.development; - if (ctx.debug.macros) |macros| { - this_bundler.options.macro_remap = macros; + switch (ctx.debug.macros) { + .disable => { + this_bundler.options.no_macros = true; + }, + .map => |macros| { + this_bundler.options.macro_remap = macros; + }, + .unspecified => {}, } // var env_loader = this_bundler.env; diff --git a/src/http.zig b/src/http.zig index c54f4ea9c..f26a0e985 100644 --- a/src/http.zig +++ b/src/http.zig @@ -1484,6 +1484,7 @@ pub const RequestContext = struct { std.debug.assert(JavaScript.VirtualMachine.isLoaded()); javascript_vm = vm; vm.bundler.options.origin = handler.origin; + vm.bundler.options.no_macros = handler.client_bundler.options.no_macros; const boot = vm.bundler.options.framework.?.server.path; std.debug.assert(boot.len > 0); errdefer vm.deinit(); @@ -3972,7 +3973,15 @@ pub const Server = struct { http_editor_context.name = debug.editor; - server.bundler.options.macro_remap = debug.macros orelse .{}; + switch (debug.macros) { + .disable => { + server.bundler.options.no_macros = true; + }, + .map => |macros| { + server.bundler.options.macro_remap = macros; + }, + .unspecified => {}, + } if (debug.fallback_only or server.bundler.env.map.get("BUN_DISABLE_BUN_JS") != null) { RequestContext.fallback_only = true; diff --git a/src/js_parser.zig b/src/js_parser.zig index 0fc4f794a..0c4b5dcb3 100644 --- a/src/js_parser.zig +++ b/src/js_parser.zig @@ -15361,6 +15361,18 @@ fn NewParser_( if (p.is_control_flow_dead) { return p.newExpr(E.Undefined{}, e_.tag.?.loc); } + + // this ordering incase someone wants ot use a macro in a node_module conditionally + if (p.options.features.no_macros) { + p.log.addError(p.source, tag.loc, "Macros are disabled") catch unreachable; + return p.newExpr(E.Undefined{}, e_.tag.?.loc); + } + + if (p.source.path.isNodeModule()) { + p.log.addError(p.source, expr.loc, "For security reasons, macros cannot be run from node_modules.") catch unreachable; + return p.newExpr(E.Undefined{}, expr.loc); + } + p.macro_call_count += 1; const record = &p.import_records.items[import_record_id]; // We must visit it to convert inline_identifiers and record usage @@ -16510,6 +16522,17 @@ fn NewParser_( if (p.is_control_flow_dead) { return p.newExpr(E.Undefined{}, e_.target.loc); } + + if (p.options.features.no_macros) { + p.log.addError(p.source, expr.loc, "Macros are disabled") catch unreachable; + return p.newExpr(E.Undefined{}, expr.loc); + } + + if (p.source.path.isNodeModule()) { + p.log.addError(p.source, expr.loc, "For security reasons, macros cannot be run from node_modules.") catch unreachable; + return p.newExpr(E.Undefined{}, expr.loc); + } + const name = p.symbols.items[ref.innerIndex()].original_name; const record = &p.import_records.items[import_record_id]; const copied = Expr{ .loc = expr.loc, .data = .{ .e_call = e_ } }; diff --git a/src/options.zig b/src/options.zig index 4133e95f7..d2752471d 100644 --- a/src/options.zig +++ b/src/options.zig @@ -1436,6 +1436,7 @@ pub const BundleOptions = struct { rewrite_jest_for_tests: bool = false, macro_remap: MacroRemap = MacroRemap{}, + no_macros: bool = false, conditions: ESMConditions = undefined, tree_shaking: bool = false, diff --git a/src/runtime.zig b/src/runtime.zig index f09e16378..7312aa4bd 100644 --- a/src/runtime.zig +++ b/src/runtime.zig @@ -283,6 +283,8 @@ pub const Runtime = struct { inject_jest_globals: bool = false, + no_macros: bool = false, + commonjs_named_exports: bool = true, minify_syntax: bool = false, |