diff options
Diffstat (limited to 'ext/web/lib.rs')
-rw-r--r-- | ext/web/lib.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/ext/web/lib.rs b/ext/web/lib.rs index 588a3adfd..f799f02e7 100644 --- a/ext/web/lib.rs +++ b/ext/web/lib.rs @@ -91,6 +91,7 @@ pub fn init<P: TimersPermission + 'static>( op_base64_btoa::decl(), op_encoding_normalize_label::decl(), op_encoding_decode_single::decl(), + op_encoding_decode_utf8::decl(), op_encoding_new_decoder::decl(), op_encoding_decode::decl(), op_encoding_encode_into::decl(), @@ -179,6 +180,39 @@ fn op_encoding_normalize_label(label: String) -> Result<String, AnyError> { Ok(encoding.name().to_lowercase()) } +#[op(v8)] +fn op_encoding_decode_utf8<'a>( + scope: &mut v8::HandleScope<'a>, + zero_copy: &[u8], + ignore_bom: bool, +) -> Result<serde_v8::Value<'a>, AnyError> { + let buf = &zero_copy; + + let buf = if !ignore_bom + && buf.len() >= 3 + && buf[0] == 0xef + && buf[1] == 0xbb + && buf[2] == 0xbf + { + &buf[3..] + } else { + buf + }; + + // If `String::new_from_utf8()` returns `None`, this means that the + // length of the decoded string would be longer than what V8 can + // handle. In this case we return `RangeError`. + // + // For more details see: + // - https://encoding.spec.whatwg.org/#dom-textdecoder-decode + // - https://github.com/denoland/deno/issues/6649 + // - https://github.com/v8/v8/blob/d68fb4733e39525f9ff0a9222107c02c28096e2a/include/v8.h#L3277-L3278 + match v8::String::new_from_utf8(scope, buf, v8::NewStringType::Normal) { + Some(text) => Ok(serde_v8::from_v8(scope, text.into())?), + None => Err(type_error("buffer exceeds maximum length")), + } +} + #[op] fn op_encoding_decode_single( data: &[u8], |