-
Notifications
You must be signed in to change notification settings - Fork 119
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
[Error] same sub-function & variable name inside a same function #159
Comments
Thanks for reporting this bug. I am not too sure how easy it would be to fix. @ksen007 do you have any thoughts or ideas here? |
Jalangi intruments the above code as follows:
and the error occurs because 'var t' and 'function t' are declared within the same block. However, if these two are declared within the same function, they don't raise an error. Therefore, the above instrumentation should be modified as follows:
This does run without an error. So, I think Jalangi should enclose the global scope and every function scope with |
Thanks for the explanation! Yes, it seems the issue here is that Jalangi is moving function statements into a nested scope from the top-level scope. I think your idea for an initial fix is reasonable. I think you'd need to introduce the fix at two places in For script bodies: jalangi2/src/js/instrument/esnstrument.js Line 954 in 7f0be09
For function bodies: jalangi2/src/js/instrument/esnstrument.js Line 979 in 7f0be09
Could you go ahead and test out your proposed fix to see if it works? If it works for you, and you open a PR with the fix and your test case, that would be great. |
I replaced both lines as follow:
And it works for this sample code:
But strangely enough, does not work for this:
|
Now that I think about it, wrapping the top-level script body in an anonymous function is not a good idea, since on the web, variables declared at the top level are globals that are visible from other scripts. So you'll need another solution there. Or, if the solution for function bodies is good enough for your use case, that might be a good intermediate step for now. |
Yes, this is the problem I actually just encountered. I started to see many red errors when I tested this on the web... |
Are you running into this problem at the top level of many scripts? I would expect this problem to come up quite rarely. |
I see this problem for jQuery |
Can you link to the problematic code? |
I am sorry, but because my version of Jalangi is connected to Puppeteer, it's little complex to show them here... But basically, global objects such as JQuery imported from the web's jquery.js raise an undefined error. I think this issue could be resolved if we enforce Jalangi to rewrite such undefined objects as window.JQuery instead of just JQuery (we apply this rule only if Jalangi's read / write callback detects that the target object is undefined). What do you think? |
So sorry for my slow response. I see how jQuery would cause an issue with your solution. What I was wondering was are you seeing this issue of a variable and function statement with the same name in the global scope, in function scopes, or both? I was hoping it was only happening in function scopes, so you could just not apply your fix at the global scope for now. I think your solution of using |
I am really sorry for my late reply. I had a car accident and was trying to recover... Now I am back. I really want to solve this issue of error for re-definition. As I already tried, enclosing the definitions with a dynamic function is not a good solution, because this causes a scope issue. Do you have any good solution in mind? |
Sorry to hear about your accident, and glad that you've recovered! As noted originally, this problem arises when there are both a variable and a function statement with the same name defined at the top-level scope of a function. In such cases, Jalangi causes a problem since it moves the function statement within a nested scope. You proposed wrapping the nested scope in an anonymous function. This fix caused issues at the global scope level, since it effectively hides global variables. My question was, is the issue with a duplicate variable and function statement with the same name appearing for you at the top level of scripts? If not, you can just apply the anonymous function solution within functions and you are done. If it is appearing at the top level, we'd need to think more. And it'd be great to see an example of such code. |
Thanks a lot for your worries, I am feeling much better now.
Yes, this happens in https://facebook.com. The code is very complex, but I narrowed down the problematic part, and the issue is because both 'var V' and 'function V' are declared in the same global scope and other scripts try to access them... |
I think the possible solution is that we wrap the code in the 'wrapScriptBodyWithTryCatch' with an anonymous function, and then right after each function declaration and assignment expression in the top-level scope this anonymous function, we append a new expression in the following format:
Do you think this will be a valid solution? If so, I was not sure how/where I am supposed to change the source code to apply this instrumentation... |
I have a possibly simpler temporary workaround. It looks like jalangi2/src/js/instrument/esnstrument.js Line 948 in 7f0be09
Could you try uncommenting this line? Line 53 in 7f0be09
That should disable the try-catch instrumentation altogether. Does that fix your problem? The only catch here is that you will lose the Jalangi callbacks for uncaught exceptions and some stuff related to the arguments array. If you need that functionality, then I think another solution would be to "hoist" named function statements in front of the inserted try-catch blocks. I think that would be simpler than what you proposed. But it would still be a bit of work. |
Thanks for the tip. I tried to uncomment that line, but I get this error, then:
Also, even if we remove the try-catch block, there is a while loop block outside there, so there wouldn't go away unless we also remove the while loop.. |
That flag should remove both the try-catch and the while loop. Too bad it doesn't work right now. Where do you get the IllegalStateException? During instrumentation, or while running the instrumented code? |
I see.. I get the error during instrumentation:
|
So it seems the jalangi2/src/js/instrument/esnstrument.js Line 1800 in 7f0be09
But this just hoists function declarations to the top of the current scope. We would need to somehow enhance it to hoist the declarations above the generated while loop, try-catch, etc. Also for some reason the current code deliberately does not hoist function declarations above the script-enter and function-enter callbacks. I am not sure why; it seems it could be hoisted further to me, and all tests pass locally if I disable that logic. Unfortunately I don't have time to fix the above in the near term. It seems pretty doable to me, but not completely trivial. @gogo9th you can either take a crack at this, or try the fix you were thinking about if you think that would be easier. |
I am very sorry for my late update.. Here I modified esnstrument.js as you suggested: I added the hoistFn_and_ExtractDeclarations() function which hoisters both function declarations and variable declarations to outside the while loop, just above the Jalangi label. This is applied at the end of each wrapScriptBodyWithTryCatch() or wrapFunBodyWithTryCatch() call. When I hoister variables, I do not hoister their initialization. I hope the code is correct. I tested about 10 tricky test cases I created, and it works fine. When I hoist, I move function declarations up, but for variable declarations, I only copy them without initialization and put the copied versions up. This means I leave the original variable declarations in their original positions. Would this cause any problem? I do this, because I wanted any variable initializations to happen in the original locations. |
@gogo9th could you open a pull request with your changes? That will make them a lot easier to read. If you could include your tests in the PR, even better.
Do you mean that you hoist the declaration, but leave just the initialization in place? That makes sense to me. But if after your transformation, there are two different declarations for the variable, that might cause issues, if they are in different scopes. If you post a PR I can look more carefully at what you did. |
Hi,
I really need urgent help on this... Jalangi fails to instrument the following code which is regularly runnable by NodeJS:
Jalangi outputs:
SyntaxError: Identifier 't' has already been declared
Could you please give me an easy instruction on how to fix this bug in Jalangi's source code? Thanks very much for your help.
The text was updated successfully, but these errors were encountered: