diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/Cargo.toml | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/error.rs | 6 | ||||
-rw-r--r-- | components/script/dom/crypto.rs | 82 | ||||
-rw-r--r-- | components/script/dom/domexception.rs | 2 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/webidls/Crypto.webidl | 25 | ||||
-rw-r--r-- | components/script/dom/window.rs | 7 | ||||
-rw-r--r-- | components/script/dom/workerglobalscope.rs | 7 | ||||
-rw-r--r-- | components/script/lib.rs | 1 |
9 files changed, 132 insertions, 0 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 9d343baeea1..d5ab8acd9fa 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -78,3 +78,4 @@ string_cache = "0.1" string_cache_plugin = "0.1" euclid = "0.1" tendril = "0.1.1" +rand = "0.3" diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs index 9c0567067db..373c6c7cbe0 100644 --- a/components/script/dom/bindings/error.rs +++ b/components/script/dom/bindings/error.rs @@ -62,6 +62,10 @@ pub enum Error { DataClone, /// NoModificationAllowedError DOMException NoModificationAllowed, + /// QuotaExceededError DOMException + QuotaExceeded, + /// TypeMismatchError DOMException + TypeMismatch, /// TypeError JavaScript Error Type(DOMString), @@ -101,6 +105,8 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, Error::InvalidNodeType => DOMErrorName::InvalidNodeTypeError, Error::DataClone => DOMErrorName::DataCloneError, Error::NoModificationAllowed => DOMErrorName::NoModificationAllowedError, + Error::QuotaExceeded => DOMErrorName::QuotaExceededError, + Error::TypeMismatch => DOMErrorName::TypeMismatchError, Error::Type(message) => { assert!(unsafe { JS_IsExceptionPending(cx) } == 0); throw_type_error(cx, &message); diff --git a/components/script/dom/crypto.rs b/components/script/dom/crypto.rs new file mode 100644 index 00000000000..aedf1aa0c26 --- /dev/null +++ b/components/script/dom/crypto.rs @@ -0,0 +1,82 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::codegen::Bindings::CryptoBinding; +use dom::bindings::codegen::Bindings::CryptoBinding::CryptoMethods; +use dom::bindings::error::{Error, Fallible}; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::Root; +use dom::bindings::utils::{Reflector, reflect_dom_object}; +use dom::bindings::cell::DOMRefCell; + +use js::jsapi::{JSContext, JSObject}; +use js::jsapi::{JS_GetObjectAsArrayBufferView, JS_GetArrayBufferViewType, Type}; + +use std::ptr; +use std::slice; + +use rand::{Rng, OsRng}; + +no_jsmanaged_fields!(OsRng); + +// https://developer.mozilla.org/en-US/docs/Web/API/Crypto +#[dom_struct] +pub struct Crypto { + reflector_: Reflector, + rng: DOMRefCell<OsRng>, +} + +impl Crypto { + fn new_inherited() -> Crypto { + Crypto { + reflector_: Reflector::new(), + rng: DOMRefCell::new(OsRng::new().unwrap()), + } + } + + pub fn new(global: GlobalRef) -> Root<Crypto> { + reflect_dom_object(box Crypto::new_inherited(), global, CryptoBinding::Wrap) + } +} + +impl<'a> CryptoMethods for &'a Crypto { + // https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#Crypto-method-getRandomValues + #[allow(unsafe_code)] + fn GetRandomValues(self, _cx: *mut JSContext, input: *mut JSObject) + -> Fallible<*mut JSObject> { + let mut length = 0; + let mut data = ptr::null_mut(); + if unsafe { JS_GetObjectAsArrayBufferView(input, &mut length, &mut data).is_null() } { + return Err(Error::Type("Argument to Crypto.getRandomValues is not an ArrayBufferView".to_owned())); + } + if !is_integer_buffer(input) { + return Err(Error::TypeMismatch); + } + if length > 65536 { + return Err(Error::QuotaExceeded); + } + + let mut buffer = unsafe { + slice::from_raw_parts_mut(data, length as usize) + }; + + self.rng.borrow_mut().fill_bytes(&mut buffer); + + Ok(input) + } +} + +#[allow(unsafe_code)] +fn is_integer_buffer(input: *mut JSObject) -> bool { + match unsafe { JS_GetArrayBufferViewType(input) } { + Type::Uint8 | + Type::Uint8Clamped | + Type::Int8 | + Type::Uint16 | + Type::Int16 | + Type::Uint32 | + Type::Int32 => true, + _ => false + } +} diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs index 9bf3a2dd88c..e724b0bcafb 100644 --- a/components/script/dom/domexception.rs +++ b/components/script/dom/domexception.rs @@ -32,6 +32,7 @@ pub enum DOMErrorName { NetworkError = DOMExceptionConstants::NETWORK_ERR, AbortError = DOMExceptionConstants::ABORT_ERR, URLMismatchError = DOMExceptionConstants::URL_MISMATCH_ERR, + TypeMismatchError = DOMExceptionConstants::TYPE_MISMATCH_ERR, QuotaExceededError = DOMExceptionConstants::QUOTA_EXCEEDED_ERR, TimeoutError = DOMExceptionConstants::TIMEOUT_ERR, InvalidNodeTypeError = DOMExceptionConstants::INVALID_NODE_TYPE_ERR, @@ -93,6 +94,7 @@ impl<'a> DOMExceptionMethods for &'a DOMException { DOMErrorName::NetworkError => "A network error occurred.", DOMErrorName::AbortError => "The operation was aborted.", DOMErrorName::URLMismatchError => "The given URL does not match another URL.", + DOMErrorName::TypeMismatchError => "The given type does not match any expected type.", DOMErrorName::QuotaExceededError => "The quota has been exceeded.", DOMErrorName::TimeoutError => "The operation timed out.", DOMErrorName::InvalidNodeTypeError => diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 466aced53d7..88695f8cc04 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -197,6 +197,7 @@ pub mod closeevent; pub mod comment; pub mod console; mod create; +pub mod crypto; pub mod customevent; pub mod dedicatedworkerglobalscope; pub mod document; diff --git a/components/script/dom/webidls/Crypto.webidl b/components/script/dom/webidls/Crypto.webidl new file mode 100644 index 00000000000..032fce382bb --- /dev/null +++ b/components/script/dom/webidls/Crypto.webidl @@ -0,0 +1,25 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#crypto-interface + * + */ + +[NoInterfaceObject] +interface GlobalCrypto { + readonly attribute Crypto crypto; +}; + +Window implements GlobalCrypto; +WorkerGlobalScope implements GlobalCrypto; + +//[Exposed=(Window,Worker)] +interface Crypto { + //readonly attribute SubtleCrypto subtle; + //ArrayBufferView getRandomValues(ArrayBufferView array); + [Throws] + ArrayBufferView getRandomValues(object array); +}; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 43fd7429832..fa9c988a30c 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -19,6 +19,7 @@ use dom::bindings::num::Finite; use dom::bindings::utils::{GlobalStaticData, Reflectable, WindowProxyHandler}; use dom::browsercontext::BrowserContext; use dom::console::Console; +use dom::crypto::Crypto; use dom::document::{Document, DocumentHelpers}; use dom::element::Element; use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; @@ -100,6 +101,7 @@ pub struct Window { script_chan: Box<ScriptChan+Send>, control_chan: ScriptControlChan, console: MutNullableHeap<JS<Console>>, + crypto: MutNullableHeap<JS<Crypto>>, navigator: MutNullableHeap<JS<Navigator>>, image_cache_task: ImageCacheTask, image_cache_chan: ImageCacheChan, @@ -360,6 +362,10 @@ impl<'a> WindowMethods for &'a Window { self.console.or_init(|| Console::new(GlobalRef::Window(self))) } + fn Crypto(self) -> Root<Crypto> { + self.crypto.or_init(|| Crypto::new(GlobalRef::Window(self))) + } + // https://html.spec.whatwg.org/#dom-frameelement fn GetFrameElement(self) -> Option<Root<Element>> { // FIXME(https://github.com/rust-lang/rust/issues/23338) @@ -981,6 +987,7 @@ impl Window { image_cache_chan: image_cache_chan, control_chan: control_chan, console: Default::default(), + crypto: Default::default(), compositor: DOMRefCell::new(compositor), page: page, navigator: Default::default(), diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index bf654a36819..3039a7cbde4 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -11,6 +11,7 @@ use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, Root, MutNullableHeap}; use dom::bindings::utils::Reflectable; use dom::console::Console; +use dom::crypto::Crypto; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScopeHelpers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::workerlocation::WorkerLocation; @@ -49,6 +50,7 @@ pub struct WorkerGlobalScope { location: MutNullableHeap<JS<WorkerLocation>>, navigator: MutNullableHeap<JS<WorkerNavigator>>, console: MutNullableHeap<JS<Console>>, + crypto: MutNullableHeap<JS<Crypto>>, timers: TimerManager, devtools_chan: Option<DevtoolsControlChan>, } @@ -68,6 +70,7 @@ impl WorkerGlobalScope { location: Default::default(), navigator: Default::default(), console: Default::default(), + crypto: Default::default(), timers: TimerManager::new(), devtools_chan: devtools_chan, } @@ -157,6 +160,10 @@ impl<'a> WorkerGlobalScopeMethods for &'a WorkerGlobalScope { self.console.or_init(|| Console::new(GlobalRef::Worker(self))) } + fn Crypto(self) -> Root<Crypto> { + self.crypto.or_init(|| Crypto::new(GlobalRef::Worker(self))) + } + fn Btoa(self, btoa: DOMString) -> Fallible<DOMString> { base64_btoa(btoa) } diff --git a/components/script/lib.rs b/components/script/lib.rs index 642efd54650..c1cdc1c02f6 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -53,6 +53,7 @@ extern crate rustc_serialize; extern crate time; extern crate canvas; extern crate canvas_traits; +extern crate rand; extern crate profile_traits; extern crate script_traits; extern crate selectors; |