According to the ECMAScript specification, running a JavaScript program class x { static { const x = { x } = 0 ; } } is expected to result in ReferenceError but after obfuscating the JavaScript program, it results in TypeError.
Expected Behavior
Running the following JavaScript code using Node.js results in ReferenceError.
class x { static { const x = { x } = 0 ; } }

Current Behavior
However, as shown below, running the obfuscated code using Node.js results in TypeError.
Obfuscated code
class x{static{const _0x2340e4={x}=0x0;}}

In summary, obfuscated code results in TypeError, because obfuscator have renamed constant variable in class static block. (e.g. x to _0x2340e4)
- Original code and obfuscated code both evaluates
{ x } = 0 and {x}=0x0 to initialize x in x = { x } = 0 and _0x2340e4 in _0x2340e4={x}=0x0.
- When resolving
x in {x}, the original code resolves to x in const x and the obfuscated code resolves to x in class x.
- In case of the original code,
ReferenceError exception arises because it tries to set mutable binding for uninitialized x, which refers to const x.
- In case of the obfuscated code,
- the
TypeError exception arises because it tries to change the value of an immutable binding x, which refers to class x.
Steps to Reproduce
- Obfuscate the following program using https://obfuscator.io.
- Run the following program using Node.js v18.13.0.
Your Environment
Stack trace
Minimal working example that will help to reproduce issue
Below is a detailed explanation using ECMAScript specification.
Evaluation of class x { static { const x = { x } = 0 ; } } is done by following algorithms.
In step 3, the algorithm creates an immutable binding of x.
In step 27, the algorithm initializes the binding of x with F.


In step 31-b, the algorithm calls Call(initializer,receiver).
where initializer represents the const x = { x } = 0 ; and receiver represents the evaluation result of ClassDefinition of x.

This step evaluates the ClassStaticBlockBody, which represents const x = { x } = 0 ; and creates binding of variables in ClassStaticBlockBody in class environment.
In step 1, the algorithm calls FunctionDeclarationInstantiation(functionObject, <<>>), where functionObject represents the const x = { x } = 0 ;.
This step creates binding of x, which represents the constant variable name const x.
In step 2, the algorithm calls the evaluation of ClassStaticBlockStatementList, where ClassStaticBlockStatementList represents const x = { x } = 0 ;

LexicalBinding represents x = {x} = 0, and it can be divided into BindingIdentifier x and Initializer = {x} = 0.
This algorithm intends to resolve bindingId and evaluate Initializer to initialize binding at step 5.
Note that binding for the constant variable x is not initialized until it reaches step 5.
In step 4, the algorithm calls the evaluation of Initializer.

AssignmentExpression represents {x} = 0, and it can be divided into LeftHandSideExpression {x} and AssignmentExpression 0.
In step 5, the algorithm calls DestructuringAssignmentEvaluation(value) of assignmentPattern, where value represents 0 and assignmentPattern represents {x}.

Then, DestructuringAssignmentEvaluation calls PropertyDestructuringAssignmentEvaluation(value), where value represents 0.
In step 2, the algorithm resolves x as the constant variable x.
In step 5, the algorithm calls PutValue(V, W), where V represents a reference of the constant variable x and W rerpresents undefined.

Then, PutValue calls SetMutableBinding(N, V, S) of base, where base represents the environment that binding of constant variable x is stored, N represents x, V represents undefined, and S represents True.
In step 3, the algorithm throws a ReferenceError exception, because the binding for N, which is x in envRec has not yet been initialized.
In detail, the x in envRec refers the x in const x. Therefore, it has not been initialized.

In comparison, the evaluation of the obfuscated JavaScript program, class x{static{const _0x2340e4={x}=0x0;}}, is similar but different in following steps.
In step 1, the algorithm creates an immutable binding of _0x2340e4 in class environment.
In step 2, the algorithm calls the evaluation of ClassStaticBlockStatementList, where ClassStaticBlockStatementList represents const _0x2340e4 = { x } = 0x0 ;.

In step 2, the algorithm resolves x as the class x.
In step 5, the algorithm calls PutValue(V, W), where V represents a reference of the class x.

Then, PutValue calls SetMutableBinding(N, V, S) of base, where base represents the environment that binding of class x is stored.
In step 5-b, the algorithm throws a TypeError exception, because the binding for x in envRec is an immutable binding (class binding).
Since this is an attempt to change the value of an immuatble binding, the algorithm throws TypeError exception.

According to the ECMAScript specification, running a JavaScript program
class x { static { const x = { x } = 0 ; } }is expected to result inReferenceErrorbut after obfuscating the JavaScript program, it results inTypeError.Expected Behavior
Running the following JavaScript code using Node.js results in ReferenceError.
Current Behavior
However, as shown below, running the obfuscated code using Node.js results in TypeError.
Obfuscated code
In summary, obfuscated code results in
TypeError, because obfuscator have renamed constant variable in class static block. (e.g.xto_0x2340e4){ x } = 0and{x}=0x0to initializexinx = { x } = 0and_0x2340e4in_0x2340e4={x}=0x0.xin{x}, the original code resolves toxinconst xand the obfuscated code resolves toxinclass x.ReferenceErrorexception arises because it tries to set mutable binding for uninitializedx, which refers toconst x.TypeErrorexception arises because it tries to change the value of an immutable bindingx, which refers toclass x.Steps to Reproduce
Your Environment
Stack trace
Minimal working example that will help to reproduce issue
Below is a detailed explanation using ECMAScript specification.
Evaluation of
class x { static { const x = { x } = 0 ; } }is done by following algorithms.1. Operation ClassDefinitionEvaluation of ECMAScript specification
In step 3, the algorithm creates an immutable binding of
x.In step 27, the algorithm initializes the binding of
xwithF.In step 31-b, the algorithm calls Call(initializer,receiver).
where initializer represents the
const x = { x } = 0 ;and receiver represents the evaluation result of ClassDefinition of x.2. Operation ClassStaticBlockBody.EvaluateClassStaticBlockBody of the ECMAScript specification
This step evaluates the ClassStaticBlockBody, which represents
const x = { x } = 0 ;and creates binding of variables in ClassStaticBlockBody in class environment.In step 1, the algorithm calls FunctionDeclarationInstantiation(functionObject, <<>>), where functionObject represents the
const x = { x } = 0 ;.This step creates binding of
x, which represents the constant variable nameconst x.In step 2, the algorithm calls the evaluation of ClassStaticBlockStatementList, where ClassStaticBlockStatementList represents
const x = { x } = 0 ;3. Evaluation of LexicalBinding in ECMAScript specification
LexicalBinding represents
x = {x} = 0, and it can be divided into BindingIdentifierxand Initializer= {x} = 0.This algorithm intends to resolve bindingId and evaluate Initializer to initialize binding at step 5.
Note that binding for the constant variable
xis not initialized until it reaches step 5.In step 4, the algorithm calls the evaluation of Initializer.
4. Evaluation of AssignmentExpression in ECMAScript specification
AssignmentExpression represents
{x} = 0, and it can be divided into LeftHandSideExpression{x}and AssignmentExpression0.In step 5, the algorithm calls DestructuringAssignmentEvaluation(value) of assignmentPattern, where value represents 0 and assignmentPattern represents
{x}.Then, DestructuringAssignmentEvaluation calls PropertyDestructuringAssignmentEvaluation(value), where value represents 0.
5. Operation AssignmentProperty.PropertyDestructuringAssignmentEvaluation in ECMASCript specification
In step 2, the algorithm resolves
xas the constant variablex.In step 5, the algorithm calls PutValue(V, W), where V represents a reference of the constant variable
xand W rerpresentsundefined.Then, PutValue calls SetMutableBinding(N, V, S) of base, where base represents the environment that binding of constant variable
xis stored, N representsx, V representsundefined, and S representsTrue.6. Operation SetMutableBinding in ECMAScript specification
In step 3, the algorithm throws a ReferenceError exception, because the binding for N, which is
xin envRec has not yet been initialized.In detail, the
xin envRec refers thexinconst x. Therefore, it has not been initialized.In comparison, the evaluation of the obfuscated JavaScript program,
class x{static{const _0x2340e4={x}=0x0;}}, is similar but different in following steps.2. Operation ClassStaticBlockBody.EvaluateClassStaticBlockBody of the ECMAScript specification
In step 1, the algorithm creates an immutable binding of
_0x2340e4in class environment.In step 2, the algorithm calls the evaluation of ClassStaticBlockStatementList, where ClassStaticBlockStatementList represents
const _0x2340e4 = { x } = 0x0 ;.5. Operation AssignmentProperty.PropertyDestructuringAssignmentEvaluation in ECMASCript specification
In step 2, the algorithm resolves
xas the classx.In step 5, the algorithm calls PutValue(V, W), where V represents a reference of the class
x.Then, PutValue calls SetMutableBinding(N, V, S) of base, where base represents the environment that binding of class
xis stored.6. Operation SetMutableBinding in ECMAScript specification
In step 5-b, the algorithm throws a TypeError exception, because the binding for
xin envRec is an immutable binding (class binding).Since this is an attempt to change the value of an immuatble binding, the algorithm throws TypeError exception.