mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 09:12:13 -05:00
LibJS: Propagate direct eval presence if the current scope is screwed
Previously it only deoptimized the parent scope if the current scope contains direct eval, which is incorrect because code ran in direct eval mode has access to the entire scope chain it was executed in. The fix is to also propagate direct eval's presence if the current scope is marked as being screwed by direct eval. This fixes Google's botguard failing to complete on Google sign in, as it tried to access local variables outside of a direct parent function with eval, causing it throw "unhandled" exceptions. Unhandled is in quotes because their bytecode VM _technically_ caught it, but it was considered an unhandled exception. This was determined by removing get optimizations and then adding debug output for every get operation. Using this, I noticed that for these errors, it would access the 'message' and 'stack' properties. This is because their error handler function noticed this was not a synthesised error, which is never expected to happen. That was determined by using Chrome Devtools 'pause on handled exception' feature, and noticing it never threw a '[var] is not defined' exception, but only synthesized error objects which contained a sentinel value to let it know it was synthesized. I added debug output to eval to print out what was being eval'd because it makes heavy use of eval. This revealed that the exceptions only came from eval. I then dumped every generated executable and noticed the variables it was trying to access were generated as local variables in the top scope. This led to checking what makes a variable considered local or not, which then lead to this block of code in ~ScopePusher that propagates eval presence only to the immediate parent scope. This variable directly controls whether to create all variables properly with variable environments and bindings or allow them to be stored as local registers tied to that function's executable. Since this now lets botguard run to completion, it no longer considers us to be an insecure/potential bot browser when signing in, now allowing us to be able to sign in to Google.
This commit is contained in:
parent
991cb8942d
commit
5f33383a7b
Notes:
github-actions[bot]
2025-01-17 13:36:59 +00:00
Author: https://github.com/Lubrsi Commit: https://github.com/LadybirdBrowser/ladybird/commit/5f33383a7bf Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3288
2 changed files with 25 additions and 1 deletions
|
@ -281,7 +281,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_parent_scope && m_contains_direct_call_to_eval) {
|
||||
if (m_parent_scope && (m_contains_direct_call_to_eval || m_screwed_by_eval_in_scope_chain)) {
|
||||
m_parent_scope->m_screwed_by_eval_in_scope_chain = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,3 +48,27 @@ test("Referencing the declared var in the initializer of a duplicate var declara
|
|||
// It's all good as long as go() doesn't throw.
|
||||
expect(go()).toBe(0);
|
||||
});
|
||||
|
||||
test("direct eval can access variables in the entire scope chain", () => {
|
||||
var a = 1;
|
||||
let g = 4;
|
||||
const j = 8;
|
||||
|
||||
const result = (function () {
|
||||
var e = 2;
|
||||
let h = 5;
|
||||
const k = 9;
|
||||
|
||||
return (function () {
|
||||
var f = 3;
|
||||
let i = 7;
|
||||
const l = 10;
|
||||
|
||||
return (function () {
|
||||
return eval("a + e + f + g + h + i + j + k + l");
|
||||
})();
|
||||
})();
|
||||
})();
|
||||
|
||||
expect(result).toBe(49);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue