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();
|
return self.IsFunctionTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t v8__TypedArray__kMaxLength() { return v8::TypedArray::kMaxLength; }
|
||||||
|
|
||||||
bool v8__Value__IsUndefined(const v8::Value& self) {
|
bool v8__Value__IsUndefined(const v8::Value& self) {
|
||||||
return self.IsUndefined();
|
return self.IsUndefined();
|
||||||
}
|
}
|
||||||
@ -849,6 +851,8 @@ int v8__Name__GetIdentityHash(const v8::Name& self) {
|
|||||||
return ptr_to_local(&self)->GetIdentityHash();
|
return ptr_to_local(&self)->GetIdentityHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t v8__String__kMaxLength() { return v8::String::kMaxLength; }
|
||||||
|
|
||||||
const v8::String* v8__String__Empty(v8::Isolate* isolate) {
|
const v8::String* v8__String__Empty(v8::Isolate* isolate) {
|
||||||
return local_to_ptr(v8::String::Empty(isolate));
|
return local_to_ptr(v8::String::Empty(isolate));
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ use crate::Local;
|
|||||||
use crate::String;
|
use crate::String;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
fn v8__String__kMaxLength() -> libc::size_t;
|
||||||
|
|
||||||
fn v8__String__Empty(isolate: *mut Isolate) -> *const String;
|
fn v8__String__Empty(isolate: *mut Isolate) -> *const String;
|
||||||
|
|
||||||
fn v8__String__NewFromUtf8(
|
fn v8__String__NewFromUtf8(
|
||||||
@ -115,6 +117,13 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl String {
|
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> {
|
pub fn empty<'s>(scope: &mut HandleScope<'s, ()>) -> Local<'s, String> {
|
||||||
// FIXME(bnoordhuis) v8__String__Empty() is infallible so there
|
// FIXME(bnoordhuis) v8__String__Empty() is infallible so there
|
||||||
// is no need to box up the result, only to unwrap it again.
|
// is no need to box up the result, only to unwrap it again.
|
||||||
|
@ -2,6 +2,20 @@
|
|||||||
use crate::ArrayBuffer;
|
use crate::ArrayBuffer;
|
||||||
use crate::HandleScope;
|
use crate::HandleScope;
|
||||||
use crate::Local;
|
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 {
|
macro_rules! typed_array {
|
||||||
($name:ident, $func:ident) => {
|
($name:ident, $func:ident) => {
|
||||||
|
@ -236,6 +236,31 @@ fn test_string() {
|
|||||||
assert_eq!(4, local.utf8_length(scope));
|
assert_eq!(4, local.utf8_length(scope));
|
||||||
assert_eq!("🦕", local.to_rust_string_lossy(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]
|
#[test]
|
||||||
@ -3113,6 +3138,31 @@ fn typed_array_constructors() {
|
|||||||
|
|
||||||
let t = v8::BigInt64Array::new(scope, ab, 0, 0).unwrap();
|
let t = v8::BigInt64Array::new(scope, ab, 0, 0).unwrap();
|
||||||
assert!(t.is_big_int64_array());
|
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]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user