mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
fix(ext/ffi): Check CStr for UTF-8 validity on read (#15318)
Co-authored-by: Phosra <phosra@tutanota.com>
This commit is contained in:
parent
6e6912489c
commit
569910856e
3 changed files with 39 additions and 7 deletions
|
@ -2187,13 +2187,14 @@ where
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
// SAFETY: Pointer is user provided.
|
// SAFETY: Pointer is user provided.
|
||||||
let cstr = unsafe { CStr::from_ptr(ptr as *const c_char) }.to_bytes();
|
let cstr = unsafe { CStr::from_ptr(ptr as *const c_char) }
|
||||||
let value: v8::Local<v8::Value> =
|
.to_str()
|
||||||
v8::String::new_from_utf8(scope, cstr, v8::NewStringType::Normal)
|
.map_err(|_| type_error("Invalid CString pointer, not valid UTF-8"))?;
|
||||||
.ok_or_else(|| {
|
let value: v8::Local<v8::Value> = v8::String::new(scope, cstr)
|
||||||
type_error("Invalid CString pointer, string exceeds max length")
|
.ok_or_else(|| {
|
||||||
})?
|
type_error("Invalid CString pointer, string exceeds max length")
|
||||||
.into();
|
})?
|
||||||
|
.into();
|
||||||
Ok(value.into())
|
Ok(value.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -411,3 +411,10 @@ static STRING: &str = "Hello, world!\0";
|
||||||
extern "C" fn ffi_string() -> *const u8 {
|
extern "C" fn ffi_string() -> *const u8 {
|
||||||
STRING.as_ptr()
|
STRING.as_ptr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Invalid UTF-8 characters, array of length 14
|
||||||
|
#[no_mangle]
|
||||||
|
pub static static_char: [u8; 14] = [
|
||||||
|
0xC0, 0xC1, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||||
|
0x00,
|
||||||
|
];
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
// Run using cargo test or `--v8-options=--allow-natives-syntax`
|
// Run using cargo test or `--v8-options=--allow-natives-syntax`
|
||||||
|
|
||||||
|
import { assertEquals } from "https://deno.land/std@0.149.0/testing/asserts.ts";
|
||||||
import {
|
import {
|
||||||
assertThrows,
|
assertThrows,
|
||||||
} from "../../test_util/std/testing/asserts.ts";
|
} from "../../test_util/std/testing/asserts.ts";
|
||||||
|
@ -186,6 +187,12 @@ const dylib = Deno.dlopen(libPath, {
|
||||||
"static_ptr": {
|
"static_ptr": {
|
||||||
type: "pointer",
|
type: "pointer",
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Invalid UTF-8 characters, buffer of length 14
|
||||||
|
*/
|
||||||
|
"static_char": {
|
||||||
|
type: "pointer",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const { symbols } = dylib;
|
const { symbols } = dylib;
|
||||||
|
|
||||||
|
@ -478,6 +485,23 @@ uint32Array[0] = 55; // MUTATES!
|
||||||
console.log("uint32Array[0] after mutation:", uint32Array[0]);
|
console.log("uint32Array[0] after mutation:", uint32Array[0]);
|
||||||
console.log("Static ptr value after mutation:", view.getUint32());
|
console.log("Static ptr value after mutation:", view.getUint32());
|
||||||
|
|
||||||
|
// Test non-UTF-8 characters
|
||||||
|
|
||||||
|
const charView = new Deno.UnsafePointerView(dylib.symbols.static_char);
|
||||||
|
|
||||||
|
const charArrayBuffer = charView.getArrayBuffer(14);
|
||||||
|
const uint8Array = new Uint8Array(charArrayBuffer);
|
||||||
|
assertEquals([...uint8Array], [
|
||||||
|
0xC0, 0xC1, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
(function cleanup() {
|
(function cleanup() {
|
||||||
dylib.close();
|
dylib.close();
|
||||||
throwCallback.close();
|
throwCallback.close();
|
||||||
|
|
Loading…
Reference in a new issue