mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-22 04:40:01 +00:00
feat: add bindings for String::kMaxLength and TypedArray::kMaxLength (#904)
This commit is contained in:
parent
fe447c88df
commit
2404d208f5
@ -457,6 +457,8 @@ bool v8__Data__IsFunctionTemplate(const v8::Data& self) {
|
||||
return self.IsFunctionTemplate();
|
||||
}
|
||||
|
||||
size_t v8__TypedArray__kMaxLength() { return v8::TypedArray::kMaxLength; }
|
||||
|
||||
bool v8__Value__IsUndefined(const v8::Value& self) {
|
||||
return self.IsUndefined();
|
||||
}
|
||||
@ -849,6 +851,8 @@ int v8__Name__GetIdentityHash(const v8::Name& self) {
|
||||
return ptr_to_local(&self)->GetIdentityHash();
|
||||
}
|
||||
|
||||
size_t v8__String__kMaxLength() { return v8::String::kMaxLength; }
|
||||
|
||||
const v8::String* v8__String__Empty(v8::Isolate* isolate) {
|
||||
return local_to_ptr(v8::String::Empty(isolate));
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ use crate::Local;
|
||||
use crate::String;
|
||||
|
||||
extern "C" {
|
||||
fn v8__String__kMaxLength() -> libc::size_t;
|
||||
|
||||
fn v8__String__Empty(isolate: *mut Isolate) -> *const String;
|
||||
|
||||
fn v8__String__NewFromUtf8(
|
||||
@ -115,6 +117,13 @@ bitflags! {
|
||||
}
|
||||
|
||||
impl String {
|
||||
/// The maximum length (in bytes) of a buffer that a v8::String can be built
|
||||
/// from. Attempting to create a v8::String from a larger buffer will result
|
||||
/// in None being returned.
|
||||
pub fn max_length() -> usize {
|
||||
unsafe { v8__String__kMaxLength() }
|
||||
}
|
||||
|
||||
pub fn empty<'s>(scope: &mut HandleScope<'s, ()>) -> Local<'s, String> {
|
||||
// FIXME(bnoordhuis) v8__String__Empty() is infallible so there
|
||||
// is no need to box up the result, only to unwrap it again.
|
||||
|
@ -2,6 +2,20 @@
|
||||
use crate::ArrayBuffer;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::TypedArray;
|
||||
|
||||
extern "C" {
|
||||
fn v8__TypedArray__kMaxLength() -> libc::size_t;
|
||||
}
|
||||
|
||||
impl TypedArray {
|
||||
/// The maximum length (in bytes) of the buffer backing a v8::TypedArray
|
||||
/// instance. Attempting to create a v8::ArrayBuffer from a larger buffer will
|
||||
/// result in a fatal error.
|
||||
pub fn max_length() -> usize {
|
||||
unsafe { v8__TypedArray__kMaxLength() }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! typed_array {
|
||||
($name:ident, $func:ident) => {
|
||||
|
@ -236,6 +236,31 @@ fn test_string() {
|
||||
assert_eq!(4, local.utf8_length(scope));
|
||||
assert_eq!("🦕", local.to_rust_string_lossy(scope));
|
||||
}
|
||||
{
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let buffer = (0..v8::String::max_length() / 4)
|
||||
.map(|_| '\u{10348}') // UTF8: 0xF0 0x90 0x8D 0x88
|
||||
.collect::<String>();
|
||||
let local = v8::String::new_from_utf8(
|
||||
scope,
|
||||
buffer.as_bytes(),
|
||||
v8::NewStringType::Normal,
|
||||
)
|
||||
.unwrap();
|
||||
// U+10348 is 2 UTF-16 code units, which is the unit of v8::String.length().
|
||||
assert_eq!(v8::String::max_length() / 2, local.length());
|
||||
assert_eq!(buffer, local.to_rust_string_lossy(scope));
|
||||
|
||||
let too_long = (0..(v8::String::max_length() / 4) + 1)
|
||||
.map(|_| '\u{10348}') // UTF8: 0xF0 0x90 0x8D 0x88
|
||||
.collect::<String>();
|
||||
let none = v8::String::new_from_utf8(
|
||||
scope,
|
||||
too_long.as_bytes(),
|
||||
v8::NewStringType::Normal,
|
||||
);
|
||||
assert!(none.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -3113,6 +3138,31 @@ fn typed_array_constructors() {
|
||||
|
||||
let t = v8::BigInt64Array::new(scope, ab, 0, 0).unwrap();
|
||||
assert!(t.is_big_int64_array());
|
||||
|
||||
// TypedArray::max_length() ought to be >= 2^30 < 2^32
|
||||
assert!(((2 << 30)..(2 << 32)).contains(&v8::TypedArray::max_length()));
|
||||
|
||||
// v8::ArrayBuffer::new raises a fatal if the length is > kMaxLength, so we test this behavior
|
||||
// through the JS side of things, where a non-fatal RangeError is thrown in such cases.
|
||||
{
|
||||
let scope = &mut v8::TryCatch::new(scope);
|
||||
let _ = eval(
|
||||
scope,
|
||||
&format!("new Uint8Array({})", v8::TypedArray::max_length()),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!scope.has_caught());
|
||||
}
|
||||
|
||||
{
|
||||
let scope = &mut v8::TryCatch::new(scope);
|
||||
eval(
|
||||
scope,
|
||||
&format!("new Uint8Array({})", v8::TypedArray::max_length() + 1),
|
||||
);
|
||||
// Array is too big (> max_length) - expecting this threw a RangeError
|
||||
assert!(scope.has_caught());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user