summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAapo Alasuutari <aapo.alasuutari@gmail.com>2023-02-12 18:42:35 +0200
committerGitHub <noreply@github.com>2023-02-12 18:42:35 +0200
commit5a83af4837c016d89378f9fa982141b34ff30a23 (patch)
treea05c144ce5dd8d239bdb0dd60d4312466e370cf0
parentd4e5a295f2f9af1f815596656a185b11d7dabb29 (diff)
perf(ext/ffi): Revert UTF-8 validity check from getCString (#17741)
-rw-r--r--ext/ffi/repr.rs15
-rw-r--r--test_ffi/tests/test.js24
2 files changed, 27 insertions, 12 deletions
diff --git a/ext/ffi/repr.rs b/ext/ffi/repr.rs
index db03479dc..c21b2b0f1 100644
--- a/ext/ffi/repr.rs
+++ b/ext/ffi/repr.rs
@@ -145,14 +145,13 @@ where
let ptr = unsafe { ptr.add(offset) };
// SAFETY: Pointer is user provided.
- let cstr = unsafe { CStr::from_ptr(ptr as *const c_char) }
- .to_str()
- .map_err(|_| type_error("Invalid CString pointer, not valid UTF-8"))?;
- let value: v8::Local<v8::Value> = v8::String::new(scope, cstr)
- .ok_or_else(|| {
- type_error("Invalid CString pointer, string exceeds max length")
- })?
- .into();
+ let cstr = unsafe { CStr::from_ptr(ptr as *const c_char) }.to_bytes();
+ let value: v8::Local<v8::Value> =
+ v8::String::new_from_utf8(scope, cstr, v8::NewStringType::Normal)
+ .ok_or_else(|| {
+ type_error("Invalid CString pointer, string exceeds max length")
+ })?
+ .into();
Ok(value.into())
}
diff --git a/test_ffi/tests/test.js b/test_ffi/tests/test.js
index e45c5895b..15900e72c 100644
--- a/test_ffi/tests/test.js
+++ b/test_ffi/tests/test.js
@@ -699,10 +699,26 @@ assertEquals([...uint8Array], [
0x00
]);
-try {
- assertThrows(() => charView.getCString(), TypeError, "Invalid CString pointer, not valid UTF-8");
-} catch (_err) {
- console.log("Invalid UTF-8 characters to `v8::String`:", charView.getCString());
+// Check that `getCString` works equally to `TextDecoder`
+assertEquals(charView.getCString(), new TextDecoder().decode(uint8Array.subarray(0, uint8Array.length - 1)));
+
+// Check a selection of various invalid UTF-8 sequences in C strings and verify
+// that the `getCString` API does not cause unexpected behaviour.
+for (const charBuffer of [
+ Uint8Array.from([0xA0, 0xA1, 0x00]),
+ Uint8Array.from([0xE2, 0x28, 0xA1, 0x00]),
+ Uint8Array.from([0xE2, 0x82, 0x28, 0x00]),
+ Uint8Array.from([0xF0, 0x28, 0x8C, 0xBC, 0x00]),
+ Uint8Array.from([0xF0, 0x90, 0x28, 0xBC, 0x00]),
+ Uint8Array.from([0xF0, 0x28, 0x8C, 0x28, 0x00]),
+ Uint8Array.from([0xF8, 0xA1, 0xA1, 0xA1, 0xA1, 0x00]),
+ Uint8Array.from([0xFC, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0x00]),
+]) {
+ const charBufferPointer = Deno.UnsafePointer.of(charBuffer);
+ const charString = Deno.UnsafePointerView.getCString(charBufferPointer);
+ const charBufferPointerArrayBuffer = new Uint8Array(Deno.UnsafePointerView.getArrayBuffer(charBufferPointer, charBuffer.length - 1));
+ assertEquals(charString, new TextDecoder().decode(charBufferPointerArrayBuffer));
+ assertEquals([...charBuffer.subarray(0, charBuffer.length - 1)], [...charBufferPointerArrayBuffer]);
}