Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/llvm_backend/src/jit.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,8 +5,8 @@
#![cfg(feature = "llvm")]

use llvm_sys::core::*;
use llvm_sys::orc2::*;
use llvm_sys::orc2::lljit::*;
use llvm_sys::orc2::*;
use std::collections::HashMap;
use std::ffi::CString;
use std::ptr;
Expand DownExpand Up@@ -60,7 +60,7 @@ impl LLVMJitEngine {

// 3. Set host target triple
let _host_triple = LLVMOrcLLJITGetExecutionSession(self.jit); // session triple fallback
// We can just keep the default LLVM target triple
// We can just keep the default LLVM target triple

// 4. Wrap Module in ThreadSafeModule
let tsm = LLVMOrcCreateNewThreadSafeModule(ctx.module, self.ts_ctx);
Expand Down
39 changes: 25 additions & 14 deletions stdlib/src/json.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,7 +39,7 @@ impl StdlibRegistry {
None,
)
})?;
Ok(parse_json_value(v))
parse_json_value(v, 0)
},
}),
);
Expand DownExpand Up@@ -92,36 +92,47 @@ pub fn stringify_value(val: &RuntimeValue) -> Result<String, RuntimeError> {
}
}

pub fn parse_json_value(v: serde_json::Value) -> RuntimeValue {
pub fn parse_json_value(v: serde_json::Value, depth: usize) -> Result<RuntimeValue, RuntimeError> {
if depth > 128 {
return Err(RuntimeError::new(
RuntimeErrorKind::InvalidOperation("JSON depth limit exceeded".to_string()),
None,
None,
));
}

match v {
serde_json::Value::Null => RuntimeValue::Null,
serde_json::Value::Bool(b) => RuntimeValue::Bool(b),
serde_json::Value::Null => Ok(RuntimeValue::Null),
serde_json::Value::Bool(b) => Ok(RuntimeValue::Bool(b)),
serde_json::Value::Number(num) => {
if let Some(i) = num.as_i64() {
RuntimeValue::Int(i)
Ok(RuntimeValue::Int(i))
} else if let Some(f) = num.as_f64() {
RuntimeValue::Float(f)
Ok(RuntimeValue::Float(f))
} else {
RuntimeValue::Null
Ok(RuntimeValue::Null)
}
}
serde_json::Value::String(s) => RuntimeValue::Str(s),
serde_json::Value::String(s) => Ok(RuntimeValue::Str(s)),
serde_json::Value::Array(arr) => {
let items = arr.into_iter().map(parse_json_value).collect::<Vec<_>>();
RuntimeValue::List {
let mut items = Vec::new();
for item in arr {
items.push(parse_json_value(item, depth + 1)?);
}
Ok(RuntimeValue::List {
items: Rc::new(RefCell::new(items)),
is_const: false,
}
})
}
serde_json::Value::Object(obj) => {
let mut entries = IndexMap::new();
for (k, v) in obj {
entries.insert(k, parse_json_value(v));
entries.insert(k, parse_json_value(v, depth + 1)?);
}
RuntimeValue::Map {
Ok(RuntimeValue::Map {
entries: Rc::new(RefCell::new(entries)),
is_const: false,
}
})
}
}
}
19 changes: 19 additions & 0 deletions stdlib/tests/stdlib_tests.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -186,6 +186,25 @@ fn test_json_module() {
} else {
panic!("JSON parse result was not a Map");
}

// Test depth limit
let mut nested_json_str = String::new();
for _ in 0..200 {
nested_json_str.push_str("{\"nested\":");
}
nested_json_str.push_str("null");
for _ in 0..200 {
nested_json_str.push('}');
}

let result = parse.call(&mut ctx, vec![RuntimeValue::Str(nested_json_str)]);
assert!(result.is_err());
if let Err(e) = result {
assert!(
e.message.contains("JSON depth limit exceeded")
|| e.message.contains("JSON parse error")
);
}
}

#[test]
Expand Down
Loading