Skip to content

Commit d8491f3

Browse files
committed
ujson: back out overeager loads() change; only change load()
1 parent eb3d5fa commit d8491f3

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

extmod/modujson.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
9494
return s->cur;
9595
}
9696

97-
STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
97+
STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
9898
const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ);
9999
ujson_stream_t s = {stream_obj, stream_p->read, 0, 0};
100100
JSON_DEBUG("got JSON stream\n");
@@ -107,15 +107,6 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
107107
mp_obj_type_t *stack_top_type = NULL;
108108
mp_obj_t stack_key = MP_OBJ_NULL;
109109
S_NEXT(s);
110-
// Eat _leading_ whitespace.
111-
// If we eat trailing whitespace we will block for timeout on streams like UART that
112-
// wait for requested data. Furthermore, it is an OSError to read(1) and incur
113-
// a timeout on those APIs.
114-
// For these reasons, we must only eat _leading_ whitespace.
115-
while (unichar_isspace(S_CUR(s))) {
116-
JSON_DEBUG("Eating leading whitespace");
117-
S_NEXT(s);
118-
}
119110
for (;;) {
120111
cont:
121112
if (S_END(s)) {
@@ -277,9 +268,19 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
277268
}
278269
}
279270
success:
280-
// It is legal for a stream to have contents before and after JSON.
281-
// If this parser has consumed a full successful JSON and its parse
282-
// stack is empty, the parse has succeeded.
271+
// It is legal for a stream to have contents after JSON.
272+
// E.g., A UART is not closed after receiving an object; in load() we will
273+
// return the first complete JSON object, while in loads() we will retain
274+
// strict adherence to the buffer's complete semantic.
275+
if (!return_first_json) {
276+
while (unichar_isspace(S_CUR(s))) {
277+
S_NEXT(s);
278+
}
279+
if (!S_END(s)) {
280+
// unexpected chars
281+
goto fail;
282+
}
283+
}
283284
if (stack_top == MP_OBJ_NULL || stack.len != 0) {
284285
// not exactly 1 object
285286
goto fail;
@@ -290,14 +291,18 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
290291
fail:
291292
mp_raise_ValueError(translate("syntax error in JSON"));
292293
}
294+
295+
STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
296+
return _mod_ujson_load(stream_obj, true);
297+
}
293298
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
294299

295300
STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
296301
size_t len;
297302
const char *buf = mp_obj_str_get_data(obj, &len);
298303
vstr_t vstr = {len, len, (char*)buf, true};
299304
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
300-
return mod_ujson_load(MP_OBJ_FROM_PTR(&sio));
305+
return _mod_ujson_load(MP_OBJ_FROM_PTR(&sio), false);
301306
}
302307
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads);
303308

0 commit comments

Comments
 (0)