Use SmartString for buffers and literal_syntax can panic.

This commit is contained in:
Stephen Chung
2022-11-22 23:30:43 +08:00
parent 05c7d00a8e
commit d911327242
16 changed files with 225 additions and 174 deletions

View File

@@ -317,7 +317,7 @@ impl Engine {
scope: &mut Scope,
this_ptr: &mut Dynamic,
expr: &Expr,
new_val: &mut Option<(Dynamic, &OpAssignment)>,
new_val: Option<(Dynamic, &OpAssignment)>,
) -> RhaiResult {
let chain_type = ChainType::from(expr);
@@ -507,7 +507,7 @@ impl Engine {
target: &mut Target,
rhs: &Expr,
idx_values: &mut FnArgsVec<Dynamic>,
new_val: &mut Option<(Dynamic, &OpAssignment)>,
new_val: Option<(Dynamic, &OpAssignment)>,
) -> RhaiResultOf<(Dynamic, bool)> {
let is_ref_mut = target.is_ref();
let op_pos = parent.position();
@@ -576,7 +576,7 @@ impl Engine {
#[cfg(feature = "debugging")]
self.run_debugger(global, caches, scope, this_ptr, parent)?;
let (new_val, op_info) = new_val.take().expect("`Some`");
let (new_val, op_info) = new_val.expect("`Some`");
let idx_val = &mut idx_values.pop().unwrap();
let idx = &mut idx_val.clone();
@@ -686,12 +686,12 @@ impl Engine {
unreachable!("function call in dot chain should not be namespace-qualified")
}
// {xxx:map}.id op= ???
Expr::Property(x, pos) if target.is_map() && new_val.is_some() => {
Expr::Property(x, pos) if new_val.is_some() && target.is_map() => {
#[cfg(feature = "debugging")]
self.run_debugger(global, caches, scope, this_ptr, rhs)?;
let index = &mut x.2.clone().into();
let (new_val, op_info) = new_val.take().expect("`Some`");
let (new_val, op_info) = new_val.expect("`Some`");
{
let val_target = &mut self.get_indexed_mut(
global, caches, target, index, *pos, op_pos, true, false,
@@ -720,7 +720,7 @@ impl Engine {
self.run_debugger(global, caches, scope, this_ptr, rhs)?;
let ((getter, hash_get), (setter, hash_set), name) = &**x;
let (mut new_val, op_info) = new_val.take().expect("`Some`");
let (mut new_val, op_info) = new_val.expect("`Some`");
if op_info.is_op_assignment() {
let args = &mut [target.as_mut()];

View File

@@ -8,7 +8,7 @@ use std::borrow::Borrow;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
impl Engine {
impl Dynamic {
/// Recursively calculate the sizes of a value.
///
/// Sizes returned are `(` [`Array`][crate::Array], [`Map`][crate::Map] and [`String`] `)`.
@@ -16,20 +16,20 @@ impl Engine {
/// # Panics
///
/// Panics if any interior data is shared (should never happen).
pub(crate) fn calc_data_sizes(value: &Dynamic, _top: bool) -> (usize, usize, usize) {
match value.0 {
pub(crate) fn calc_data_sizes(&self, _top: bool) -> (usize, usize, usize) {
match self.0 {
#[cfg(not(feature = "no_index"))]
Union::Array(ref arr, ..) => {
arr.iter()
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
Union::Array(..) => {
let (a, m, s) = Self::calc_data_sizes(value, false);
let (a, m, s) = value.calc_data_sizes(false);
(ax + a + 1, mx + m, sx + s)
}
Union::Blob(ref a, ..) => (ax + 1 + a.len(), mx, sx),
#[cfg(not(feature = "no_object"))]
Union::Map(..) => {
let (a, m, s) = Self::calc_data_sizes(value, false);
let (a, m, s) = value.calc_data_sizes(false);
(ax + a + 1, mx + m, sx + s)
}
Union::Str(ref s, ..) => (ax + 1, mx, sx + s.len()),
@@ -44,13 +44,13 @@ impl Engine {
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
#[cfg(not(feature = "no_index"))]
Union::Array(..) => {
let (a, m, s) = Self::calc_data_sizes(value, false);
let (a, m, s) = value.calc_data_sizes(false);
(ax + a, mx + m + 1, sx + s)
}
#[cfg(not(feature = "no_index"))]
Union::Blob(ref a, ..) => (ax + a.len(), mx, sx),
Union::Map(..) => {
let (a, m, s) = Self::calc_data_sizes(value, false);
let (a, m, s) = value.calc_data_sizes(false);
(ax + a, mx + m + 1, sx + s)
}
Union::Str(ref s, ..) => (ax, mx + 1, sx + s.len()),
@@ -59,17 +59,17 @@ impl Engine {
}
Union::Str(ref s, ..) => (0, 0, s.len()),
#[cfg(not(feature = "no_closure"))]
Union::Shared(..) if _top => {
Self::calc_data_sizes(&*value.read_lock::<Dynamic>().unwrap(), true)
}
Union::Shared(..) if _top => self.read_lock::<Dynamic>().unwrap().calc_data_sizes(true),
#[cfg(not(feature = "no_closure"))]
Union::Shared(..) => {
unreachable!("shared values discovered within data: {}", value)
unreachable!("shared values discovered within data: {}", self)
}
_ => (0, 0, 0),
}
}
}
impl Engine {
/// Raise an error if any data size exceeds limit.
///
/// [`Position`] in [`EvalAltResult`][crate::EvalAltResult] is always [`NONE`][Position::NONE]
@@ -125,7 +125,7 @@ impl Engine {
return Ok(value);
}
let sizes = Self::calc_data_sizes(value.borrow(), true);
let sizes = value.borrow().calc_data_sizes(true);
self.raise_err_if_over_data_size_limit(sizes)
.map(|_| value)

View File

@@ -307,7 +307,7 @@ impl Engine {
#[cfg(not(feature = "unchecked"))]
if self.has_data_size_limit() {
let val_sizes = Self::calc_data_sizes(&value, true);
let val_sizes = value.calc_data_sizes(true);
total_data_sizes = (
total_data_sizes.0 + val_sizes.0,
@@ -339,7 +339,7 @@ impl Engine {
#[cfg(not(feature = "unchecked"))]
if self.has_data_size_limit() {
let delta = Self::calc_data_sizes(&value, true);
let delta = value.calc_data_sizes(true);
total_data_sizes = (
total_data_sizes.0 + delta.0,
total_data_sizes.1 + delta.1,
@@ -411,13 +411,11 @@ impl Engine {
#[cfg(not(feature = "no_index"))]
Expr::Index(..) => {
self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, &mut None)
self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, None)
}
#[cfg(not(feature = "no_object"))]
Expr::Dot(..) => {
self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, &mut None)
}
Expr::Dot(..) => self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, None),
_ => unreachable!("expression cannot be evaluated: {:?}", expr),
}

View File

@@ -21,7 +21,9 @@ pub use eval_context::EvalContext;
#[cfg(not(feature = "no_function"))]
pub use global_state::GlobalConstants;
pub use global_state::GlobalRuntimeState;
pub use target::{calc_index, calc_offset_len, Target};
#[cfg(not(feature = "no_index"))]
pub use target::calc_offset_len;
pub use target::{calc_index, Target};
#[cfg(feature = "unchecked")]
mod unchecked {

View File

@@ -258,7 +258,7 @@ impl Engine {
rhs_val = self.get_interned_string(value).into();
}
let _new_val = &mut Some((rhs_val, op_info));
let _new_val = Some((rhs_val, op_info));
// Must be either `var[index] op= val` or `var.prop op= val`
match lhs {

View File

@@ -13,8 +13,8 @@ use std::{
/// Negative starting positions count from the end.
///
/// Values going over bounds are limited to the actual length.
#[cfg(not(feature = "no_index"))]
#[inline]
#[allow(dead_code)]
pub fn calc_offset_len(length: usize, start: crate::INT, len: crate::INT) -> (usize, usize) {
let start = if start < 0 {
let abs_start = start.unsigned_abs();