mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-09 18:16:09 +03:00
LibWeb: Add the Web::Crypto namespace, built-in, and getRandomValues
Since we don't support IDL typedefs or unions yet, the responsibility of verifying the type of the argument is temporarily moved from the generated Wrapper to the implementation.
This commit is contained in:
parent
becbb0ea97
commit
2c6c9b73c8
Notes:
sideshowbarker
2024-07-18 03:16:47 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/2c6c9b73c88 Pull-request: https://github.com/SerenityOS/serenity/pull/10279
@ -726,7 +726,7 @@ int main(int argc, char** argv)
|
||||
auto data = file_or_error.value()->read_all();
|
||||
auto interface = IDL::parse_interface(path, data);
|
||||
|
||||
if (namespace_.is_one_of("CSS", "DOM", "HTML", "UIEvents", "Geometry", "HighResolutionTime", "NavigationTiming", "RequestIdleCallback", "SVG", "XHR", "URL")) {
|
||||
if (namespace_.is_one_of("Crypto", "CSS", "DOM", "HTML", "UIEvents", "Geometry", "HighResolutionTime", "NavigationTiming", "RequestIdleCallback", "SVG", "XHR", "URL")) {
|
||||
StringBuilder builder;
|
||||
builder.append(namespace_);
|
||||
builder.append("::");
|
||||
@ -1346,7 +1346,9 @@ static void generate_header(IDL::Interface const& interface)
|
||||
#include <LibWeb/Bindings/Wrapper.h>
|
||||
|
||||
// FIXME: This is very strange.
|
||||
#if __has_include(<LibWeb/CSS/@name@.h>)
|
||||
#if __has_include(<LibWeb/Crypto/@name@.h>)
|
||||
# include <LibWeb/Crypto/@name@.h>
|
||||
#elif __has_include(<LibWeb/CSS/@name@.h>)
|
||||
# include <LibWeb/CSS/@name@.h>
|
||||
#elif __has_include(<LibWeb/DOM/@name@.h>)
|
||||
# include <LibWeb/DOM/@name@.h>
|
||||
@ -2428,7 +2430,9 @@ void generate_constructor_implementation(IDL::Interface const& interface)
|
||||
#include <LibWeb/Bindings/@wrapper_class@.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Bindings/WindowObject.h>
|
||||
#if __has_include(<LibWeb/CSS/@name@.h>)
|
||||
#if __has_include(<LibWeb/Crypto/@name@.h>)
|
||||
# include <LibWeb/Crypto/@name@.h>
|
||||
#elif __has_include(<LibWeb/CSS/@name@.h>)
|
||||
# include <LibWeb/CSS/@name@.h>
|
||||
#elif __has_include(<LibWeb/DOM/@name@.h>)
|
||||
# include <LibWeb/DOM/@name@.h>
|
||||
@ -2730,7 +2734,9 @@ void generate_prototype_implementation(IDL::Interface const& interface)
|
||||
#if __has_include(<LibWeb/Bindings/@prototype_base_class@.h>)
|
||||
# include <LibWeb/Bindings/@prototype_base_class@.h>
|
||||
#endif
|
||||
#if __has_include(<LibWeb/CSS/@name@.h>)
|
||||
#if __has_include(<LibWeb/Crypto/@name@.h>)
|
||||
# include <LibWeb/Crypto/@name@.h>
|
||||
#elif __has_include(<LibWeb/CSS/@name@.h>)
|
||||
# include <LibWeb/CSS/@name@.h>
|
||||
#elif __has_include(<LibWeb/DOM/@name@.h>)
|
||||
# include <LibWeb/DOM/@name@.h>
|
||||
@ -3179,7 +3185,9 @@ static void generate_iterator_header(IDL::Interface const& interface)
|
||||
#include <LibWeb/Bindings/Wrapper.h>
|
||||
|
||||
// FIXME: This is very strange.
|
||||
#if __has_include(<LibWeb/CSS/@name@.h>)
|
||||
#if __has_include(<LibWeb/Crypto/@name@.h>)
|
||||
# include <LibWeb/Crypto/@name@.h>
|
||||
#elif __has_include(<LibWeb/CSS/@name@.h>)
|
||||
# include <LibWeb/CSS/@name@.h>
|
||||
#elif __has_include(<LibWeb/DOM/@name@.h>)
|
||||
# include <LibWeb/DOM/@name@.h>
|
||||
@ -3356,7 +3364,9 @@ void generate_iterator_prototype_implementation(IDL::Interface const& interface)
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Bindings/WindowObject.h>
|
||||
|
||||
#if __has_include(<LibWeb/CSS/@name@.h>)
|
||||
#if __has_include(<LibWeb/Crypto/@name@.h>)
|
||||
# include <LibWeb/Crypto/@name@.h>
|
||||
#elif __has_include(<LibWeb/CSS/@name@.h>)
|
||||
# include <LibWeb/CSS/@name@.h>
|
||||
#elif __has_include(<LibWeb/DOM/@name@.h>)
|
||||
# include <LibWeb/DOM/@name@.h>
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <LibJS/Runtime/Shape.h>
|
||||
#include <LibTextCodec/Decoder.h>
|
||||
#include <LibWeb/Bindings/CSSStyleDeclarationWrapper.h>
|
||||
#include <LibWeb/Bindings/CryptoWrapper.h>
|
||||
#include <LibWeb/Bindings/DocumentWrapper.h>
|
||||
#include <LibWeb/Bindings/ElementWrapper.h>
|
||||
#include <LibWeb/Bindings/EventTargetConstructor.h>
|
||||
@ -30,6 +31,8 @@
|
||||
#include <LibWeb/Bindings/Replaceable.h>
|
||||
#include <LibWeb/Bindings/ScreenWrapper.h>
|
||||
#include <LibWeb/Bindings/WindowObject.h>
|
||||
#include <LibWeb/Bindings/WindowObjectHelper.h>
|
||||
#include <LibWeb/Crypto/Crypto.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Event.h>
|
||||
#include <LibWeb/DOM/Window.h>
|
||||
@ -39,8 +42,6 @@
|
||||
#include <LibWeb/Page/Page.h>
|
||||
#include <LibWeb/WebAssembly/WebAssemblyObject.h>
|
||||
|
||||
#include <LibWeb/Bindings/WindowObjectHelper.h>
|
||||
|
||||
namespace Web::Bindings {
|
||||
|
||||
WindowObject::WindowObject(DOM::Window& impl)
|
||||
@ -65,6 +66,7 @@ void WindowObject::initialize_global_object()
|
||||
define_native_accessor("document", document_getter, {}, JS::Attribute::Enumerable);
|
||||
define_native_accessor("history", history_getter, {}, JS::Attribute::Enumerable);
|
||||
define_native_accessor("performance", performance_getter, {}, JS::Attribute::Enumerable);
|
||||
define_native_accessor("crypto", crypto_getter, {}, JS::Attribute::Enumerable);
|
||||
define_native_accessor("screen", screen_getter, {}, JS::Attribute::Enumerable);
|
||||
define_native_accessor("innerWidth", inner_width_getter, {}, JS::Attribute::Enumerable);
|
||||
define_native_accessor("innerHeight", inner_height_getter, {}, JS::Attribute::Enumerable);
|
||||
@ -497,6 +499,14 @@ JS_DEFINE_NATIVE_FUNCTION(WindowObject::event_setter)
|
||||
REPLACEABLE_PROPERTY_SETTER(WindowObject, event);
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::crypto_getter)
|
||||
{
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
if (!impl)
|
||||
return {};
|
||||
return wrap(global_object, impl->crypto());
|
||||
}
|
||||
|
||||
JS_DEFINE_NATIVE_FUNCTION(WindowObject::inner_width_getter)
|
||||
{
|
||||
auto* impl = impl_from(vm, global_object);
|
||||
|
@ -111,6 +111,8 @@ private:
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(queue_microtask);
|
||||
|
||||
JS_DECLARE_NATIVE_FUNCTION(crypto_getter);
|
||||
|
||||
#define __ENUMERATE(attribute, event_name) \
|
||||
JS_DECLARE_NATIVE_FUNCTION(attribute##_getter); \
|
||||
JS_DECLARE_NATIVE_FUNCTION(attribute##_setter);
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <LibWeb/Bindings/CloseEventPrototype.h>
|
||||
#include <LibWeb/Bindings/CommentConstructor.h>
|
||||
#include <LibWeb/Bindings/CommentPrototype.h>
|
||||
#include <LibWeb/Bindings/CryptoConstructor.h>
|
||||
#include <LibWeb/Bindings/CryptoPrototype.h>
|
||||
#include <LibWeb/Bindings/CustomEventConstructor.h>
|
||||
#include <LibWeb/Bindings/CustomEventPrototype.h>
|
||||
#include <LibWeb/Bindings/DOMExceptionConstructor.h>
|
||||
@ -271,6 +273,7 @@
|
||||
auto& vm = this->vm(); \
|
||||
ADD_WINDOW_OBJECT_INTERFACE(AbortController) \
|
||||
ADD_WINDOW_OBJECT_INTERFACE(AbortSignal) \
|
||||
ADD_WINDOW_OBJECT_INTERFACE(Crypto) \
|
||||
ADD_WINDOW_OBJECT_INTERFACE(CSSRule) \
|
||||
ADD_WINDOW_OBJECT_INTERFACE(CSSRuleList) \
|
||||
ADD_WINDOW_OBJECT_INTERFACE(CSSStyleDeclaration) \
|
||||
|
@ -13,6 +13,7 @@ set(SOURCES
|
||||
Bindings/ScriptExecutionContext.cpp
|
||||
Bindings/WindowObject.cpp
|
||||
Bindings/Wrappable.cpp
|
||||
Crypto/Crypto.cpp
|
||||
CSS/CSSConditionRule.cpp
|
||||
CSS/CSSGroupingRule.cpp
|
||||
CSS/CSSImportRule.cpp
|
||||
@ -341,6 +342,7 @@ function(libweb_js_wrapper class)
|
||||
add_dependencies(all_generated generate_${basename}Prototype.cpp)
|
||||
endfunction()
|
||||
|
||||
libweb_js_wrapper(Crypto/Crypto)
|
||||
libweb_js_wrapper(CSS/CSSRule)
|
||||
libweb_js_wrapper(CSS/CSSRuleList)
|
||||
libweb_js_wrapper(CSS/CSSStyleDeclaration)
|
||||
|
37
Userland/Libraries/LibWeb/Crypto/Crypto.cpp
Normal file
37
Userland/Libraries/LibWeb/Crypto/Crypto.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Random.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibWeb/Bindings/Wrapper.h>
|
||||
#include <LibWeb/Crypto/Crypto.h>
|
||||
|
||||
namespace Web::Crypto {
|
||||
|
||||
DOM::ExceptionOr<JS::Value> Crypto::get_random_values(JS::Value array) const
|
||||
{
|
||||
// 1. If array is not an Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array, then throw a TypeMismatchError and terminate the algorithm.
|
||||
if (!array.is_object() || !(is<JS::Int8Array>(array.as_object()) || is<JS::Uint8Array>(array.as_object()) || is<JS::Uint8ClampedArray>(array.as_object()) || is<JS::Int16Array>(array.as_object()) || is<JS::Uint16Array>(array.as_object()) || is<JS::Int32Array>(array.as_object()) || is<JS::Uint32Array>(array.as_object()) || is<JS::BigInt64Array>(array.as_object()) || is<JS::BigUint64Array>(array.as_object())))
|
||||
return DOM::TypeMismatchError::create("array must be one of Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array");
|
||||
auto& typed_array = static_cast<JS::TypedArrayBase&>(array.as_object());
|
||||
|
||||
// 2. If the byteLength of array is greater than 65536, throw a QuotaExceededError and terminate the algorithm.
|
||||
if (typed_array.byte_length() > 65536)
|
||||
return DOM::QuotaExceededError::create("array's byteLength may not be greater than 65536");
|
||||
|
||||
// IMPLEMENTATION DEFINED: If the viewed array buffer is detached, throw a InvalidStateError and terminate the algorithm.
|
||||
if (typed_array.viewed_array_buffer()->is_detached())
|
||||
return DOM::InvalidStateError::create("array is detached");
|
||||
// FIXME: Handle SharedArrayBuffers
|
||||
|
||||
// 3. Overwrite all elements of array with cryptographically strong random values of the appropriate type.
|
||||
fill_with_random(typed_array.viewed_array_buffer()->buffer().data(), typed_array.viewed_array_buffer()->buffer().size());
|
||||
|
||||
// 4. Return array.
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
38
Userland/Libraries/LibWeb/Crypto/Crypto.h
Normal file
38
Userland/Libraries/LibWeb/Crypto/Crypto.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibWeb/Bindings/Wrappable.h>
|
||||
#include <LibWeb/DOM/ExceptionOr.h>
|
||||
|
||||
namespace Web::Crypto {
|
||||
|
||||
class Crypto : public Bindings::Wrappable
|
||||
, public RefCounted<Crypto>
|
||||
, public Weakable<Crypto> {
|
||||
public:
|
||||
using WrapperType = Bindings::CryptoWrapper;
|
||||
|
||||
static NonnullRefPtr<Crypto> create()
|
||||
{
|
||||
return adopt_ref(*new Crypto());
|
||||
}
|
||||
|
||||
DOM::ExceptionOr<JS::Value> get_random_values(JS::Value array) const;
|
||||
|
||||
private:
|
||||
Crypto() = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace Web::Bindings {
|
||||
|
||||
CryptoWrapper* wrap(JS::GlobalObject&, Crypto::Crypto&);
|
||||
|
||||
}
|
7
Userland/Libraries/LibWeb/Crypto/Crypto.idl
Normal file
7
Userland/Libraries/LibWeb/Crypto/Crypto.idl
Normal file
@ -0,0 +1,7 @@
|
||||
[Exposed=(Window,Worker)]
|
||||
interface Crypto {
|
||||
// TODO: [SecureContext] readonly attribute SubtleCrypto subtle;
|
||||
|
||||
// FIXME: the argument and the return value should be of type ArrayBufferView
|
||||
any getRandomValues(any array);
|
||||
};
|
@ -7,6 +7,7 @@
|
||||
#include <LibGUI/DisplayLink.h>
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
#include <LibWeb/CSS/ResolvedCSSStyleDeclaration.h>
|
||||
#include <LibWeb/Crypto/Crypto.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Event.h>
|
||||
#include <LibWeb/DOM/EventDispatcher.h>
|
||||
@ -94,6 +95,7 @@ Window::Window(Document& document)
|
||||
: EventTarget(static_cast<Bindings::ScriptExecutionContext&>(document))
|
||||
, m_associated_document(document)
|
||||
, m_performance(make<HighResolutionTime::Performance>(*this))
|
||||
, m_crypto(Crypto::Crypto::create())
|
||||
, m_screen(CSS::Screen::create(*this))
|
||||
{
|
||||
}
|
||||
|
@ -74,6 +74,8 @@ public:
|
||||
|
||||
HighResolutionTime::Performance& performance() { return *m_performance; }
|
||||
|
||||
Crypto::Crypto& crypto() { return *m_crypto; }
|
||||
|
||||
CSS::Screen& screen() { return *m_screen; }
|
||||
|
||||
Event const* current_event() const { return m_current_event; }
|
||||
@ -107,6 +109,7 @@ private:
|
||||
HashMap<int, NonnullRefPtr<Timer>> m_timers;
|
||||
|
||||
NonnullOwnPtr<HighResolutionTime::Performance> m_performance;
|
||||
NonnullRefPtr<Crypto::Crypto> m_crypto;
|
||||
NonnullRefPtr<CSS::Screen> m_screen;
|
||||
RefPtr<Event> m_current_event;
|
||||
|
||||
|
@ -13,6 +13,10 @@ struct ParsedCookie;
|
||||
enum class Source;
|
||||
}
|
||||
|
||||
namespace Web::Crypto {
|
||||
class Crypto;
|
||||
}
|
||||
|
||||
namespace Web::CSS {
|
||||
class CalculatedStyleValue;
|
||||
class CSSRule;
|
||||
@ -262,6 +266,7 @@ class URLSearchParamsIterator;
|
||||
namespace Web::Bindings {
|
||||
class AbortControllerWrapper;
|
||||
class AbortSignalWrapper;
|
||||
class CryptoWrapper;
|
||||
class CSSRuleListWrapper;
|
||||
class CSSRuleWrapper;
|
||||
class CSSStyleDeclarationWrapper;
|
||||
|
@ -361,7 +361,7 @@ JS::Value to_js_value(Wasm::Value& wasm_value, JS::GlobalObject& global_object)
|
||||
{
|
||||
switch (wasm_value.type().kind()) {
|
||||
case Wasm::ValueType::I64:
|
||||
return global_object.heap().allocate<JS::BigInt>(global_object, Crypto::SignedBigInteger::create_from(wasm_value.to<i64>().value()));
|
||||
return global_object.heap().allocate<JS::BigInt>(global_object, ::Crypto::SignedBigInteger::create_from(wasm_value.to<i64>().value()));
|
||||
case Wasm::ValueType::I32:
|
||||
return JS::Value(wasm_value.to<i32>().value());
|
||||
case Wasm::ValueType::F64:
|
||||
@ -382,7 +382,7 @@ JS::Value to_js_value(Wasm::Value& wasm_value, JS::GlobalObject& global_object)
|
||||
|
||||
Optional<Wasm::Value> to_webassembly_value(JS::Value value, const Wasm::ValueType& type, JS::GlobalObject& global_object)
|
||||
{
|
||||
static Crypto::SignedBigInteger two_64 = "1"_sbigint.shift_left(64);
|
||||
static ::Crypto::SignedBigInteger two_64 = "1"_sbigint.shift_left(64);
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
switch (type.kind()) {
|
||||
|
Loading…
Reference in New Issue
Block a user