From 8b14ec93706bf0347eb4a082ddcfa49d819a8121 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sun, 2 Nov 2025 12:20:56 +0000 Subject: [PATCH] fix(minifier): handle `{ __proto__: null } instanceof Object` correctly (#15217) `{ __proto__: null } instanceof Object` should be `false` or kept as-is, or it was compressed to `true`. --- .../src/constant_evaluation/mod.rs | 22 ++++++++++++++++--- .../src/peephole/fold_constants.rs | 5 +++++ .../snapshots/minifier_node_compat.snap | 4 +--- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/crates/oxc_ecmascript/src/constant_evaluation/mod.rs b/crates/oxc_ecmascript/src/constant_evaluation/mod.rs index a21dbc43c91bd..2b86b087126d6 100644 --- a/crates/oxc_ecmascript/src/constant_evaluation/mod.rs +++ b/crates/oxc_ecmascript/src/constant_evaluation/mod.rs @@ -350,9 +350,25 @@ fn binary_operation_evaluate_value_to<'a>( if left_ty.is_undetermined() { return None; } - return Some(ConstantValue::Boolean( - name == "Object" && left.value_type(ctx).is_object(), - )); + if name == "Object" { + if !left_ty.is_object() { + return Some(ConstantValue::Boolean(false)); + } + if matches!( + left, + Expression::ArrayExpression(_) + | Expression::RegExpLiteral(_) + | Expression::FunctionExpression(_) + | Expression::ArrowFunctionExpression(_) + | Expression::ClassExpression(_) + ) | matches!(left, Expression::ObjectExpression(obj_expr) if obj_expr.properties.is_empty()) + { + return Some(ConstantValue::Boolean(true)); + } + // NOTE: `{ __proto__: null } instanceof Object` is false + return None; + } + return Some(ConstantValue::Boolean(false)); } } None diff --git a/crates/oxc_minifier/src/peephole/fold_constants.rs b/crates/oxc_minifier/src/peephole/fold_constants.rs index 59a055d165397..c52f88844ed33 100644 --- a/crates/oxc_minifier/src/peephole/fold_constants.rs +++ b/crates/oxc_minifier/src/peephole/fold_constants.rs @@ -1819,6 +1819,11 @@ mod test { fn test_fold_instance_of_additional() { fold("(typeof {}) instanceof Object", "!1"); fold("(+{}) instanceof Number", "!1"); + fold_same("({ __proto__: null }) instanceof Object"); + fold("/foo/ instanceof Object", "!0"); + fold("(() => {}) instanceof Object", "!0"); + fold("(function(){}) instanceof Object", "!0"); + fold("(class{}) instanceof Object", "!0"); } #[test] diff --git a/tasks/coverage/snapshots/minifier_node_compat.snap b/tasks/coverage/snapshots/minifier_node_compat.snap index 7ad1845dc2d01..ba07f6386ccf6 100644 --- a/tasks/coverage/snapshots/minifier_node_compat.snap +++ b/tasks/coverage/snapshots/minifier_node_compat.snap @@ -2,9 +2,7 @@ commit: 17ac85ca minifier_node_compat Summary: AST Parsed : 938/938 (100.00%) -Positive Passed: 929/938 (99.04%) -execution_result: tasks/coverage/ES2015/annex b›__proto__ in object literals›basic support - +Positive Passed: 930/938 (99.15%) execution_result: tasks/coverage/ES2015/built-ins›Proxy›"getOwnPropertyDescriptor" handler invariants execution_result: tasks/coverage/ES2015/misc›Proxy, internal 'get' calls›HasBinding