py/objdict: Quote non-string types when used as keys in JSON output.

JSON requires that keys of objects be strings.  CPython will therefore
automatically quote simple types (NoneType, bool, int, float) when they are
used directly as keys in JSON output.  To prevent subtle bugs and emit
compliant JSON, MicroPython should at least test for such keys so they
aren't silently let through.  Then doing the actual quoting is a similar
cost to raising an exception, so that's what is implemented by this patch.

Fixes issue #4790.
pull/4946/head
Eric Poulsen 2019-07-16 14:29:22 -07:00 zatwierdzone przez Damien George
rodzic 8f55a8fab6
commit 01054f2092
3 zmienionych plików z 13 dodań i 0 usunięć

Wyświetl plik

@ -31,6 +31,7 @@
#include "py/runtime.h"
#include "py/builtin.h"
#include "py/objtype.h"
#include "py/objstr.h"
#define mp_obj_is_dict_type(o) (mp_obj_is_obj(o) && ((mp_obj_base_t*)MP_OBJ_TO_PTR(o))->type->make_new == dict_make_new)
@ -70,7 +71,14 @@ STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_
mp_print_str(print, ", ");
}
first = false;
bool add_quote = MICROPY_PY_UJSON && kind == PRINT_JSON && !mp_obj_is_str_or_bytes(next->key);
if (add_quote) {
mp_print_str(print, "\"");
}
mp_obj_print_helper(print, next->key, kind);
if (add_quote) {
mp_print_str(print, "\"");
}
mp_print_str(print, ": ");
mp_obj_print_helper(print, next->value, kind);
}

Wyświetl plik

@ -26,3 +26,7 @@ print(json.dumps({"a":1}))
print(json.dumps({"a":(2,[3,None])}))
print(json.dumps('"quoted"'))
print(json.dumps('space\n\r\tspace'))
print(json.dumps({None: -1}))
print(json.dumps({False: 0}))
print(json.dumps({True: 1}))
print(json.dumps({1: 2}))

Wyświetl plik

@ -8,3 +8,4 @@ except ImportError:
raise SystemExit
print(json.dumps(1.2))
print(json.dumps({1.5: 'hi'}))