Skip to content

Commit

Permalink
fix: handle fractional numbers properly (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulkr authored Jun 14, 2024
1 parent 5751cd6 commit 37f1cc0
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
3 changes: 2 additions & 1 deletion js-sandbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[package]
name = "js-sandbox-ios"
version = "0.1.0"
version = "0.1.1"
description = "Execute JavaScript code from Rust in a secure sandbox, and transport data to/from JS plug-ins."
repository = "https://github.com/Bromeon/js-sandbox"
documentation = "https://docs.rs/js-sandbox/0.2.0-rc.1"
Expand All @@ -16,3 +16,4 @@ js-sandbox-macros = { path = "../js-sandbox-macros", version = "=0.2.0-rc.1" }
deno_core = "0.238.0"
serde_json = "1.0.106"
serde = { version = "1.0.188", features = ["derive"] }
tracing = "0.1.40"
55 changes: 54 additions & 1 deletion js-sandbox/src/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,66 @@ impl Script {
};
let deserialized_value = serde_v8::from_v8::<serde_json::Value>(scope, func_res)
.with_context(|| "Could not serialize func res")?;
let result: CallResult<R> = serde_json::from_value(deserialized_value)?;
let sanitized_value = Self::sanitize_number(deserialized_value)?;
let result: CallResult<R> = serde_json::from_value(sanitized_value)?;
match result {
CallResult::Error { error } => Err(JsError::Runtime(AnyError::msg(error))),
CallResult::Result(r) => Ok(r),
}
}

fn sanitize_number(value: serde_json::Value) -> Result<serde_json::Value, JsError> {
match value {
serde_json::Value::Number(number) => {
if number.is_f64() {
let f = number.as_f64().ok_or_else(|| {
JsError::Runtime(AnyError::msg("Failed to convert number to f64"))
})?;

if f.fract() == 0.0 {
return Ok(serde_json::Value::Number(serde_json::Number::from(
f as i64,
)));
}

Ok(serde_json::Value::Number(
serde_json::Number::from_f64(f).ok_or_else(|| {
JsError::Runtime(AnyError::msg("Failed to convert f64 to number"))
})?,
))
} else if number.is_u64() {
Ok(serde_json::Value::Number(
number
.as_i64()
.ok_or_else(|| {
JsError::Runtime(AnyError::msg("Failed to convert number to i64"))
})?
.into(),
))
} else if number.is_i64() {
Ok(serde_json::Value::Number(number))
} else {
Err(JsError::Runtime(AnyError::msg("Failed to convert number")))
}
}
serde_json::Value::Object(map) => {
let mut new_map = serde_json::Map::new();
for (key, value) in map {
new_map.insert(key, Self::sanitize_number(value)?);
}
Ok(serde_json::Value::Object(new_map))
}
serde_json::Value::Array(vec) => {
let mut new_vec = Vec::new();
for value in vec {
new_vec.push(Self::sanitize_number(value)?);
}
Ok(serde_json::Value::Array(new_vec))
}
_ => Ok(value),
}
}

pub fn bind_api<'a, A>(&'a mut self) -> A
where
A: JsApi<'a>,
Expand Down

0 comments on commit 37f1cc0

Please sign in to comment.