Skip to content

Commit 622cd7b

Browse files
akxijl
authored andcommitted
Add special casing for deserializing empty objects, lists and strings
1 parent 5da14a0 commit 622cd7b

2 files changed

Lines changed: 23 additions & 7 deletions

File tree

src/deserialize/deserializer.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
22

33
use crate::deserialize::cache::*;
4-
use crate::deserialize::utf8::read_input_to_str;
4+
use crate::deserialize::utf8::{read_buf_to_str, read_input_to_buf};
55
use crate::deserialize::DeserializeError;
66
use crate::typeref::*;
77
use crate::unicode::*;
@@ -14,7 +14,19 @@ use std::ptr::NonNull;
1414
pub fn deserialize(
1515
ptr: *mut pyo3::ffi::PyObject,
1616
) -> Result<NonNull<pyo3::ffi::PyObject>, DeserializeError<'static>> {
17-
let buffer_str = read_input_to_str(ptr)?;
17+
let buffer = read_input_to_buf(ptr)?;
18+
if unlikely!(buffer.len() == 2) {
19+
if buffer == b"[]" {
20+
return Ok(nonnull!(ffi!(PyList_New(0))));
21+
} else if buffer == b"{}" {
22+
return Ok(nonnull!(ffi!(PyDict_New())));
23+
} else if buffer == b"\"\"" {
24+
ffi!(Py_INCREF(EMPTY_UNICODE));
25+
unsafe { return Ok(nonnull!(EMPTY_UNICODE)) }
26+
}
27+
}
28+
let buffer_str = read_buf_to_str(buffer)?;
29+
1830
let mut deserializer = serde_json::Deserializer::from_str(buffer_str);
1931
let seed = JsonValue {};
2032
match seed.deserialize(&mut deserializer) {

src/deserialize/utf8.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ fn is_valid_utf8(buf: &[u8]) -> bool {
3131
std::str::from_utf8(buf).is_ok()
3232
}
3333

34-
pub fn read_input_to_str(
34+
pub fn read_input_to_buf(
3535
ptr: *mut pyo3::ffi::PyObject,
36-
) -> Result<&'static str, DeserializeError<'static>> {
36+
) -> Result<&'static [u8], DeserializeError<'static>> {
3737
let obj_type_ptr = ob_type!(ptr);
3838
let contents: &[u8];
3939
if is_type!(obj_type_ptr, STR_TYPE) {
@@ -73,9 +73,13 @@ pub fn read_input_to_str(
7373
));
7474
}
7575
contents = unsafe { std::slice::from_raw_parts(buffer, length) };
76-
if !is_valid_utf8(contents) {
77-
return Err(DeserializeError::new(Cow::Borrowed(INVALID_STR), 0, 0, ""));
78-
}
76+
}
77+
Ok(contents)
78+
}
79+
80+
pub fn read_buf_to_str(contents: &[u8]) -> Result<&str, DeserializeError> {
81+
if !is_valid_utf8(contents) {
82+
return Err(DeserializeError::new(Cow::Borrowed(INVALID_STR), 0, 0, ""));
7983
}
8084
Ok(unsafe { std::str::from_utf8_unchecked(contents) })
8185
}

0 commit comments

Comments
 (0)