diff --git a/core/json/mod.rs b/core/json/mod.rs index d3b1f4e19..077c9dc93 100644 --- a/core/json/mod.rs +++ b/core/json/mod.rs @@ -116,10 +116,12 @@ pub fn convert_dbtype_to_jsonb(val: &Value, strict: Conv) -> crate::Result crate::Result { - let str = std::str::from_utf8(slice) +fn parse_as_json_text(slice: &[u8], mode: Conv) -> crate::Result { + let zero_pos = slice.iter().position(|&b| b == 0).unwrap_or(slice.len()); + let truncated = &slice[..zero_pos]; + let str = std::str::from_utf8(truncated) .map_err(|_| LimboError::ParseError("malformed JSON".to_string()))?; - Jsonb::from_str_with_mode(str, Conv::Strict).map_err(Into::into) + Jsonb::from_str_with_mode(str, mode).map_err(Into::into) } pub fn convert_ref_dbtype_to_jsonb(val: ValueRef<'_>, strict: Conv) -> crate::Result { @@ -147,14 +149,14 @@ pub fn convert_ref_dbtype_to_jsonb(val: ValueRef<'_>, strict: Conv) -> crate::Re let slice = &bytes[index..]; let json = match slice { // branch with no overlapping initial byte - [b'"', ..] | [b'-', ..] | [b'0'..=b'2', ..] => parse_as_json_text(slice)?, + [b'"', ..] | [b'-', ..] | [b'0'..=b'2', ..] => parse_as_json_text(slice, strict)?, _ => match JsonbHeader::from_slice(0, slice) { Ok((header, header_offset)) => { let payload_size = header.payload_size(); let total_expected = header_offset + payload_size; if total_expected != slice.len() { - parse_as_json_text(slice)? + parse_as_json_text(slice, strict)? } else { let jsonb = Jsonb::from_raw_data(slice); let is_valid_json = if payload_size <= 7 { @@ -165,11 +167,11 @@ pub fn convert_ref_dbtype_to_jsonb(val: ValueRef<'_>, strict: Conv) -> crate::Re if is_valid_json { jsonb } else { - parse_as_json_text(slice)? + parse_as_json_text(slice, strict)? } } } - Err(_) => parse_as_json_text(slice)?, + Err(_) => parse_as_json_text(slice, strict)?, }, }; json.element_type()?; diff --git a/testing/json.test b/testing/json.test index dbb6c37e0..32f793376 100755 --- a/testing/json.test +++ b/testing/json.test @@ -634,6 +634,10 @@ do_execsql_test json_type_null_arg { select json_type(null) } {{}} +do_execsql_test json_type_blob_with_trailing_bytes { + select json_type(x'7B2261223A317D00FF') +} {{object}} + do_execsql_test json_error_position_valid { SELECT json_error_position('{"a":55,"b":72,}'); } {{0}} @@ -739,6 +743,10 @@ do_execsql_test json_valid_8 { do_execsql_test json_valid_9 { SELECT json_valid(NULL); } {} + +do_execsql_test json_valid_blob_embedded_null { + SELECT json_valid(x'7B226100223A317D'); +} {0} do_execsql_test json-patch-basic-1 { select json_patch('{"a":1}', '{"b":2}'); } {{{"a":1,"b":2}}} @@ -1773,4 +1781,3 @@ do_execsql_test json-tree-nested-object { {$.a[1]|2} {$.a[2]|3} } -