Repository: servo/servo
File: components/script/dom/crypto.rs (Rust)

Code before:
use crate::dom::subtlecrypto::SubtleCrypto;
use crate::script_runtime::{CanGc, JSContext};

// https://developer.mozilla.org/en-US/docs/Web/API/Crypto
#[dom_struct]
pub(crate) struct Crypto {
    reflector_: Reflector,
    subtle: MutNullableDom<SubtleCrypto>,
}

impl Crypto {
    fn new_inherited() -> Crypto {
        Crypto {
            reflector_: Reflector::new(),
            subtle: MutNullableDom::default(),
        }
    }

    pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<Crypto> {
        reflect_dom_object(Box::new(Crypto::new_inherited()), global, can_gc)
    }
}

impl CryptoMethods<crate::DomTypeHolder> for Crypto {
    /// <https://w3c.github.io/webcrypto/#dfn-Crypto-attribute-subtle>
    fn Subtle(&self, can_gc: CanGc) -> DomRoot<SubtleCrypto> {
        self.subtle
            .or_init(|| SubtleCrypto::new(&self.global(), can_gc))
    }

    #[expect(unsafe_code)]
    /// <https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues>
    fn GetRandomValues(
        &self,
        _cx: JSContext,
        mut input: CustomAutoRooterGuard<ArrayBufferView>,
    ) -> Fallible<RootedTraceableBox<HeapArrayBufferView>> {
        let array_type = input.get_array_type();

        if !is_integer_buffer(array_type) {
            Err(Error::TypeMismatch(None))
        } else {
            let data = unsafe { input.as_mut_slice() };
            if data.len() > 65536 {
                return Err(Error::QuotaExceeded {
                    quota: None,
                    requested: None,
                });
            }

            if OsRng.try_fill_bytes(data).is_err() {

Review comment (suggestion):
I would import `js::context::JSContext` at the top of the file:

```suggestion
    fn Subtle(&self, cx: &mut JSContext) -> DomRoot<SubtleCrypto> {
```

Code after:
use crate::dom::subtlecrypto::SubtleCrypto;
use crate::script_runtime::{CanGc, JSContext};

// https://developer.mozilla.org/en-US/docs/Web/API/Crypto
#[dom_struct]
pub(crate) struct Crypto {
    reflector_: Reflector,
    subtle: MutNullableDom<SubtleCrypto>,
}

impl Crypto {
    fn new_inherited() -> Crypto {
        Crypto {
            reflector_: Reflector::new(),
            subtle: MutNullableDom::default(),
        }
    }

    pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<Crypto> {
        reflect_dom_object(Box::new(Crypto::new_inherited()), global, can_gc)
    }
}

impl CryptoMethods<crate::DomTypeHolder> for Crypto {
    /// <https://w3c.github.io/webcrypto/#dfn-Crypto-attribute-subtle>
    fn Subtle(&self, cx: &mut js::context::JSContext) -> DomRoot<SubtleCrypto> {
        self.subtle
            .or_init(|| SubtleCrypto::new(cx, &self.global()))
    }

    #[expect(unsafe_code)]
    /// <https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues>
    fn GetRandomValues(
        &self,
        _cx: JSContext,
        mut input: CustomAutoRooterGuard<ArrayBufferView>,
    ) -> Fallible<RootedTraceableBox<HeapArrayBufferView>> {
        let array_type = input.get_array_type();

        if !is_integer_buffer(array_type) {
            Err(Error::TypeMismatch(None))
        } else {
            let data = unsafe { input.as_mut_slice() };
            if data.len() > 65536 {
                return Err(Error::QuotaExceeded {
                    quota: None,
                    requested: None,
                });
            }

            if OsRng.try_fill_bytes(data).is_err() {