Skip to content

Commit

Permalink
fix(ext/ffi): Check CStr for UTF-8 validity on read (#15318)
Browse files Browse the repository at this point in the history
Co-authored-by: Phosra <[email protected]>
  • Loading branch information
aapoalas and Phosra committed Aug 5, 2022
1 parent 6e69124 commit 5699108
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
15 changes: 8 additions & 7 deletions ext/ffi/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2187,13 +2187,14 @@ where
permissions.check(None)?;

// SAFETY: Pointer is user provided.
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();
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();
Ok(value.into())
}

Expand Down
7 changes: 7 additions & 0 deletions test_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,10 @@ static STRING: &str = "Hello, world!\0";
extern "C" fn ffi_string() -> *const u8 {
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,
];
24 changes: 24 additions & 0 deletions test_ffi/tests/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

// Run using cargo test or `--v8-options=--allow-natives-syntax`

import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import {
assertThrows,
} from "../../test_util/std/testing/asserts.ts";
Expand Down Expand Up @@ -186,6 +187,12 @@ const dylib = Deno.dlopen(libPath, {
"static_ptr": {
type: "pointer",
},
/**
* Invalid UTF-8 characters, buffer of length 14
*/
"static_char": {
type: "pointer",
},
});
const { symbols } = dylib;

Expand Down Expand Up @@ -478,6 +485,23 @@ uint32Array[0] = 55; // MUTATES!
console.log("uint32Array[0] after mutation:", uint32Array[0]);
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() {
dylib.close();
throwCallback.close();
Expand Down

0 comments on commit 5699108

Please sign in to comment.