Skip to content

Commit

Permalink
Fix a bug where throw_(type,internal,..etc) would feed into printf
Browse files Browse the repository at this point in the history
  • Loading branch information
DelSkayn committed Jan 15, 2024
1 parent efeda6e commit b1813b4
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 35 deletions.
4 changes: 2 additions & 2 deletions core/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ mod symbol;
pub use array::Array;
pub use atom::Atom;
pub use bigint::BigInt;
pub use convert::{Coerced, FromAtom, FromIteratorJs, FromJs, IntoAtom, IntoJs, IteratorJs};
pub use convert::{FromAtom, FromIteratorJs, FromJs, IntoAtom, IntoJs, IteratorJs};
pub use exception::Exception;
pub use function::{Constructor, Function};
pub use module::Module;
pub use object::{Filter, Object};
pub use object::Object;
pub use string::String;
pub use symbol::Symbol;

Expand Down
83 changes: 50 additions & 33 deletions core/src/value/exception.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{error::Error as ErrorTrait, fmt};
use std::{error::Error as ErrorTrait, ffi::CStr, fmt, usize};

use crate::{atom::PredefinedAtom, convert::Coerced, qjs, Ctx, Error, Object, Result, Value};

Expand All @@ -23,6 +23,19 @@ impl fmt::Debug for Exception<'_> {
}
}

static ERROR_FORMAT_STR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked("%s\0".as_bytes()) };

fn truncate_str(mut max: usize, bytes: &[u8]) -> &[u8] {
if bytes.len() <= max {
return bytes;
}
// while the byte at len is a continue byte shorten the byte.
while (bytes[max] & 0b1100_0000) == 0b1000_0000 {
max -= 1;
}
&bytes[..max]
}

impl<'js> Exception<'js> {
/// Turns the exception into the underlying object.
pub fn into_object(self) -> Object<'js> {
Expand Down Expand Up @@ -156,11 +169,15 @@ impl<'js> Exception<'js> {
// QuickJS implementation doesn't allow error strings longer then 256 anyway so truncating
// here is fine.
let mut buffer = std::mem::MaybeUninit::<[u8; 256]>::uninit();
let str_len = message.as_bytes().len().min(255);
let str = truncate_str(255, message.as_bytes());
unsafe {
std::ptr::copy_nonoverlapping(message.as_ptr(), buffer.as_mut_ptr().cast(), str_len);
buffer.as_mut_ptr().cast::<u8>().add(str_len).write(b'\0');
let res = qjs::JS_ThrowSyntaxError(ctx.as_ptr(), buffer.as_ptr().cast());
std::ptr::copy_nonoverlapping(message.as_ptr(), buffer.as_mut_ptr().cast(), str.len());
buffer.as_mut_ptr().cast::<u8>().add(str.len()).write(b'\0');
let res = qjs::JS_ThrowSyntaxError(
ctx.as_ptr(),
ERROR_FORMAT_STR.as_ptr(),
buffer.as_ptr().cast::<*mut u8>(),
);
debug_assert_eq!(qjs::JS_VALUE_GET_NORM_TAG(res), qjs::JS_TAG_EXCEPTION);
}
Error::Exception
Expand All @@ -172,15 +189,15 @@ impl<'js> Exception<'js> {
// QuickJS implementation doesn't allow error strings longer then 256 anyway so truncating
// here is fine.
let mut buffer = std::mem::MaybeUninit::<[u8; 256]>::uninit();
let str_len = message.as_bytes().len().min(255);
let str = truncate_str(255, message.as_bytes());
unsafe {
std::ptr::copy_nonoverlapping(
message.as_ptr(),
buffer.as_mut_ptr().cast::<u8>(),
str_len,
std::ptr::copy_nonoverlapping(message.as_ptr(), buffer.as_mut_ptr().cast(), str.len());
buffer.as_mut_ptr().cast::<u8>().add(str.len()).write(b'\0');
let res = qjs::JS_ThrowTypeError(
ctx.as_ptr(),
ERROR_FORMAT_STR.as_ptr(),
buffer.as_ptr().cast::<*mut u8>(),
);
buffer.as_mut_ptr().cast::<u8>().add(str_len).write(b'\0');
let res = qjs::JS_ThrowTypeError(ctx.as_ptr(), buffer.as_ptr().cast());
debug_assert_eq!(qjs::JS_VALUE_GET_NORM_TAG(res), qjs::JS_TAG_EXCEPTION);
}
Error::Exception
Expand All @@ -192,15 +209,15 @@ impl<'js> Exception<'js> {
// QuickJS implementation doesn't allow error strings longer then 256 anyway so truncating
// here is fine.
let mut buffer = std::mem::MaybeUninit::<[u8; 256]>::uninit();
let str_len = message.as_bytes().len().min(255);
let str = truncate_str(255, message.as_bytes());
unsafe {
std::ptr::copy_nonoverlapping(
message.as_ptr(),
buffer.as_mut_ptr().cast::<u8>(),
str_len,
std::ptr::copy_nonoverlapping(message.as_ptr(), buffer.as_mut_ptr().cast(), str.len());
buffer.as_mut_ptr().cast::<u8>().add(str.len()).write(b'\0');
let res = qjs::JS_ThrowReferenceError(
ctx.as_ptr(),
ERROR_FORMAT_STR.as_ptr(),
buffer.as_ptr().cast::<*mut u8>(),
);
buffer.as_mut_ptr().cast::<u8>().add(str_len).write(b'\0');
let res = qjs::JS_ThrowReferenceError(ctx.as_ptr(), buffer.as_ptr().cast());
debug_assert_eq!(qjs::JS_VALUE_GET_NORM_TAG(res), qjs::JS_TAG_EXCEPTION);
}
Error::Exception
Expand All @@ -212,15 +229,15 @@ impl<'js> Exception<'js> {
// QuickJS implementation doesn't allow error strings longer then 256 anyway so truncating
// here is fine.
let mut buffer = std::mem::MaybeUninit::<[u8; 256]>::uninit();
let str_len = message.as_bytes().len().min(255);
let str = truncate_str(255, message.as_bytes());
unsafe {
std::ptr::copy_nonoverlapping(
message.as_ptr(),
buffer.as_mut_ptr().cast::<u8>(),
str_len,
std::ptr::copy_nonoverlapping(message.as_ptr(), buffer.as_mut_ptr().cast(), str.len());
buffer.as_mut_ptr().cast::<u8>().add(str.len()).write(b'\0');
let res = qjs::JS_ThrowRangeError(
ctx.as_ptr(),
ERROR_FORMAT_STR.as_ptr(),
buffer.as_ptr().cast::<*mut u8>(),
);
buffer.as_mut_ptr().cast::<u8>().add(str_len).write(b'\0');
let res = qjs::JS_ThrowRangeError(ctx.as_ptr(), buffer.as_ptr().cast());
debug_assert_eq!(qjs::JS_VALUE_GET_NORM_TAG(res), qjs::JS_TAG_EXCEPTION);
}
Error::Exception
Expand All @@ -232,15 +249,15 @@ impl<'js> Exception<'js> {
// QuickJS implementation doesn't allow error strings longer then 256 anyway so truncating
// here is fine.
let mut buffer = std::mem::MaybeUninit::<[u8; 256]>::uninit();
let str_len = message.as_bytes().len().min(255);
let str = truncate_str(255, message.as_bytes());
unsafe {
std::ptr::copy_nonoverlapping(
message.as_ptr(),
buffer.as_mut_ptr().cast::<u8>(),
str_len,
std::ptr::copy_nonoverlapping(message.as_ptr(), buffer.as_mut_ptr().cast(), str.len());
buffer.as_mut_ptr().cast::<u8>().add(str.len()).write(b'\0');
let res = qjs::JS_ThrowInternalError(
ctx.as_ptr(),
ERROR_FORMAT_STR.as_ptr(),
buffer.as_ptr().cast::<*mut u8>(),
);
buffer.as_mut_ptr().cast::<u8>().add(str_len).write(b'\0');
let res = qjs::JS_ThrowInternalError(ctx.as_ptr(), buffer.as_ptr().cast());
debug_assert_eq!(qjs::JS_VALUE_GET_NORM_TAG(res), qjs::JS_TAG_EXCEPTION);
}
Error::Exception
Expand Down

0 comments on commit b1813b4

Please sign in to comment.