From 97e2bf75dff2b2bfb0c2ec5a88f6b830db833dd8 Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Sun, 11 Oct 2020 17:59:11 -0700 Subject: [PATCH 1/6] Make json_is_valid consider max recursion depth --- src/json.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/src/json.rs b/src/json.rs index 702c2494..ad53647a 100644 --- a/src/json.rs +++ b/src/json.rs @@ -1,7 +1,72 @@ +use serde_json::Value; +use std::cmp; + +const VALID_JSON_MAX_RECURSION_DEPTH: usize = 5; + byond_fn! { json_is_valid(text) { - Some( - serde_json::from_str::(text) + Some( + serde_json::from_str::(text) .is_ok() .to_string(), ) } } + +/// Gets the recursion level of the given value +/// If it is above VALID_JSON_MAX_RECURSION_DEPTH, returns Err(()) +fn get_recursion_level(value: &Value) -> Result { + let values: Vec<&Value> = match value { + Value::Array(array) => array.iter().collect(), + + Value::Object(map) => map.values().collect(), + + _ => return Ok(0), + }; + + let mut max_recursion_level = 0; + + for value in values { + max_recursion_level = cmp::max(max_recursion_level, get_recursion_level(value)?); + } + + if max_recursion_level >= VALID_JSON_MAX_RECURSION_DEPTH { + Err(()) + } else { + Ok(max_recursion_level + 1) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_recursion_level() { + assert_eq!( + get_recursion_level(&serde_json::from_str("[]").unwrap()), + Ok(1) + ); + assert_eq!( + get_recursion_level(&serde_json::from_str("[[]]").unwrap()), + Ok(2) + ); + assert_eq!( + get_recursion_level(&serde_json::from_str("[[[]]]").unwrap()), + Ok(3) + ); + } + + #[test] + fn test_get_recursion_level_max_depth() { + assert_eq!( + get_recursion_level( + &serde_json::from_str(&format!( + "{}{}", + "[".repeat(VALID_JSON_MAX_RECURSION_DEPTH), + "]".repeat(VALID_JSON_MAX_RECURSION_DEPTH) + )) + .unwrap() + ), + Err(()) + ); + } +} From 7a269c7a59d0ca5502d5e07f633dee8631cdd30d Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Sun, 11 Oct 2020 18:03:35 -0700 Subject: [PATCH 2/6] 5 -> 8 --- src/json.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/json.rs b/src/json.rs index ad53647a..f7f09013 100644 --- a/src/json.rs +++ b/src/json.rs @@ -1,7 +1,7 @@ use serde_json::Value; use std::cmp; -const VALID_JSON_MAX_RECURSION_DEPTH: usize = 5; +const VALID_JSON_MAX_RECURSION_DEPTH: usize = 8; byond_fn! { json_is_valid(text) { Some( From 153980a256f767d19d82868900a0af09007f4c43 Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Sun, 11 Oct 2020 18:06:24 -0700 Subject: [PATCH 3/6] Make json_is_valid use get_recursion_level --- src/json.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/json.rs b/src/json.rs index f7f09013..9a0beacd 100644 --- a/src/json.rs +++ b/src/json.rs @@ -4,11 +4,12 @@ use std::cmp; const VALID_JSON_MAX_RECURSION_DEPTH: usize = 8; byond_fn! { json_is_valid(text) { - Some( - serde_json::from_str::(text) - .is_ok() - .to_string(), - ) + let value = match serde_json::from_str::(text) { + Ok(value) => value, + Err(_) => return "false" + }; + + get_recursion_level(value).is_ok().to_string() } } /// Gets the recursion level of the given value From f03c9df770574c85bc7f6dac09b6b92f69d4622c Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Sun, 11 Oct 2020 18:07:47 -0700 Subject: [PATCH 4/6] Check true value --- build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.rs b/build.rs index f627eac2..f5888ddb 100644 --- a/build.rs +++ b/build.rs @@ -128,7 +128,7 @@ fn main() { write!( f, r#" -#define rustg_json_is_valid(text) call(RUST_G, "json_is_valid")(text) +#define rustg_json_is_valid(text) (call(RUST_G, "json_is_valid")(text) == "true") "# ) .unwrap(); From a8492224bef202f20d015fd1d29787b7b2b352ec Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Sun, 11 Oct 2020 18:09:04 -0700 Subject: [PATCH 5/6] Compiles --- src/json.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/json.rs b/src/json.rs index 9a0beacd..83f26808 100644 --- a/src/json.rs +++ b/src/json.rs @@ -6,10 +6,10 @@ const VALID_JSON_MAX_RECURSION_DEPTH: usize = 8; byond_fn! { json_is_valid(text) { let value = match serde_json::from_str::(text) { Ok(value) => value, - Err(_) => return "false" + Err(_) => return Some("false".to_owned()) }; - get_recursion_level(value).is_ok().to_string() + Some(get_recursion_level(&value).is_ok().to_string()) } } /// Gets the recursion level of the given value From e453ee9c83f0768ae65f03765ccb3a6d739dcf93 Mon Sep 17 00:00:00 2001 From: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> Date: Sun, 11 Oct 2020 19:06:12 -0700 Subject: [PATCH 6/6] Move +1 --- src/json.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/json.rs b/src/json.rs index 83f26808..2185e9d6 100644 --- a/src/json.rs +++ b/src/json.rs @@ -29,10 +29,12 @@ fn get_recursion_level(value: &Value) -> Result { max_recursion_level = cmp::max(max_recursion_level, get_recursion_level(value)?); } + max_recursion_level += 1; + if max_recursion_level >= VALID_JSON_MAX_RECURSION_DEPTH { Err(()) } else { - Ok(max_recursion_level + 1) + Ok(max_recursion_level) } }