mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:57:35 +00:00
LibJS: Correct behaviour of direct vs. indirect eval
eval only has direct access to the local scope when accessed through the name eval. This includes locals named eval, because of course it does.
This commit is contained in:
parent
5d24b5f4be
commit
2822da8c8f
10 changed files with 121 additions and 20 deletions
|
@ -8,13 +8,13 @@
|
|||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/Hex.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/TemporaryChange.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibJS/Console.h>
|
||||
#include <LibJS/Heap/DeferGC.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Lexer.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/AggregateErrorConstructor.h>
|
||||
#include <LibJS/Runtime/AggregateErrorPrototype.h>
|
||||
#include <LibJS/Runtime/ArrayBufferConstructor.h>
|
||||
|
@ -140,6 +140,8 @@ void GlobalObject::initialize_global_object()
|
|||
define_native_function(vm.names.parseFloat, parse_float, 1, attr);
|
||||
define_native_function(vm.names.parseInt, parse_int, 2, attr);
|
||||
define_native_function(vm.names.eval, eval, 1, attr);
|
||||
m_eval_function = &get_without_side_effects(vm.names.eval).as_function();
|
||||
|
||||
define_native_function(vm.names.encodeURI, encode_uri, 1, attr);
|
||||
define_native_function(vm.names.decodeURI, decode_uri, 1, attr);
|
||||
define_native_function(vm.names.encodeURIComponent, encode_uri_component, 1, attr);
|
||||
|
@ -223,6 +225,8 @@ void GlobalObject::visit_edges(Visitor& visitor)
|
|||
visitor.visit(m_##snake_name##_prototype);
|
||||
JS_ENUMERATE_ITERATOR_PROTOTYPES
|
||||
#undef __JS_ENUMERATE
|
||||
|
||||
visitor.visit(m_eval_function);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::gc)
|
||||
|
@ -335,23 +339,7 @@ JS_DEFINE_NATIVE_FUNCTION(GlobalObject::parse_int)
|
|||
// 19.2.1 eval ( x ), https://tc39.es/ecma262/#sec-eval-x
|
||||
JS_DEFINE_NATIVE_FUNCTION(GlobalObject::eval)
|
||||
{
|
||||
if (!vm.argument(0).is_string())
|
||||
return vm.argument(0);
|
||||
auto& code_string = vm.argument(0).as_string();
|
||||
JS::Parser parser { JS::Lexer { code_string.string() } };
|
||||
auto program = parser.parse_program();
|
||||
|
||||
if (parser.has_errors()) {
|
||||
auto& error = parser.errors()[0];
|
||||
vm.throw_exception<SyntaxError>(global_object, error.to_string());
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& caller_frame = vm.call_stack().at(vm.call_stack().size() - 2);
|
||||
TemporaryChange scope_change(vm.call_frame().lexical_environment, caller_frame->lexical_environment);
|
||||
|
||||
auto& interpreter = vm.interpreter();
|
||||
return interpreter.execute_statement(global_object, program).value_or(js_undefined());
|
||||
return perform_eval(vm.argument(0), global_object, CallerMode::NonStrict, EvalMode::Indirect);
|
||||
}
|
||||
|
||||
// 19.2.6.1.1 Encode ( string, unescapedSet ), https://tc39.es/ecma262/#sec-encode
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue