mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:57:43 +00:00
WebContent: Implement ConsoleGlobalObject which proxies to WindowObject
ConsoleGlobalObject is used as the global object when running javascript from the Browser console. This lets us implement console-only functions and variables (like `$0`) without exposing them to webpage content. It passes other calls over to the usual WindowObject so any code that would have worked in the webpage will still work in the console. :^)
This commit is contained in:
parent
ca2c129923
commit
7838eab341
8 changed files with 156 additions and 10 deletions
|
@ -8,6 +8,7 @@ compile_ipc(WebContentClient.ipc WebContentClientEndpoint.h)
|
|||
|
||||
set(SOURCES
|
||||
ClientConnection.cpp
|
||||
ConsoleGlobalObject.cpp
|
||||
main.cpp
|
||||
PageHost.cpp
|
||||
WebContentConsoleClient.cpp
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <LibJS/Heap/Heap.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/HashMap.h>
|
||||
#include <LibIPC/ClientConnection.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <WebContent/Forward.h>
|
||||
|
@ -72,6 +73,7 @@ private:
|
|||
|
||||
WeakPtr<JS::Interpreter> m_interpreter;
|
||||
OwnPtr<WebContentConsoleClient> m_console_client;
|
||||
JS::Handle<JS::GlobalObject> m_console_global_object;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
90
Userland/Services/WebContent/ConsoleGlobalObject.cpp
Normal file
90
Userland/Services/WebContent/ConsoleGlobalObject.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "ConsoleGlobalObject.h"
|
||||
#include <LibWeb/Bindings/WindowObject.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Window.h>
|
||||
|
||||
namespace WebContent {
|
||||
|
||||
ConsoleGlobalObject::ConsoleGlobalObject(Web::Bindings::WindowObject& parent_object)
|
||||
: m_window_object(&parent_object)
|
||||
{
|
||||
}
|
||||
|
||||
ConsoleGlobalObject::~ConsoleGlobalObject()
|
||||
{
|
||||
}
|
||||
|
||||
void ConsoleGlobalObject::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_window_object);
|
||||
}
|
||||
|
||||
JS::Object* ConsoleGlobalObject::internal_get_prototype_of() const
|
||||
{
|
||||
return m_window_object->internal_get_prototype_of();
|
||||
}
|
||||
|
||||
bool ConsoleGlobalObject::internal_set_prototype_of(JS::Object* prototype)
|
||||
{
|
||||
return m_window_object->internal_set_prototype_of(prototype);
|
||||
}
|
||||
|
||||
bool ConsoleGlobalObject::internal_is_extensible() const
|
||||
{
|
||||
return m_window_object->internal_is_extensible();
|
||||
}
|
||||
|
||||
bool ConsoleGlobalObject::internal_prevent_extensions()
|
||||
{
|
||||
return m_window_object->internal_prevent_extensions();
|
||||
}
|
||||
|
||||
Optional<JS::PropertyDescriptor> ConsoleGlobalObject::internal_get_own_property(JS::PropertyName const& property_name) const
|
||||
{
|
||||
if (auto result = m_window_object->internal_get_own_property(property_name); result.has_value())
|
||||
return result;
|
||||
|
||||
return Base::internal_get_own_property(property_name);
|
||||
}
|
||||
|
||||
bool ConsoleGlobalObject::internal_define_own_property(JS::PropertyName const& property_name, JS::PropertyDescriptor const& descriptor)
|
||||
{
|
||||
return m_window_object->internal_define_own_property(property_name, descriptor);
|
||||
}
|
||||
|
||||
bool ConsoleGlobalObject::internal_has_property(JS::PropertyName const& property_name) const
|
||||
{
|
||||
return Object::internal_has_property(property_name) || m_window_object->internal_has_property(property_name);
|
||||
}
|
||||
|
||||
JS::Value ConsoleGlobalObject::internal_get(JS::PropertyName const& property_name, JS::Value receiver) const
|
||||
{
|
||||
if (m_window_object->has_own_property(property_name))
|
||||
return m_window_object->internal_get(property_name, (receiver == this) ? m_window_object : receiver);
|
||||
|
||||
return Base::internal_get(property_name, receiver);
|
||||
}
|
||||
|
||||
bool ConsoleGlobalObject::internal_set(JS::PropertyName const& property_name, JS::Value value, JS::Value receiver)
|
||||
{
|
||||
return m_window_object->internal_set(property_name, value, (receiver == this) ? m_window_object : receiver);
|
||||
}
|
||||
|
||||
bool ConsoleGlobalObject::internal_delete(JS::PropertyName const& property_name)
|
||||
{
|
||||
return m_window_object->internal_delete(property_name);
|
||||
}
|
||||
|
||||
JS::MarkedValueList ConsoleGlobalObject::internal_own_property_keys() const
|
||||
{
|
||||
return m_window_object->internal_own_property_keys();
|
||||
}
|
||||
|
||||
}
|
43
Userland/Services/WebContent/ConsoleGlobalObject.h
Normal file
43
Userland/Services/WebContent/ConsoleGlobalObject.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
|
||||
namespace Web::Bindings {
|
||||
class WindowObject;
|
||||
}
|
||||
|
||||
namespace WebContent {
|
||||
|
||||
class ConsoleGlobalObject final : public JS::GlobalObject {
|
||||
JS_OBJECT(ConsoleGlobalObject, JS::GlobalObject);
|
||||
|
||||
public:
|
||||
ConsoleGlobalObject(Web::Bindings::WindowObject&);
|
||||
virtual ~ConsoleGlobalObject() override;
|
||||
|
||||
virtual Object* internal_get_prototype_of() const override;
|
||||
virtual bool internal_set_prototype_of(Object* prototype) override;
|
||||
virtual bool internal_is_extensible() const override;
|
||||
virtual bool internal_prevent_extensions() override;
|
||||
virtual Optional<JS::PropertyDescriptor> internal_get_own_property(JS::PropertyName const& name) const override;
|
||||
virtual bool internal_define_own_property(JS::PropertyName const& name, JS::PropertyDescriptor const& descriptor) override;
|
||||
virtual bool internal_has_property(JS::PropertyName const& name) const override;
|
||||
virtual JS::Value internal_get(JS::PropertyName const&, JS::Value) const override;
|
||||
virtual bool internal_set(JS::PropertyName const&, JS::Value value, JS::Value receiver) override;
|
||||
virtual bool internal_delete(JS::PropertyName const& name) override;
|
||||
virtual JS::MarkedValueList internal_own_property_keys() const override;
|
||||
|
||||
private:
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
Web::Bindings::WindowObject* m_window_object;
|
||||
};
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
namespace WebContent {
|
||||
|
||||
class ClientConnection;
|
||||
class ConsoleGlobalObject;
|
||||
class PageHost;
|
||||
class WebContentConsoleClient;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Brandon Scott <xeon.productions@gmail.com>
|
||||
* Copyright (c) 2020, Hunter Salyer <thefalsehonesty@gmail.com>
|
||||
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -9,10 +10,22 @@
|
|||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/MarkupGenerator.h>
|
||||
#include <LibJS/Parser.h>
|
||||
#include <LibWeb/Bindings/DOMExceptionWrapper.h>
|
||||
#include <LibWeb/Bindings/WindowObject.h>
|
||||
#include <WebContent/ConsoleGlobalObject.h>
|
||||
|
||||
namespace WebContent {
|
||||
|
||||
WebContentConsoleClient::WebContentConsoleClient(JS::Console& console, WeakPtr<JS::Interpreter> interpreter, ClientConnection& client)
|
||||
: ConsoleClient(console)
|
||||
, m_client(client)
|
||||
, m_interpreter(interpreter)
|
||||
{
|
||||
JS::DeferGC defer_gc(m_interpreter->heap());
|
||||
auto console_global_object = m_interpreter->heap().allocate_without_global_object<ConsoleGlobalObject>(static_cast<Web::Bindings::WindowObject&>(m_interpreter->global_object()));
|
||||
console_global_object->initialize_global_object();
|
||||
m_console_global_object = JS::make_handle(console_global_object);
|
||||
}
|
||||
|
||||
void WebContentConsoleClient::handle_input(const String& js_source)
|
||||
{
|
||||
auto parser = JS::Parser(JS::Lexer(js_source));
|
||||
|
@ -24,9 +37,9 @@ void WebContentConsoleClient::handle_input(const String& js_source)
|
|||
auto hint = error.source_location_hint(js_source);
|
||||
if (!hint.is_empty())
|
||||
output_html.append(String::formatted("<pre>{}</pre>", escape_html_entities(hint)));
|
||||
m_interpreter->vm().throw_exception<JS::SyntaxError>(m_interpreter->global_object(), error.to_string());
|
||||
m_interpreter->vm().throw_exception<JS::SyntaxError>(*m_console_global_object.cell(), error.to_string());
|
||||
} else {
|
||||
m_interpreter->run(m_interpreter->global_object(), *program);
|
||||
m_interpreter->run(*m_console_global_object.cell(), *program);
|
||||
}
|
||||
|
||||
if (m_interpreter->exception()) {
|
||||
|
|
|
@ -17,12 +17,7 @@ namespace WebContent {
|
|||
|
||||
class WebContentConsoleClient final : public JS::ConsoleClient {
|
||||
public:
|
||||
WebContentConsoleClient(JS::Console& console, WeakPtr<JS::Interpreter> interpreter, ClientConnection& client)
|
||||
: ConsoleClient(console)
|
||||
, m_client(client)
|
||||
, m_interpreter(interpreter)
|
||||
{
|
||||
}
|
||||
WebContentConsoleClient(JS::Console&, WeakPtr<JS::Interpreter>, ClientConnection&);
|
||||
|
||||
void handle_input(const String& js_source);
|
||||
|
||||
|
@ -40,6 +35,8 @@ private:
|
|||
|
||||
ClientConnection& m_client;
|
||||
WeakPtr<JS::Interpreter> m_interpreter;
|
||||
JS::Handle<ConsoleGlobalObject> m_console_global_object;
|
||||
|
||||
void clear_output();
|
||||
void print_html(const String& line);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue