summaryrefslogtreecommitdiff
path: root/ext/web/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/web/lib.rs')
-rw-r--r--ext/web/lib.rs34
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],