Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A named function, existing as a variable in its own local scope, shadows the global declaration #251

Closed
malwarebin opened this issue May 12, 2023 · 3 comments · Fixed by #252

Comments

@malwarebin
Copy link

When a named function is called in JS-Interpreter, that very function is introduced in its own local scope as a variable with the same name.

That shadows the actual function declaration in the parent scope and code, which works in NodeJS and in any browser (tested in Chromium, Firefox and Chrome), does not work in JS-Interpreter (see the end of this issue for the actual code).

Debugging the code in a browser shows that the function being called is not present in its local scope, unlike JS-Interpreter.

I skimmed the Function references at MDN but I could not find anything related to this function reassignment issue.

Problem code follows:

function funcArray() {
  var strArray = ['JFfff', 'nfnjsff', 'furhet', 'simmxqe', 'jfFJSDDDD', 'frknwf-fnfh', 'IgfwJ', 'SOMGRWHWND', 'flisJFfd', 'fsdEffhfD', 'fjshe', '16GxFGGwe', '7834fjiweJF', 'wfe', 'FJWEJFf', 'xewasd', '00$slkdjf', 'ggg', 'wednd', ' foiwnf', '2556594jfrwwFF', 'fwrFF', 'sfWfwfWwfw', '500llg', 'ferr-er-re', 'lkesjfsSerr', 'III', '1205955sdkjfSDF', '1 fwerf', 'w;oejf', 'wfffwefef', 'fwefww', 'cjwwwWdjdwWd', 'DDW', 'dwWEdw', ' sdafff:0;', 'nmfwer#0', '7|1|0', 'ionfF', '11Gjfwwje', 'Ejdnw', 'asd.frjier', '326pxFlew', 'sdwe:0. fjkw', 'oweirbddd', 'kwqulfj', 'fewwffwwf', 'y sddffw.iru', 'wef!fioewjw', 'jgirr', 'ssffwef', '2763927wpiejfFw', 'wieihf', '# lihwef:1', 'sdffD', 'eoO', 'fkwlhef', 'wlejf/wekfjwef', '2946fijwWJF', 'fwejEJ', 'lkwehfhf:100&', 'kwsejfw$0; f', 'srewf', 'WFWwwf', 'fwlejfweffff', 'UfwuwUw', 'OWfjfwJ', 'weihwEeewww', 'weFJwf', 'wekfhfwhx', 'wef-wef', '9314730JWfjwJ', '3503476pewfmNF', 'xoxo', 'WEJFnfWNNWF', 'WJXjxjw', 'weJFJFw', 'weejfjw', 'jjj:999999', '20=2fjf2', '4|5|2|3|6|', 'wlehfhflw', 'flweh-fwef', '7371wefWFw', '100...', 'wefWFwfwF', 'owefncC', 'WFwwEF', 'wfwef.wefr.rrr', 'werwerJ.w', 'wcmiweEErrr', 'weWRR', 'WERF', 'werr', 'weff.W>WE.', 'wefjJweff', 'weffweff', 'LWELFddw', 'weEEFff', 'weffwefff'];
  funcArray = function funcArray() {
    return strArray;
  };
  return funcArray();
}
function funcAccess(index) {
  var intrFuncArray = funcArray();
  return funcAccess = function funcAccess(intIndex) {
    intIndex = intIndex - 472;
    var tempResult = intrFuncArray[intIndex];
    return tempResult;
  }, funcAccess(index);
}
(function (myFuncArray, numberEnd) {
  var intFuncAccess = funcAccess,
    intFuncArray = myFuncArray();
  while (true) {
    try {
      var calcNumber = parseInt(intFuncAccess(487)) / 1 * (parseInt(intFuncAccess(557)) / 2) + parseInt(intFuncAccess(565)) / 3 + parseInt(intFuncAccess(517)) / 4 + -parseInt(intFuncAccess(472)) / 5 + -parseInt(intFuncAccess(503)) / 6 * (parseInt(intFuncAccess(528)) / 7) + parseInt(intFuncAccess(556)) / 8 * (-parseInt(intFuncAccess(496)) / 9) + -parseInt(intFuncAccess(516)) / 10 * (parseInt(intFuncAccess(484)) / 11);
      if (calcNumber === numberEnd) break;else {
        intFuncArray.push(intFuncArray.shift());
      }
    } catch (_0x76eba) {
      intFuncArray['push'](intFuncArray['shift']());
    }
  }
})(funcArray, 701116);
console.log('end');
@NeilFraser
Copy link
Owner

Thanks for this. I'm always excited to learn about JS-Interpreter bugs.

Here's a minimal testcase:

function myFunc() {
  myFunc = 42;
}
myFunc();
alert(myFunc);

Browser output: 42
JS-Interpreter output: [object Function]

This will be fixed immediately. Investigating...

@cpcallen
Copy link
Collaborator

cpcallen commented May 12, 2023

There are two bugs here:

  1. With function declarations, per example given in the previous comment.
  2. With named function expressions:
    alert((function foo() { foo = 42; return foo; })())
    should return the function object in nonstrict mode, and throw TypeError: Assignment to constant variable in strict mode, but in fact returns 42.
    • The name of a named function expression is an immutable binding within the body of the function.)
    • N.B. however that it can be shadowed by a parameter or variable:
      alert((function foo(foo) { foo = 42; return foo;})())
      
      and
      alert((function foo() { var foo = 42; return foo;})())
      
      should both return 42 in either strict or nonstrict mode.

NeilFraser added a commit that referenced this issue May 12, 2023
In the case of a function expression with a name (e.g. var x = function foo() {...}) create an intermediate scope that contains the read-only name.

Resolves issue #251.
NeilFraser added a commit that referenced this issue May 16, 2023
In the case of a function expression with a name (e.g. var x = function foo() {...}) create an intermediate scope that contains the read-only name.

Resolves issue #251.
@malwarebin
Copy link
Author

Tested the fix, it works perfectly. Thank you very much!

JS-Interpreter and Blockly are two great projects, your efforts are much appreciated.

If there is a way to send you both a beer or two, please let me know :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants