Title: Renaming constant variable in class static block results in TypeError · Issue #1141 · javascript-obfuscator/javascript-obfuscator · GitHub
Open Graph Title: Renaming constant variable in class static block results in TypeError · Issue #1141 · javascript-obfuscator/javascript-obfuscator
X Title: Renaming constant variable in class static block results in TypeError · Issue #1141 · javascript-obfuscator/javascript-obfuscator
Description: 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 ...
Open Graph Description: 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 pro...
X Description: 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 pro...
Opengraph URL: https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1141
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Renaming constant variable in class static block results in TypeError","articleBody":"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`.\r\n\r\n\u003c!-- Love javascript-obfuscator? Please consider supporting our collective:\r\n👉 https://opencollective.com/javascript-obfuscator/donate --\u003e\r\n\r\n\u003c!--- Provide a general summary of the issue in the Title above --\u003e\r\n\r\n## Expected Behavior\r\n\u003c!--- Tell us what should happen --\u003e\r\n\u003c!-- Expected ReferenceError but got TypeError from the obfuscated code. --\u003e\r\n\r\nRunning the following JavaScript code using Node.js results in ReferenceError.\r\n\r\n```JavaScript\r\nclass x { static { const x = { x } = 0 ; } }\r\n```\r\n\u003cimg width=\"456\" alt=\"obfuscator_referenceerror\" src=\"https://user-images.githubusercontent.com/48983829/213082925-ceabb5ed-5da6-431f-8365-b15c4ba2edd3.png\"\u003e\r\n\r\n## Current Behavior\r\n\u003c!--- Tell us what happens instead of the expected behavior --\u003e\r\n\r\nHowever, as shown below, running the obfuscated code using Node.js results in TypeError.\r\n\r\nObfuscated code\r\n```JavaScript\r\nclass x{static{const _0x2340e4={x}=0x0;}}\r\n```\r\n\u003cimg width=\"377\" alt=\"obfuscator_typeerror\" src=\"https://user-images.githubusercontent.com/48983829/213082935-a88c18b2-91ee-43b8-b84e-f9dc85b1101f.png\"\u003e\r\n\r\nIn summary, obfuscated code results in `TypeError`, because obfuscator have renamed constant variable in class static block. (e.g. `x` to `_0x2340e4`)\r\n1. 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`.\r\n2. When resolving `x` in `{x}`, the original code resolves to `x` in `const x` and the obfuscated code resolves to `x` in `class x`.\r\n3. In case of the original code,\r\n 1. `ReferenceError` exception arises because it tries to set mutable binding for uninitialized `x`, which refers to `const x`.\r\n4. In case of the obfuscated code,\r\n 1. the `TypeError` exception arises because it tries to change the value of an immutable binding `x`, which refers to `class x`.\r\n\r\n\r\n## Steps to Reproduce\r\n\u003c!--- Provide a link to a live example, or an unambiguous set of steps to --\u003e\r\n\u003c!--- reproduce this bug. Include code to reproduce, if relevant --\u003e\r\n1. Obfuscate the following program using https://obfuscator.io.\r\n2. Run the following program using Node.js v18.13.0.\r\n\r\n## Your Environment\r\n\u003c!--- Include as many relevant details about the environment you experienced the bug in --\u003e\r\n* Obfuscator version used: https://obfuscator.io.\r\n* Node version used: v18.13.0\r\n\r\n# Stack trace\r\n\u003c!--- Include stack trace --\u003e\r\n\r\n## Minimal working example that will help to reproduce issue\r\n\u003c!--- Include code --\u003e\r\n\r\n* * *\r\nBelow is a detailed explanation using ECMAScript specification.\r\n\r\nEvaluation of `class x { static { const x = { x } = 0 ; } }` is done by following algorithms.\r\n\r\n### 1. [Operation ClassDefinitionEvaluation of ECMAScript specification](https://tc39.es/ecma262/#sec-runtime-semantics-classdefinitionevaluation)\r\n\r\nIn step 3, the algorithm creates an immutable binding of `x`.\r\n\r\nIn step 27, the algorithm initializes the binding of `x` with `F`.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_3\" src=\"https://user-images.githubusercontent.com/48983829/213086652-444f58ba-079f-46a6-9726-2d5bc36d1a8b.png\"\u003e\r\n\u003cimg width=\"700\" alt=\"obs_4\" src=\"https://user-images.githubusercontent.com/48983829/213086668-5b5ed8d2-3498-47ae-8c1f-3f7ce0f1bedb.png\"\u003e\r\n\r\nIn step 31-b, the algorithm calls **Call**_(initializer,receiver)_.\r\nwhere _initializer_ represents the `const x = { x } = 0 ;` and _receiver_ represents the evaluation result of *ClassDefinition* of x.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_5\" src=\"https://user-images.githubusercontent.com/48983829/213086687-58a74cba-1edd-4e2e-90c2-4c2972df3896.png\"\u003e\r\n\r\n### 2. [Operation ClassStaticBlockBody.EvaluateClassStaticBlockBody of the ECMAScript specification](https://tc39.es/ecma262/#sec-runtime-semantics-evaluateclassstaticblockbody)\r\n\r\nThis step evaluates the _ClassStaticBlockBody_, which represents `const x = { x } = 0 ;` and creates binding of variables in _ClassStaticBlockBody_ in class environment.\r\n\r\nIn step 1, the algorithm calls **FunctionDeclarationInstantiation**_(functionObject, \u003c\u003c\u003e\u003e)_, where functionObject represents the `const x = { x } = 0 ;`.\r\nThis step creates binding of `x`, which represents the constant variable name `const x`.\r\n\r\nIn step 2, the algorithm calls the evaluation of *ClassStaticBlockStatementList*, where *ClassStaticBlockStatementList* represents `const x = { x } = 0 ;`\r\n\r\n\u003cimg width=\"700\" alt=\"obs_10\" src=\"https://user-images.githubusercontent.com/48983829/213089286-e051a9cf-8676-485d-80bc-46a22ec175ba.png\"\u003e\r\n\r\n\r\n### 3. [Evaluation of _LexicalBinding_ in ECMAScript specification](https://tc39.es/ecma262/#sec-let-and-const-declarations-runtime-semantics-evaluation)\r\n*LexicalBinding* represents `x = {x} = 0`, and it can be divided into *BindingIdentifier* `x` and *Initializer* `= {x} = 0`.\r\n\r\nThis algorithm intends to resolve *bindingId* and evaluate *Initializer* to initialize binding at step 5.\r\n\r\nNote that binding for the constant variable `x` is **not initialized** until it reaches step 5. \r\n\r\nIn step 4, the algorithm calls the evaluation of *Initializer*.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_11\" src=\"https://user-images.githubusercontent.com/48983829/213089312-ca97f6bc-9ba8-499e-b3a5-b70b3fd0461a.png\"\u003e\r\n\r\n### 4. [Evaluation of _AssignmentExpression_ in ECMAScript specification](https://tc39.es/ecma262/#sec-assignment-operators-runtime-semantics-evaluation)\r\n\r\n*AssignmentExpression* represents `{x} = 0`, and it can be divided into *LeftHandSideExpression* `{x}` and *AssignmentExpression* `0`.\r\n\r\nIn step 5, the algorithm calls **DestructuringAssignmentEvaluation**_(value)_ of _assignmentPattern_, where _value_ represents 0 and _assignmentPattern_ represents `{x}`.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_12\" src=\"https://user-images.githubusercontent.com/48983829/213089835-c42cf0da-6661-4e42-9f97-ada32dc26f80.png\"\u003e\r\n\r\nThen, **DestructuringAssignmentEvaluation** calls **PropertyDestructuringAssignmentEvaluation**_(value)_, where _value_ represents 0.\r\n\r\n### 5. [Operation AssignmentProperty.PropertyDestructuringAssignmentEvaluation in ECMASCript specification](https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation)\r\n\r\nIn step 2, the algorithm resolves `x` as the constant variable `x`.\r\n\r\nIn step 5, the algorithm calls **PutValue**_(V, W)_, where _V_ represents a reference of the constant variable `x` and _W_ rerpresents `undefined`.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_14\" src=\"https://user-images.githubusercontent.com/48983829/213090859-acb52282-5a33-47d2-bad8-5909b818b3ac.png\"\u003e\r\n\r\nThen, **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`.\r\n\r\n### 6. [Operation SetMutableBinding in ECMAScript specification](https://tc39.es/ecma262/#sec-declarative-environment-records-setmutablebinding-n-v-s)\r\n\r\nIn step 3, the algorithm throws a **ReferenceError** exception, because the binding for N, which is `x` in envRec has not yet been initialized.\r\n\r\nIn detail, the `x` in envRec refers the `x` in `const x`. Therefore, it has not been initialized.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_16\" src=\"https://user-images.githubusercontent.com/48983829/213091849-16f6e1cf-79e9-478b-87db-82ace2e2d19d.png\"\u003e\r\n\r\n---\r\nIn comparison, the evaluation of the obfuscated JavaScript program, `class x{static{const _0x2340e4={x}=0x0;}}`, is similar but different in following steps.\r\n\r\n### 2. [Operation ClassStaticBlockBody.EvaluateClassStaticBlockBody of the ECMAScript specification](https://tc39.es/ecma262/#sec-runtime-semantics-evaluateclassstaticblockbody)\r\n\r\nIn step 1, the algorithm creates an immutable binding of `_0x2340e4` in class environment.\r\n\r\nIn step 2, the algorithm calls the evaluation of *ClassStaticBlockStatementList*, where *ClassStaticBlockStatementList* represents `const _0x2340e4 = { x } = 0x0 ;`.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_10\" src=\"https://user-images.githubusercontent.com/48983829/213089286-e051a9cf-8676-485d-80bc-46a22ec175ba.png\"\u003e\r\n\r\n\r\n### 5. [Operation AssignmentProperty.PropertyDestructuringAssignmentEvaluation in ECMASCript specification](https://tc39.es/ecma262/#sec-runtime-semantics-propertydestructuringassignmentevaluation)\r\n\r\nIn step 2, the algorithm resolves `x` as the class `x`.\r\n\r\nIn step 5, the algorithm calls **PutValue**_(V, W)_, where _V_ represents a reference of the class `x`.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_14\" src=\"https://user-images.githubusercontent.com/48983829/213090859-acb52282-5a33-47d2-bad8-5909b818b3ac.png\"\u003e\r\n\r\nThen, **PutValue** calls **SetMutableBinding**_(N, V, S)_ of _base_, where _base_ represents the environment that binding of class `x` is stored.\r\n\r\n### 6. [Operation SetMutableBinding in ECMAScript specification](https://tc39.es/ecma262/#sec-declarative-environment-records-setmutablebinding-n-v-s)\r\n\r\nIn step 5-b, the algorithm throws a **TypeError** exception, because the binding for `x` in envRec is an immutable binding (class binding).\r\n\r\nSince this is an attempt to change the value of an immuatble binding, the algorithm throws **TypeError** exception.\r\n\r\n\u003cimg width=\"700\" alt=\"obs_16\" src=\"https://user-images.githubusercontent.com/48983829/213091849-16f6e1cf-79e9-478b-87db-82ace2e2d19d.png\"\u003e\r\n","author":{"url":"https://github.com/nicolejrkim","@type":"Person","name":"nicolejrkim"},"datePublished":"2023-01-18T06:00:51.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/1141/javascript-obfuscator/issues/1141"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:d3c52669-a6b9-f7ce-3928-a56020bbb7c5 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | CE14:198EE1:52025:71FAF:6A62F6C7 |
| html-safe-nonce | cfe5cc11aa18ff3d9930087b6f843d05f328c5c809a9987d8404ebaeb68f2b59 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDRTE0OjE5OEVFMTo1MjAyNTo3MUZBRjo2QTYyRjZDNyIsInZpc2l0b3JfaWQiOiIzNzgzNjI3NjQyNzgyMjgzNDYzIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | afef810fbd67d5d4bf6abba6003f427bef3aa13b0bd60e779b8e796cc50bdc3a |
| hovercard-subject-tag | issue:1537445903 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/javascript-obfuscator/javascript-obfuscator/1141/issue_layout |
| twitter:image | https://opengraph.githubassets.com/be18ec7d452d5142e896d6ce3a99de224772401a4e28d3239937f0840f55939b/javascript-obfuscator/javascript-obfuscator/issues/1141 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/be18ec7d452d5142e896d6ce3a99de224772401a4e28d3239937f0840f55939b/javascript-obfuscator/javascript-obfuscator/issues/1141 |
| og:image:alt | 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 pro... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | nicolejrkim |
| hostname | github.com |
| expected-hostname | github.com |
| None | b415018e190e73858133ddcaa36acce7b3f3572fe54dda84bd3b21a6ec714c30 |
| turbo-cache-control | no-preview |
| go-import | github.com/javascript-obfuscator/javascript-obfuscator git https://github.com/javascript-obfuscator/javascript-obfuscator.git |
| octolytics-dimension-user_id | 23015672 |
| octolytics-dimension-user_login | javascript-obfuscator |
| octolytics-dimension-repository_id | 58360147 |
| octolytics-dimension-repository_nwo | javascript-obfuscator/javascript-obfuscator |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 58360147 |
| octolytics-dimension-repository_network_root_nwo | javascript-obfuscator/javascript-obfuscator |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 22f98521e99f504294ab0812b66104d50eb75a70 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width