Branch data Line data Source code
1 : : /* JSON accelerator C extensor: _json module.
2 : : *
3 : : * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows
4 : : * and as an extension module (Py_BUILD_CORE_MODULE define) on other
5 : : * platforms. */
6 : :
7 : : #ifndef Py_BUILD_CORE_BUILTIN
8 : : # define Py_BUILD_CORE_MODULE 1
9 : : #endif
10 : : #define NEEDS_PY_IDENTIFIER
11 : :
12 : : #include "Python.h"
13 : : #include "pycore_ceval.h" // _Py_EnterRecursiveCall()
14 : : #include "structmember.h" // PyMemberDef
15 : : #include "pycore_accu.h"
16 : :
17 : :
18 : : typedef struct _PyScannerObject {
19 : : PyObject_HEAD
20 : : signed char strict;
21 : : PyObject *object_hook;
22 : : PyObject *object_pairs_hook;
23 : : PyObject *parse_float;
24 : : PyObject *parse_int;
25 : : PyObject *parse_constant;
26 : : PyObject *memo;
27 : : } PyScannerObject;
28 : :
29 : : static PyMemberDef scanner_members[] = {
30 : : {"strict", T_BOOL, offsetof(PyScannerObject, strict), READONLY, "strict"},
31 : : {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"},
32 : : {"object_pairs_hook", T_OBJECT, offsetof(PyScannerObject, object_pairs_hook), READONLY},
33 : : {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"},
34 : : {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"},
35 : : {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"},
36 : : {NULL}
37 : : };
38 : :
39 : : typedef struct _PyEncoderObject {
40 : : PyObject_HEAD
41 : : PyObject *markers;
42 : : PyObject *defaultfn;
43 : : PyObject *encoder;
44 : : PyObject *indent;
45 : : PyObject *key_separator;
46 : : PyObject *item_separator;
47 : : char sort_keys;
48 : : char skipkeys;
49 : : int allow_nan;
50 : : PyCFunction fast_encode;
51 : : } PyEncoderObject;
52 : :
53 : : static PyMemberDef encoder_members[] = {
54 : : {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"},
55 : : {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"},
56 : : {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"},
57 : : {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"},
58 : : {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"},
59 : : {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"},
60 : : {"sort_keys", T_BOOL, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"},
61 : : {"skipkeys", T_BOOL, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"},
62 : : {NULL}
63 : : };
64 : :
65 : : /* Forward decls */
66 : :
67 : : static PyObject *
68 : : ascii_escape_unicode(PyObject *pystr);
69 : : static PyObject *
70 : : py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr);
71 : : static PyObject *
72 : : scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr);
73 : : static PyObject *
74 : : _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
75 : : static PyObject *
76 : : scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
77 : : static void
78 : : scanner_dealloc(PyObject *self);
79 : : static int
80 : : scanner_clear(PyScannerObject *self);
81 : : static PyObject *
82 : : encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
83 : : static void
84 : : encoder_dealloc(PyObject *self);
85 : : static int
86 : : encoder_clear(PyEncoderObject *self);
87 : : static int
88 : : encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level);
89 : : static int
90 : : encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, PyObject *obj, Py_ssize_t indent_level);
91 : : static int
92 : : encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level);
93 : : static PyObject *
94 : : _encoded_const(PyObject *obj);
95 : : static void
96 : : raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end);
97 : : static PyObject *
98 : : encoder_encode_string(PyEncoderObject *s, PyObject *obj);
99 : : static PyObject *
100 : : encoder_encode_float(PyEncoderObject *s, PyObject *obj);
101 : :
102 : : #define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"')
103 : : #define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
104 : :
105 : : static Py_ssize_t
106 : 618 : ascii_escape_unichar(Py_UCS4 c, unsigned char *output, Py_ssize_t chars)
107 : : {
108 : : /* Escape unicode code point c to ASCII escape sequences
109 : : in char *output. output must have at least 12 bytes unused to
110 : : accommodate an escaped surrogate pair "\uXXXX\uXXXX" */
111 : 618 : output[chars++] = '\\';
112 [ + + + + : 618 : switch (c) {
+ + + + ]
113 : 5 : case '\\': output[chars++] = c; break;
114 : 18 : case '"': output[chars++] = c; break;
115 : 7 : case '\b': output[chars++] = 'b'; break;
116 : 5 : case '\f': output[chars++] = 'f'; break;
117 : 42 : case '\n': output[chars++] = 'n'; break;
118 : 5 : case '\r': output[chars++] = 'r'; break;
119 : 5 : case '\t': output[chars++] = 't'; break;
120 : 531 : default:
121 [ + + ]: 531 : if (c >= 0x10000) {
122 : : /* UTF-16 surrogate pair */
123 : 8 : Py_UCS4 v = Py_UNICODE_HIGH_SURROGATE(c);
124 : 8 : output[chars++] = 'u';
125 : 8 : output[chars++] = Py_hexdigits[(v >> 12) & 0xf];
126 : 8 : output[chars++] = Py_hexdigits[(v >> 8) & 0xf];
127 : 8 : output[chars++] = Py_hexdigits[(v >> 4) & 0xf];
128 : 8 : output[chars++] = Py_hexdigits[(v ) & 0xf];
129 : 8 : c = Py_UNICODE_LOW_SURROGATE(c);
130 : 8 : output[chars++] = '\\';
131 : : }
132 : 531 : output[chars++] = 'u';
133 : 531 : output[chars++] = Py_hexdigits[(c >> 12) & 0xf];
134 : 531 : output[chars++] = Py_hexdigits[(c >> 8) & 0xf];
135 : 531 : output[chars++] = Py_hexdigits[(c >> 4) & 0xf];
136 : 531 : output[chars++] = Py_hexdigits[(c ) & 0xf];
137 : : }
138 : 618 : return chars;
139 : : }
140 : :
141 : : static PyObject *
142 : 34033 : ascii_escape_unicode(PyObject *pystr)
143 : : {
144 : : /* Take a PyUnicode pystr and return a new ASCII-only escaped PyUnicode */
145 : : Py_ssize_t i;
146 : : Py_ssize_t input_chars;
147 : : Py_ssize_t output_size;
148 : : Py_ssize_t chars;
149 : : PyObject *rval;
150 : : const void *input;
151 : : Py_UCS1 *output;
152 : : int kind;
153 : :
154 [ - + ]: 34033 : if (PyUnicode_READY(pystr) == -1)
155 : 0 : return NULL;
156 : :
157 : 34033 : input_chars = PyUnicode_GET_LENGTH(pystr);
158 : 34033 : input = PyUnicode_DATA(pystr);
159 : 34033 : kind = PyUnicode_KIND(pystr);
160 : :
161 : : /* Compute the output size */
162 [ + + ]: 379033 : for (i = 0, output_size = 2; i < input_chars; i++) {
163 : 345000 : Py_UCS4 c = PyUnicode_READ(kind, input, i);
164 : : Py_ssize_t d;
165 [ + + + + : 345000 : if (S_CHAR(c)) {
+ + + + ]
166 : 344382 : d = 1;
167 : : }
168 : : else {
169 [ + + ]: 618 : switch(c) {
170 : 87 : case '\\': case '"': case '\b': case '\f':
171 : : case '\n': case '\r': case '\t':
172 : 87 : d = 2; break;
173 : 531 : default:
174 [ + + ]: 531 : d = c >= 0x10000 ? 12 : 6;
175 : : }
176 : : }
177 [ - + ]: 345000 : if (output_size > PY_SSIZE_T_MAX - d) {
178 : 0 : PyErr_SetString(PyExc_OverflowError, "string is too long to escape");
179 : 0 : return NULL;
180 : : }
181 : 345000 : output_size += d;
182 : : }
183 : :
184 : 34033 : rval = PyUnicode_New(output_size, 127);
185 [ - + ]: 34033 : if (rval == NULL) {
186 : 0 : return NULL;
187 : : }
188 : 34033 : output = PyUnicode_1BYTE_DATA(rval);
189 : 34033 : chars = 0;
190 : 34033 : output[chars++] = '"';
191 [ + + ]: 379033 : for (i = 0; i < input_chars; i++) {
192 : 345000 : Py_UCS4 c = PyUnicode_READ(kind, input, i);
193 [ + + + + : 345000 : if (S_CHAR(c)) {
+ + + + ]
194 : 344382 : output[chars++] = c;
195 : : }
196 : : else {
197 : 618 : chars = ascii_escape_unichar(c, output, chars);
198 : : }
199 : : }
200 : 34033 : output[chars++] = '"';
201 : : #ifdef Py_DEBUG
202 : : assert(_PyUnicode_CheckConsistency(rval, 1));
203 : : #endif
204 : 34033 : return rval;
205 : : }
206 : :
207 : : static PyObject *
208 : 5 : escape_unicode(PyObject *pystr)
209 : : {
210 : : /* Take a PyUnicode pystr and return a new escaped PyUnicode */
211 : : Py_ssize_t i;
212 : : Py_ssize_t input_chars;
213 : : Py_ssize_t output_size;
214 : : Py_ssize_t chars;
215 : : PyObject *rval;
216 : : const void *input;
217 : : int kind;
218 : : Py_UCS4 maxchar;
219 : :
220 [ - + ]: 5 : if (PyUnicode_READY(pystr) == -1)
221 : 0 : return NULL;
222 : :
223 : 5 : maxchar = PyUnicode_MAX_CHAR_VALUE(pystr);
224 : 5 : input_chars = PyUnicode_GET_LENGTH(pystr);
225 : 5 : input = PyUnicode_DATA(pystr);
226 : 5 : kind = PyUnicode_KIND(pystr);
227 : :
228 : : /* Compute the output size */
229 [ + + ]: 14 : for (i = 0, output_size = 2; i < input_chars; i++) {
230 : 9 : Py_UCS4 c = PyUnicode_READ(kind, input, i);
231 : : Py_ssize_t d;
232 [ - + ]: 9 : switch (c) {
233 : 0 : case '\\': case '"': case '\b': case '\f':
234 : : case '\n': case '\r': case '\t':
235 : 0 : d = 2;
236 : 0 : break;
237 : 9 : default:
238 [ - + ]: 9 : if (c <= 0x1f)
239 : 0 : d = 6;
240 : : else
241 : 9 : d = 1;
242 : : }
243 [ - + ]: 9 : if (output_size > PY_SSIZE_T_MAX - d) {
244 : 0 : PyErr_SetString(PyExc_OverflowError, "string is too long to escape");
245 : 0 : return NULL;
246 : : }
247 : 9 : output_size += d;
248 : : }
249 : :
250 : 5 : rval = PyUnicode_New(output_size, maxchar);
251 [ - + ]: 5 : if (rval == NULL)
252 : 0 : return NULL;
253 : :
254 : 5 : kind = PyUnicode_KIND(rval);
255 : :
256 : : #define ENCODE_OUTPUT do { \
257 : : chars = 0; \
258 : : output[chars++] = '"'; \
259 : : for (i = 0; i < input_chars; i++) { \
260 : : Py_UCS4 c = PyUnicode_READ(kind, input, i); \
261 : : switch (c) { \
262 : : case '\\': output[chars++] = '\\'; output[chars++] = c; break; \
263 : : case '"': output[chars++] = '\\'; output[chars++] = c; break; \
264 : : case '\b': output[chars++] = '\\'; output[chars++] = 'b'; break; \
265 : : case '\f': output[chars++] = '\\'; output[chars++] = 'f'; break; \
266 : : case '\n': output[chars++] = '\\'; output[chars++] = 'n'; break; \
267 : : case '\r': output[chars++] = '\\'; output[chars++] = 'r'; break; \
268 : : case '\t': output[chars++] = '\\'; output[chars++] = 't'; break; \
269 : : default: \
270 : : if (c <= 0x1f) { \
271 : : output[chars++] = '\\'; \
272 : : output[chars++] = 'u'; \
273 : : output[chars++] = '0'; \
274 : : output[chars++] = '0'; \
275 : : output[chars++] = Py_hexdigits[(c >> 4) & 0xf]; \
276 : : output[chars++] = Py_hexdigits[(c ) & 0xf]; \
277 : : } else { \
278 : : output[chars++] = c; \
279 : : } \
280 : : } \
281 : : } \
282 : : output[chars++] = '"'; \
283 : : } while (0)
284 : :
285 [ + + ]: 5 : if (kind == PyUnicode_1BYTE_KIND) {
286 : 1 : Py_UCS1 *output = PyUnicode_1BYTE_DATA(rval);
287 [ - - - - : 4 : ENCODE_OUTPUT;
- - - + -
+ + + ]
288 [ + + ]: 4 : } else if (kind == PyUnicode_2BYTE_KIND) {
289 : 2 : Py_UCS2 *output = PyUnicode_2BYTE_DATA(rval);
290 [ - - - - : 6 : ENCODE_OUTPUT;
- - - + -
+ + + ]
291 : : } else {
292 : 2 : Py_UCS4 *output = PyUnicode_4BYTE_DATA(rval);
293 : : assert(kind == PyUnicode_4BYTE_KIND);
294 [ - - - - : 4 : ENCODE_OUTPUT;
- - - + -
+ + + ]
295 : : }
296 : : #undef ENCODE_OUTPUT
297 : :
298 : : #ifdef Py_DEBUG
299 : : assert(_PyUnicode_CheckConsistency(rval, 1));
300 : : #endif
301 : 5 : return rval;
302 : : }
303 : :
304 : : static void
305 : 73 : raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end)
306 : : {
307 : : /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */
308 : : _Py_static_string(PyId_decoder, "json.decoder");
309 : 73 : PyObject *decoder = _PyImport_GetModuleId(&PyId_decoder);
310 [ - + ]: 73 : if (decoder == NULL) {
311 : 0 : return;
312 : : }
313 : :
314 : : _Py_IDENTIFIER(JSONDecodeError);
315 : 73 : PyObject *JSONDecodeError = _PyObject_GetAttrId(decoder, &PyId_JSONDecodeError);
316 : 73 : Py_DECREF(decoder);
317 [ - + ]: 73 : if (JSONDecodeError == NULL) {
318 : 0 : return;
319 : : }
320 : :
321 : : PyObject *exc;
322 : 73 : exc = PyObject_CallFunction(JSONDecodeError, "zOn", msg, s, end);
323 : 73 : Py_DECREF(JSONDecodeError);
324 [ + - ]: 73 : if (exc) {
325 : 73 : PyErr_SetObject(JSONDecodeError, exc);
326 : 73 : Py_DECREF(exc);
327 : : }
328 : : }
329 : :
330 : : static void
331 : 32 : raise_stop_iteration(Py_ssize_t idx)
332 : : {
333 : 32 : PyObject *value = PyLong_FromSsize_t(idx);
334 [ + - ]: 32 : if (value != NULL) {
335 : 32 : PyErr_SetObject(PyExc_StopIteration, value);
336 : 32 : Py_DECREF(value);
337 : : }
338 : 32 : }
339 : :
340 : : static PyObject *
341 : 56456 : _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) {
342 : : /* return (rval, idx) tuple, stealing reference to rval */
343 : : PyObject *tpl;
344 : : PyObject *pyidx;
345 : : /*
346 : : steal a reference to rval, returns (rval, idx)
347 : : */
348 [ + + ]: 56456 : if (rval == NULL) {
349 : 23 : return NULL;
350 : : }
351 : 56433 : pyidx = PyLong_FromSsize_t(idx);
352 [ - + ]: 56433 : if (pyidx == NULL) {
353 : 0 : Py_DECREF(rval);
354 : 0 : return NULL;
355 : : }
356 : 56433 : tpl = PyTuple_New(2);
357 [ - + ]: 56433 : if (tpl == NULL) {
358 : 0 : Py_DECREF(pyidx);
359 : 0 : Py_DECREF(rval);
360 : 0 : return NULL;
361 : : }
362 : 56433 : PyTuple_SET_ITEM(tpl, 0, rval);
363 : 56433 : PyTuple_SET_ITEM(tpl, 1, pyidx);
364 : 56433 : return tpl;
365 : : }
366 : :
367 : : static PyObject *
368 : 89640 : scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr)
369 : : {
370 : : /* Read the JSON string from PyUnicode pystr.
371 : : end is the index of the first character after the quote.
372 : : if strict is zero then literal control characters are allowed
373 : : *next_end_ptr is a return-by-reference index of the character
374 : : after the end quote
375 : :
376 : : Return value is a new PyUnicode
377 : : */
378 : 89640 : PyObject *rval = NULL;
379 : : Py_ssize_t len;
380 : 89640 : Py_ssize_t begin = end - 1;
381 : : Py_ssize_t next /* = begin */;
382 : : const void *buf;
383 : : int kind;
384 : :
385 [ - + ]: 89640 : if (PyUnicode_READY(pystr) == -1)
386 : 0 : return 0;
387 : :
388 : : _PyUnicodeWriter writer;
389 : 89640 : _PyUnicodeWriter_Init(&writer);
390 : 89640 : writer.overallocate = 1;
391 : :
392 : 89640 : len = PyUnicode_GET_LENGTH(pystr);
393 : 89640 : buf = PyUnicode_DATA(pystr);
394 : 89640 : kind = PyUnicode_KIND(pystr);
395 : :
396 [ + - + - ]: 89640 : if (end < 0 || len < end) {
397 : 0 : PyErr_SetString(PyExc_ValueError, "end is out of bounds");
398 : 0 : goto bail;
399 : : }
400 : 55928 : while (1) {
401 : : /* Find the end of the string or the next escape */
402 : : Py_UCS4 c;
403 : : {
404 : : // Use tight scope variable to help register allocation.
405 : 145568 : Py_UCS4 d = 0;
406 [ + + ]: 510640 : for (next = end; next < len; next++) {
407 : 510631 : d = PyUnicode_READ(kind, buf, next);
408 [ + + + + ]: 510631 : if (d == '"' || d == '\\') {
409 : : break;
410 : : }
411 [ + + + - ]: 365075 : if (d <= 0x1f && strict) {
412 : 3 : raise_errmsg("Invalid control character at", pystr, next);
413 : 3 : goto bail;
414 : : }
415 : : }
416 : 145565 : c = d;
417 : : }
418 : :
419 [ + + ]: 145565 : if (c == '"') {
420 : : // Fast path for simple case.
421 [ + + ]: 89602 : if (writer.buffer == NULL) {
422 : 33788 : PyObject *ret = PyUnicode_Substring(pystr, end, next);
423 [ - + ]: 33788 : if (ret == NULL) {
424 : 0 : goto bail;
425 : : }
426 : 33788 : *next_end_ptr = next + 1;;
427 : 33788 : return ret;
428 : : }
429 : : }
430 [ + + ]: 55963 : else if (c != '\\') {
431 : 9 : raise_errmsg("Unterminated string starting at", pystr, begin);
432 : 9 : goto bail;
433 : : }
434 : :
435 : : /* Pick up this chunk if it's not zero length */
436 [ + + ]: 111768 : if (next != end) {
437 [ - + ]: 562 : if (_PyUnicodeWriter_WriteSubstring(&writer, pystr, end, next) < 0) {
438 : 0 : goto bail;
439 : : }
440 : : }
441 : 111768 : next++;
442 [ + + ]: 111768 : if (c == '"') {
443 : 55814 : end = next;
444 : 55814 : break;
445 : : }
446 [ - + ]: 55954 : if (next == len) {
447 : 0 : raise_errmsg("Unterminated string starting at", pystr, begin);
448 : 0 : goto bail;
449 : : }
450 : 55954 : c = PyUnicode_READ(kind, buf, next);
451 [ + + ]: 55954 : if (c != 'u') {
452 : : /* Non-unicode backslash escapes */
453 : 100 : end = next + 1;
454 [ + + + + : 100 : switch (c) {
+ + + +
+ ]
455 : 24 : case '"': break;
456 : 4 : case '\\': break;
457 : 2 : case '/': break;
458 : 6 : case 'b': c = '\b'; break;
459 : 4 : case 'f': c = '\f'; break;
460 : 46 : case 'n': c = '\n'; break;
461 : 4 : case 'r': c = '\r'; break;
462 : 4 : case 't': c = '\t'; break;
463 : 6 : default: c = 0;
464 : : }
465 [ + + ]: 100 : if (c == 0) {
466 : 6 : raise_errmsg("Invalid \\escape", pystr, end - 2);
467 : 6 : goto bail;
468 : : }
469 : : }
470 : : else {
471 : 55854 : c = 0;
472 : 55854 : next++;
473 : 55854 : end = next + 4;
474 [ + + ]: 55854 : if (end >= len) {
475 : 8 : raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1);
476 : 8 : goto bail;
477 : : }
478 : : /* Decode 4 hex digits */
479 [ + + ]: 279214 : for (; next < end; next++) {
480 : 223374 : Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
481 : 223374 : c <<= 4;
482 [ + + + + ]: 223374 : switch (digit) {
483 : 146996 : case '0': case '1': case '2': case '3': case '4':
484 : : case '5': case '6': case '7': case '8': case '9':
485 : 146996 : c |= (digit - '0'); break;
486 : 76350 : case 'a': case 'b': case 'c': case 'd': case 'e':
487 : : case 'f':
488 : 76350 : c |= (digit - 'a' + 10); break;
489 : 22 : case 'A': case 'B': case 'C': case 'D': case 'E':
490 : : case 'F':
491 : 22 : c |= (digit - 'A' + 10); break;
492 : 6 : default:
493 : 6 : raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
494 : 6 : goto bail;
495 : : }
496 : : }
497 : : /* Surrogate pair */
498 [ + + + + : 55862 : if (Py_UNICODE_IS_HIGH_SURROGATE(c) && end + 6 < len &&
+ + ]
499 [ + - ]: 43 : PyUnicode_READ(kind, buf, next++) == '\\' &&
500 : 21 : PyUnicode_READ(kind, buf, next++) == 'u') {
501 : 21 : Py_UCS4 c2 = 0;
502 : 21 : end += 6;
503 : : /* Decode 4 hex digits */
504 [ + + ]: 89 : for (; next < end; next++) {
505 : 74 : Py_UCS4 digit = PyUnicode_READ(kind, buf, next);
506 : 74 : c2 <<= 4;
507 [ + + - + ]: 74 : switch (digit) {
508 : 36 : case '0': case '1': case '2': case '3': case '4':
509 : : case '5': case '6': case '7': case '8': case '9':
510 : 36 : c2 |= (digit - '0'); break;
511 : 32 : case 'a': case 'b': case 'c': case 'd': case 'e':
512 : : case 'f':
513 : 32 : c2 |= (digit - 'a' + 10); break;
514 : 0 : case 'A': case 'B': case 'C': case 'D': case 'E':
515 : : case 'F':
516 : 0 : c2 |= (digit - 'A' + 10); break;
517 : 6 : default:
518 : 6 : raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5);
519 : 6 : goto bail;
520 : : }
521 : : }
522 [ + + ]: 15 : if (Py_UNICODE_IS_LOW_SURROGATE(c2))
523 : 13 : c = Py_UNICODE_JOIN_SURROGATES(c, c2);
524 : : else
525 : 2 : end -= 6;
526 : : }
527 : : }
528 [ - + ]: 55928 : if (_PyUnicodeWriter_WriteChar(&writer, c) < 0) {
529 : 0 : goto bail;
530 : : }
531 : : }
532 : :
533 : 55814 : rval = _PyUnicodeWriter_Finish(&writer);
534 : 55814 : *next_end_ptr = end;
535 : 55814 : return rval;
536 : :
537 : 38 : bail:
538 : 38 : *next_end_ptr = -1;
539 : 38 : _PyUnicodeWriter_Dealloc(&writer);
540 : 38 : return NULL;
541 : : }
542 : :
543 : : PyDoc_STRVAR(pydoc_scanstring,
544 : : "scanstring(string, end, strict=True) -> (string, end)\n"
545 : : "\n"
546 : : "Scan the string s for a JSON string. End is the index of the\n"
547 : : "character in s after the quote that started the JSON string.\n"
548 : : "Unescapes all valid JSON string escape sequences and raises ValueError\n"
549 : : "on attempt to decode an invalid string. If strict is False then literal\n"
550 : : "control characters are allowed in the string.\n"
551 : : "\n"
552 : : "Returns a tuple of the decoded string and the index of the character in s\n"
553 : : "after the end quote."
554 : : );
555 : :
556 : : static PyObject *
557 : 53 : py_scanstring(PyObject* Py_UNUSED(self), PyObject *args)
558 : : {
559 : : PyObject *pystr;
560 : : PyObject *rval;
561 : : Py_ssize_t end;
562 : 53 : Py_ssize_t next_end = -1;
563 : 53 : int strict = 1;
564 [ + + ]: 53 : if (!PyArg_ParseTuple(args, "On|i:scanstring", &pystr, &end, &strict)) {
565 : 1 : return NULL;
566 : : }
567 [ + - ]: 52 : if (PyUnicode_Check(pystr)) {
568 : 52 : rval = scanstring_unicode(pystr, end, strict, &next_end);
569 : : }
570 : : else {
571 : 0 : PyErr_Format(PyExc_TypeError,
572 : : "first argument must be a string, not %.80s",
573 : 0 : Py_TYPE(pystr)->tp_name);
574 : 0 : return NULL;
575 : : }
576 : 52 : return _build_rval_index_tuple(rval, next_end);
577 : : }
578 : :
579 : : PyDoc_STRVAR(pydoc_encode_basestring_ascii,
580 : : "encode_basestring_ascii(string) -> string\n"
581 : : "\n"
582 : : "Return an ASCII-only JSON representation of a Python string"
583 : : );
584 : :
585 : : static PyObject *
586 : 34033 : py_encode_basestring_ascii(PyObject* Py_UNUSED(self), PyObject *pystr)
587 : : {
588 : : PyObject *rval;
589 : : /* Return an ASCII-only JSON representation of a Python string */
590 : : /* METH_O */
591 [ + - ]: 34033 : if (PyUnicode_Check(pystr)) {
592 : 34033 : rval = ascii_escape_unicode(pystr);
593 : : }
594 : : else {
595 : 0 : PyErr_Format(PyExc_TypeError,
596 : : "first argument must be a string, not %.80s",
597 : 0 : Py_TYPE(pystr)->tp_name);
598 : 0 : return NULL;
599 : : }
600 : 34033 : return rval;
601 : : }
602 : :
603 : :
604 : : PyDoc_STRVAR(pydoc_encode_basestring,
605 : : "encode_basestring(string) -> string\n"
606 : : "\n"
607 : : "Return a JSON representation of a Python string"
608 : : );
609 : :
610 : : static PyObject *
611 : 5 : py_encode_basestring(PyObject* Py_UNUSED(self), PyObject *pystr)
612 : : {
613 : : PyObject *rval;
614 : : /* Return a JSON representation of a Python string */
615 : : /* METH_O */
616 [ + - ]: 5 : if (PyUnicode_Check(pystr)) {
617 : 5 : rval = escape_unicode(pystr);
618 : : }
619 : : else {
620 : 0 : PyErr_Format(PyExc_TypeError,
621 : : "first argument must be a string, not %.80s",
622 : 0 : Py_TYPE(pystr)->tp_name);
623 : 0 : return NULL;
624 : : }
625 : 5 : return rval;
626 : : }
627 : :
628 : : static void
629 : 1038 : scanner_dealloc(PyObject *self)
630 : : {
631 : 1038 : PyTypeObject *tp = Py_TYPE(self);
632 : : /* bpo-31095: UnTrack is needed before calling any callbacks */
633 : 1038 : PyObject_GC_UnTrack(self);
634 : 1038 : scanner_clear((PyScannerObject *)self);
635 : 1038 : tp->tp_free(self);
636 : 1038 : Py_DECREF(tp);
637 : 1038 : }
638 : :
639 : : static int
640 : 30662 : scanner_traverse(PyScannerObject *self, visitproc visit, void *arg)
641 : : {
642 [ + - - + ]: 30662 : Py_VISIT(Py_TYPE(self));
643 [ + - - + ]: 30662 : Py_VISIT(self->object_hook);
644 [ + - - + ]: 30662 : Py_VISIT(self->object_pairs_hook);
645 [ + - - + ]: 30662 : Py_VISIT(self->parse_float);
646 [ + - - + ]: 30662 : Py_VISIT(self->parse_int);
647 [ + - - + ]: 30662 : Py_VISIT(self->parse_constant);
648 [ + - - + ]: 30662 : Py_VISIT(self->memo);
649 : 30662 : return 0;
650 : : }
651 : :
652 : : static int
653 : 1038 : scanner_clear(PyScannerObject *self)
654 : : {
655 [ + + ]: 1038 : Py_CLEAR(self->object_hook);
656 [ + + ]: 1038 : Py_CLEAR(self->object_pairs_hook);
657 [ + + ]: 1038 : Py_CLEAR(self->parse_float);
658 [ + + ]: 1038 : Py_CLEAR(self->parse_int);
659 [ + + ]: 1038 : Py_CLEAR(self->parse_constant);
660 [ + - ]: 1038 : Py_CLEAR(self->memo);
661 : 1038 : return 0;
662 : : }
663 : :
664 : : static PyObject *
665 : 1312 : _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
666 : : {
667 : : /* Read a JSON object from PyUnicode pystr.
668 : : idx is the index of the first character after the opening curly brace.
669 : : *next_idx_ptr is a return-by-reference index to the first character after
670 : : the closing curly brace.
671 : :
672 : : Returns a new PyObject (usually a dict, but object_hook can change that)
673 : : */
674 : : const void *str;
675 : : int kind;
676 : : Py_ssize_t end_idx;
677 : 1312 : PyObject *val = NULL;
678 : 1312 : PyObject *rval = NULL;
679 : 1312 : PyObject *key = NULL;
680 : 1312 : int has_pairs_hook = (s->object_pairs_hook != Py_None);
681 : : Py_ssize_t next_idx;
682 : :
683 [ - + ]: 1312 : if (PyUnicode_READY(pystr) == -1)
684 : 0 : return NULL;
685 : :
686 : 1312 : str = PyUnicode_DATA(pystr);
687 : 1312 : kind = PyUnicode_KIND(pystr);
688 : 1312 : end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
689 : :
690 [ + + ]: 1312 : if (has_pairs_hook)
691 : 10 : rval = PyList_New(0);
692 : : else
693 : 1302 : rval = PyDict_New();
694 [ - + ]: 1312 : if (rval == NULL)
695 : 0 : return NULL;
696 : :
697 : : /* skip whitespace after { */
698 [ + + + + : 1412 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind,str, idx))) idx++;
+ + + + -
+ ]
699 : :
700 : : /* only loop if the object is non-empty */
701 [ + + + + ]: 1312 : if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '}') {
702 : 24362 : while (1) {
703 : : PyObject *memokey;
704 : :
705 : : /* read key */
706 [ + + + + ]: 25661 : if (idx > end_idx || PyUnicode_READ(kind, str, idx) != '"') {
707 : 11 : raise_errmsg("Expecting property name enclosed in double quotes", pystr, idx);
708 : 11 : goto bail;
709 : : }
710 : 25650 : key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
711 [ + + ]: 25650 : if (key == NULL)
712 : 2 : goto bail;
713 : 25648 : memokey = PyDict_SetDefault(s->memo, key, key);
714 [ - + ]: 25648 : if (memokey == NULL) {
715 : 0 : goto bail;
716 : : }
717 : 25648 : Py_INCREF(memokey);
718 : 25648 : Py_DECREF(key);
719 : 25648 : key = memokey;
720 : 25648 : idx = next_idx;
721 : :
722 : : /* skip whitespace between key and : delimiter, read :, skip whitespace */
723 [ + + + + : 25728 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
- + + + -
+ ]
724 [ + + + + ]: 25648 : if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ':') {
725 : 6 : raise_errmsg("Expecting ':' delimiter", pystr, idx);
726 : 6 : goto bail;
727 : : }
728 : 25642 : idx++;
729 [ + + + + : 51115 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
+ + + + -
+ ]
730 : :
731 : : /* read any JSON term */
732 : 25642 : val = scan_once_unicode(s, pystr, idx, &next_idx);
733 [ + + ]: 25642 : if (val == NULL)
734 : 75 : goto bail;
735 : :
736 [ + + ]: 25567 : if (has_pairs_hook) {
737 : 50 : PyObject *item = PyTuple_Pack(2, key, val);
738 [ - + ]: 50 : if (item == NULL)
739 : 0 : goto bail;
740 [ + - ]: 50 : Py_CLEAR(key);
741 [ + - ]: 50 : Py_CLEAR(val);
742 [ - + ]: 50 : if (PyList_Append(rval, item) == -1) {
743 : 0 : Py_DECREF(item);
744 : 0 : goto bail;
745 : : }
746 : 50 : Py_DECREF(item);
747 : : }
748 : : else {
749 [ - + ]: 25517 : if (PyDict_SetItem(rval, key, val) < 0)
750 : 0 : goto bail;
751 [ + - ]: 25517 : Py_CLEAR(key);
752 [ + - ]: 25517 : Py_CLEAR(val);
753 : : }
754 : 25567 : idx = next_idx;
755 : :
756 : : /* skip whitespace before } or , */
757 [ + + + + : 25651 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
+ + + + -
+ ]
758 : :
759 : : /* bail if the object is closed or we didn't get the , delimiter */
760 [ + + + + ]: 25567 : if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == '}')
761 : 1199 : break;
762 [ + + + + ]: 24368 : if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
763 : 6 : raise_errmsg("Expecting ',' delimiter", pystr, idx);
764 : 6 : goto bail;
765 : : }
766 : 24362 : idx++;
767 : :
768 : : /* skip whitespace after , delimiter */
769 [ + + + + : 49054 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
+ + + + -
+ ]
770 : : }
771 : : }
772 : :
773 : 1212 : *next_idx_ptr = idx + 1;
774 : :
775 [ + + ]: 1212 : if (has_pairs_hook) {
776 : 10 : val = PyObject_CallOneArg(s->object_pairs_hook, rval);
777 : 10 : Py_DECREF(rval);
778 : 10 : return val;
779 : : }
780 : :
781 : : /* if object_hook is not None: rval = object_hook(rval) */
782 [ + + ]: 1202 : if (s->object_hook != Py_None) {
783 : 470 : val = PyObject_CallOneArg(s->object_hook, rval);
784 : 470 : Py_DECREF(rval);
785 : 470 : return val;
786 : : }
787 : 732 : return rval;
788 : 100 : bail:
789 : 100 : Py_XDECREF(key);
790 : 100 : Py_XDECREF(val);
791 : 100 : Py_XDECREF(rval);
792 : 100 : return NULL;
793 : : }
794 : :
795 : : static PyObject *
796 : 2794 : _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
797 : : /* Read a JSON array from PyUnicode pystr.
798 : : idx is the index of the first character after the opening brace.
799 : : *next_idx_ptr is a return-by-reference index to the first character after
800 : : the closing brace.
801 : :
802 : : Returns a new PyList
803 : : */
804 : : const void *str;
805 : : int kind;
806 : : Py_ssize_t end_idx;
807 : 2794 : PyObject *val = NULL;
808 : : PyObject *rval;
809 : : Py_ssize_t next_idx;
810 : :
811 [ - + ]: 2794 : if (PyUnicode_READY(pystr) == -1)
812 : 0 : return NULL;
813 : :
814 : 2794 : rval = PyList_New(0);
815 [ - + ]: 2794 : if (rval == NULL)
816 : 0 : return NULL;
817 : :
818 : 2794 : str = PyUnicode_DATA(pystr);
819 : 2794 : kind = PyUnicode_KIND(pystr);
820 : 2794 : end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
821 : :
822 : : /* skip whitespace after [ */
823 [ + + + + : 3182 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
+ + + + -
+ ]
824 : :
825 : : /* only loop if the array is non-empty */
826 [ + + + + ]: 2794 : if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
827 : : while (1) {
828 : :
829 : : /* read any JSON term */
830 : 7286 : val = scan_once_unicode(s, pystr, idx, &next_idx);
831 [ + + ]: 7286 : if (val == NULL)
832 : 65 : goto bail;
833 : :
834 [ - + ]: 7221 : if (PyList_Append(rval, val) == -1)
835 : 0 : goto bail;
836 : :
837 [ + - ]: 7221 : Py_CLEAR(val);
838 : 7221 : idx = next_idx;
839 : :
840 : : /* skip whitespace between term and , */
841 [ + + + + : 7424 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
+ + + + -
+ ]
842 : :
843 : : /* bail if the array is closed or we didn't get the , delimiter */
844 [ + + + + ]: 7221 : if (idx <= end_idx && PyUnicode_READ(kind, str, idx) == ']')
845 : 2174 : break;
846 [ + + + + ]: 5047 : if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ',') {
847 : 12 : raise_errmsg("Expecting ',' delimiter", pystr, idx);
848 : 12 : goto bail;
849 : : }
850 : 5035 : idx++;
851 : :
852 : : /* skip whitespace after , */
853 [ + + + + : 11974 : while (idx <= end_idx && IS_WHITESPACE(PyUnicode_READ(kind, str, idx))) idx++;
+ + + + +
+ ]
854 : : }
855 : : }
856 : :
857 : : /* verify that idx < end_idx, PyUnicode_READ(kind, str, idx) should be ']' */
858 [ + - - + ]: 2717 : if (idx > end_idx || PyUnicode_READ(kind, str, idx) != ']') {
859 : 0 : raise_errmsg("Expecting value", pystr, end_idx);
860 : 0 : goto bail;
861 : : }
862 : 2717 : *next_idx_ptr = idx + 1;
863 : 2717 : return rval;
864 : 77 : bail:
865 : 77 : Py_XDECREF(val);
866 : 77 : Py_DECREF(rval);
867 : 77 : return NULL;
868 : : }
869 : :
870 : : static PyObject *
871 : 15 : _parse_constant(PyScannerObject *s, const char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) {
872 : : /* Read a JSON constant.
873 : : constant is the constant string that was found
874 : : ("NaN", "Infinity", "-Infinity").
875 : : idx is the index of the first character of the constant
876 : : *next_idx_ptr is a return-by-reference index to the first character after
877 : : the constant.
878 : :
879 : : Returns the result of parse_constant
880 : : */
881 : : PyObject *cstr;
882 : : PyObject *rval;
883 : : /* constant is "NaN", "Infinity", or "-Infinity" */
884 : 15 : cstr = PyUnicode_InternFromString(constant);
885 [ - + ]: 15 : if (cstr == NULL)
886 : 0 : return NULL;
887 : :
888 : : /* rval = parse_constant(constant) */
889 : 15 : rval = PyObject_CallOneArg(s->parse_constant, cstr);
890 : 15 : idx += PyUnicode_GET_LENGTH(cstr);
891 : 15 : Py_DECREF(cstr);
892 : 15 : *next_idx_ptr = idx;
893 : 15 : return rval;
894 : : }
895 : :
896 : : static PyObject *
897 : 4765 : _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) {
898 : : /* Read a JSON number from PyUnicode pystr.
899 : : idx is the index of the first character of the number
900 : : *next_idx_ptr is a return-by-reference index to the first character after
901 : : the number.
902 : :
903 : : Returns a new PyObject representation of that number:
904 : : PyLong, or PyFloat.
905 : : May return other types if parse_int or parse_float are set
906 : : */
907 : : const void *str;
908 : : int kind;
909 : : Py_ssize_t end_idx;
910 : 4765 : Py_ssize_t idx = start;
911 : 4765 : int is_float = 0;
912 : : PyObject *rval;
913 : 4765 : PyObject *numstr = NULL;
914 : : PyObject *custom_func;
915 : :
916 [ - + ]: 4765 : if (PyUnicode_READY(pystr) == -1)
917 : 0 : return NULL;
918 : :
919 : 4765 : str = PyUnicode_DATA(pystr);
920 : 4765 : kind = PyUnicode_KIND(pystr);
921 : 4765 : end_idx = PyUnicode_GET_LENGTH(pystr) - 1;
922 : :
923 : : /* read a sign if it's there, make sure it's not the end of the string */
924 [ + + ]: 4765 : if (PyUnicode_READ(kind, str, idx) == '-') {
925 : 5 : idx++;
926 [ - + ]: 5 : if (idx > end_idx) {
927 : 0 : raise_stop_iteration(start);
928 : 0 : return NULL;
929 : : }
930 : : }
931 : :
932 : : /* read as many integer digits as we find as long as it doesn't start with 0 */
933 [ + + + + ]: 4765 : if (PyUnicode_READ(kind, str, idx) >= '1' && PyUnicode_READ(kind, str, idx) <= '9') {
934 : 2339 : idx++;
935 [ + + + + : 6056 : while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
+ + ]
936 : : }
937 : : /* if it starts with 0 we only expect one integer digit */
938 [ + + ]: 2426 : else if (PyUnicode_READ(kind, str, idx) == '0') {
939 : 2401 : idx++;
940 : : }
941 : : /* no integer digits, error */
942 : : else {
943 : 25 : raise_stop_iteration(start);
944 : 25 : return NULL;
945 : : }
946 : :
947 : : /* if the next char is '.' followed by a digit then read all float digits */
948 [ + + + + : 4740 : if (idx < end_idx && PyUnicode_READ(kind, str, idx) == '.' && PyUnicode_READ(kind, str, idx + 1) >= '0' && PyUnicode_READ(kind, str, idx + 1) <= '9') {
+ - + - ]
949 : 535 : is_float = 1;
950 : 535 : idx += 2;
951 [ + + + + : 7380 : while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
+ + ]
952 : : }
953 : :
954 : : /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */
955 [ + + + + : 4740 : if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == 'e' || PyUnicode_READ(kind, str, idx) == 'E')) {
+ + ]
956 : 19 : Py_ssize_t e_start = idx;
957 : 19 : idx++;
958 : :
959 : : /* read an exponent sign if present */
960 [ + + + + : 19 : if (idx < end_idx && (PyUnicode_READ(kind, str, idx) == '-' || PyUnicode_READ(kind, str, idx) == '+')) idx++;
+ + ]
961 : :
962 : : /* read all digits */
963 [ + + + + : 50 : while (idx <= end_idx && PyUnicode_READ(kind, str, idx) >= '0' && PyUnicode_READ(kind, str, idx) <= '9') idx++;
+ + ]
964 : :
965 : : /* if we got a digit, then parse as float. if not, backtrack */
966 [ + + + + ]: 19 : if (PyUnicode_READ(kind, str, idx - 1) >= '0' && PyUnicode_READ(kind, str, idx - 1) <= '9') {
967 : 16 : is_float = 1;
968 : : }
969 : : else {
970 : 3 : idx = e_start;
971 : : }
972 : : }
973 : :
974 [ + + + + ]: 4740 : if (is_float && s->parse_float != (PyObject *)&PyFloat_Type)
975 : 3 : custom_func = s->parse_float;
976 [ + + + + ]: 4737 : else if (!is_float && s->parse_int != (PyObject *) &PyLong_Type)
977 : 1 : custom_func = s->parse_int;
978 : : else
979 : 4736 : custom_func = NULL;
980 : :
981 [ + + ]: 4740 : if (custom_func) {
982 : : /* copy the section we determined to be a number */
983 : 4 : numstr = PyUnicode_FromKindAndData(kind,
984 : 4 : (char*)str + kind * start,
985 : : idx - start);
986 [ - + ]: 4 : if (numstr == NULL)
987 : 0 : return NULL;
988 : 4 : rval = PyObject_CallOneArg(custom_func, numstr);
989 : : }
990 : : else {
991 : : Py_ssize_t i, n;
992 : : char *buf;
993 : : /* Straight conversion to ASCII, to avoid costly conversion of
994 : : decimal unicode digits (which cannot appear here) */
995 : 4736 : n = idx - start;
996 : 4736 : numstr = PyBytes_FromStringAndSize(NULL, n);
997 [ - + ]: 4736 : if (numstr == NULL)
998 : 0 : return NULL;
999 : 4736 : buf = PyBytes_AS_STRING(numstr);
1000 [ + + ]: 21160 : for (i = 0; i < n; i++) {
1001 : 16424 : buf[i] = (char) PyUnicode_READ(kind, str, i + start);
1002 : : }
1003 [ + + ]: 4736 : if (is_float)
1004 : 540 : rval = PyFloat_FromString(numstr);
1005 : : else
1006 : 4196 : rval = PyLong_FromString(buf, NULL, 10);
1007 : : }
1008 : 4740 : Py_DECREF(numstr);
1009 : 4740 : *next_idx_ptr = idx;
1010 : 4740 : return rval;
1011 : : }
1012 : :
1013 : : static PyObject *
1014 : 89418 : scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr)
1015 : : {
1016 : : /* Read one JSON term (of any kind) from PyUnicode pystr.
1017 : : idx is the index of the first character of the term
1018 : : *next_idx_ptr is a return-by-reference index to the first character after
1019 : : the number.
1020 : :
1021 : : Returns a new PyObject representation of the term.
1022 : : */
1023 : : PyObject *res;
1024 : : const void *str;
1025 : : int kind;
1026 : : Py_ssize_t length;
1027 : :
1028 [ - + ]: 89418 : if (PyUnicode_READY(pystr) == -1)
1029 : 0 : return NULL;
1030 : :
1031 : 89418 : str = PyUnicode_DATA(pystr);
1032 : 89418 : kind = PyUnicode_KIND(pystr);
1033 : 89418 : length = PyUnicode_GET_LENGTH(pystr);
1034 : :
1035 [ + + ]: 89418 : if (idx < 0) {
1036 : 1 : PyErr_SetString(PyExc_ValueError, "idx cannot be negative");
1037 : 1 : return NULL;
1038 : : }
1039 [ + + ]: 89417 : if (idx >= length) {
1040 : 7 : raise_stop_iteration(idx);
1041 : 7 : return NULL;
1042 : : }
1043 : :
1044 [ + + + + : 89410 : switch (PyUnicode_READ(kind, str, idx)) {
+ + + + +
+ ]
1045 : 63938 : case '"':
1046 : : /* string */
1047 : 63938 : return scanstring_unicode(pystr, idx + 1, s->strict, next_idx_ptr);
1048 : 1314 : case '{':
1049 : : /* object */
1050 [ + + ]: 1314 : if (_Py_EnterRecursiveCall(" while decoding a JSON object "
1051 : : "from a unicode string"))
1052 : 2 : return NULL;
1053 : 1312 : res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
1054 : 1312 : _Py_LeaveRecursiveCall();
1055 : 1312 : return res;
1056 : 2795 : case '[':
1057 : : /* array */
1058 [ + + ]: 2795 : if (_Py_EnterRecursiveCall(" while decoding a JSON array "
1059 : : "from a unicode string"))
1060 : 1 : return NULL;
1061 : 2794 : res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
1062 : 2794 : _Py_LeaveRecursiveCall();
1063 : 2794 : return res;
1064 : 6719 : case 'n':
1065 : : /* null */
1066 [ + - + - : 6719 : if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'u' && PyUnicode_READ(kind, str, idx + 2) == 'l' && PyUnicode_READ(kind, str, idx + 3) == 'l') {
+ - + - ]
1067 : 6719 : *next_idx_ptr = idx + 4;
1068 : 6719 : Py_RETURN_NONE;
1069 : : }
1070 : 0 : break;
1071 : 974 : case 't':
1072 : : /* true */
1073 [ + - + - : 974 : if ((idx + 3 < length) && PyUnicode_READ(kind, str, idx + 1) == 'r' && PyUnicode_READ(kind, str, idx + 2) == 'u' && PyUnicode_READ(kind, str, idx + 3) == 'e') {
+ - + + ]
1074 : 973 : *next_idx_ptr = idx + 4;
1075 : 973 : Py_RETURN_TRUE;
1076 : : }
1077 : 1 : break;
1078 : 8891 : case 'f':
1079 : : /* false */
1080 [ + - + - : 17782 : if ((idx + 4 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
+ - ]
1081 [ + - ]: 17782 : PyUnicode_READ(kind, str, idx + 2) == 'l' &&
1082 [ + - ]: 17782 : PyUnicode_READ(kind, str, idx + 3) == 's' &&
1083 : 8891 : PyUnicode_READ(kind, str, idx + 4) == 'e') {
1084 : 8891 : *next_idx_ptr = idx + 5;
1085 : 8891 : Py_RETURN_FALSE;
1086 : : }
1087 : 0 : break;
1088 : 5 : case 'N':
1089 : : /* NaN */
1090 [ + - + - : 10 : if ((idx + 2 < length) && PyUnicode_READ(kind, str, idx + 1) == 'a' &&
+ - ]
1091 : 5 : PyUnicode_READ(kind, str, idx + 2) == 'N') {
1092 : 5 : return _parse_constant(s, "NaN", idx, next_idx_ptr);
1093 : : }
1094 : 0 : break;
1095 : 5 : case 'I':
1096 : : /* Infinity */
1097 [ + - + - : 10 : if ((idx + 7 < length) && PyUnicode_READ(kind, str, idx + 1) == 'n' &&
+ - ]
1098 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 2) == 'f' &&
1099 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 3) == 'i' &&
1100 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 4) == 'n' &&
1101 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 5) == 'i' &&
1102 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 6) == 't' &&
1103 : 5 : PyUnicode_READ(kind, str, idx + 7) == 'y') {
1104 : 5 : return _parse_constant(s, "Infinity", idx, next_idx_ptr);
1105 : : }
1106 : 0 : break;
1107 : 10 : case '-':
1108 : : /* -Infinity */
1109 [ + - + + : 15 : if ((idx + 8 < length) && PyUnicode_READ(kind, str, idx + 1) == 'I' &&
+ - ]
1110 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 2) == 'n' &&
1111 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 3) == 'f' &&
1112 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 4) == 'i' &&
1113 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 5) == 'n' &&
1114 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 6) == 'i' &&
1115 [ + - ]: 10 : PyUnicode_READ(kind, str, idx + 7) == 't' &&
1116 : 5 : PyUnicode_READ(kind, str, idx + 8) == 'y') {
1117 : 5 : return _parse_constant(s, "-Infinity", idx, next_idx_ptr);
1118 : : }
1119 : 5 : break;
1120 : : }
1121 : : /* Didn't find a string, object, array, or named constant. Look for a number. */
1122 : 4765 : return _match_number_unicode(s, pystr, idx, next_idx_ptr);
1123 : : }
1124 : :
1125 : : static PyObject *
1126 : 56490 : scanner_call(PyScannerObject *self, PyObject *args, PyObject *kwds)
1127 : : {
1128 : : /* Python callable interface to scan_once_{str,unicode} */
1129 : : PyObject *pystr;
1130 : : PyObject *rval;
1131 : : Py_ssize_t idx;
1132 : 56490 : Py_ssize_t next_idx = -1;
1133 : : static char *kwlist[] = {"string", "idx", NULL};
1134 [ - + ]: 56490 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:scan_once", kwlist, &pystr, &idx))
1135 : 0 : return NULL;
1136 : :
1137 [ + - ]: 56490 : if (PyUnicode_Check(pystr)) {
1138 : 56490 : rval = scan_once_unicode(self, pystr, idx, &next_idx);
1139 : : }
1140 : : else {
1141 : 0 : PyErr_Format(PyExc_TypeError,
1142 : : "first argument must be a string, not %.80s",
1143 : 0 : Py_TYPE(pystr)->tp_name);
1144 : 0 : return NULL;
1145 : : }
1146 : 56490 : PyDict_Clear(self->memo);
1147 [ + + ]: 56490 : if (rval == NULL)
1148 : 86 : return NULL;
1149 : 56404 : return _build_rval_index_tuple(rval, next_idx);
1150 : : }
1151 : :
1152 : : static PyObject *
1153 : 1038 : scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1154 : : {
1155 : : PyScannerObject *s;
1156 : : PyObject *ctx;
1157 : : PyObject *strict;
1158 : : static char *kwlist[] = {"context", NULL};
1159 : :
1160 [ - + ]: 1038 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
1161 : 0 : return NULL;
1162 : :
1163 : 1038 : s = (PyScannerObject *)type->tp_alloc(type, 0);
1164 [ - + ]: 1038 : if (s == NULL) {
1165 : 0 : return NULL;
1166 : : }
1167 : :
1168 : 1038 : s->memo = PyDict_New();
1169 [ - + ]: 1038 : if (s->memo == NULL)
1170 : 0 : goto bail;
1171 : :
1172 : : /* All of these will fail "gracefully" so we don't need to verify them */
1173 : 1038 : strict = PyObject_GetAttrString(ctx, "strict");
1174 [ + + ]: 1038 : if (strict == NULL)
1175 : 1 : goto bail;
1176 : 1037 : s->strict = PyObject_IsTrue(strict);
1177 : 1037 : Py_DECREF(strict);
1178 [ + + ]: 1037 : if (s->strict < 0)
1179 : 2 : goto bail;
1180 : 1035 : s->object_hook = PyObject_GetAttrString(ctx, "object_hook");
1181 [ - + ]: 1035 : if (s->object_hook == NULL)
1182 : 0 : goto bail;
1183 : 1035 : s->object_pairs_hook = PyObject_GetAttrString(ctx, "object_pairs_hook");
1184 [ - + ]: 1035 : if (s->object_pairs_hook == NULL)
1185 : 0 : goto bail;
1186 : 1035 : s->parse_float = PyObject_GetAttrString(ctx, "parse_float");
1187 [ - + ]: 1035 : if (s->parse_float == NULL)
1188 : 0 : goto bail;
1189 : 1035 : s->parse_int = PyObject_GetAttrString(ctx, "parse_int");
1190 [ - + ]: 1035 : if (s->parse_int == NULL)
1191 : 0 : goto bail;
1192 : 1035 : s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant");
1193 [ - + ]: 1035 : if (s->parse_constant == NULL)
1194 : 0 : goto bail;
1195 : :
1196 : 1035 : return (PyObject *)s;
1197 : :
1198 : 3 : bail:
1199 : 3 : Py_DECREF(s);
1200 : 3 : return NULL;
1201 : : }
1202 : :
1203 : : PyDoc_STRVAR(scanner_doc, "JSON scanner object");
1204 : :
1205 : : static PyType_Slot PyScannerType_slots[] = {
1206 : : {Py_tp_doc, (void *)scanner_doc},
1207 : : {Py_tp_dealloc, scanner_dealloc},
1208 : : {Py_tp_call, scanner_call},
1209 : : {Py_tp_traverse, scanner_traverse},
1210 : : {Py_tp_clear, scanner_clear},
1211 : : {Py_tp_members, scanner_members},
1212 : : {Py_tp_new, scanner_new},
1213 : : {0, 0}
1214 : : };
1215 : :
1216 : : static PyType_Spec PyScannerType_spec = {
1217 : : .name = "_json.Scanner",
1218 : : .basicsize = sizeof(PyScannerObject),
1219 : : .itemsize = 0,
1220 : : .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1221 : : .slots = PyScannerType_slots,
1222 : : };
1223 : :
1224 : : static PyObject *
1225 : 1118 : encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1226 : : {
1227 : : static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
1228 : :
1229 : : PyEncoderObject *s;
1230 : : PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
1231 : : PyObject *item_separator;
1232 : : int sort_keys, skipkeys, allow_nan;
1233 : :
1234 [ + + ]: 1118 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUppp:make_encoder", kwlist,
1235 : : &markers, &defaultfn, &encoder, &indent,
1236 : : &key_separator, &item_separator,
1237 : : &sort_keys, &skipkeys, &allow_nan))
1238 : 7 : return NULL;
1239 : :
1240 [ + + + + ]: 1111 : if (markers != Py_None && !PyDict_Check(markers)) {
1241 : 1 : PyErr_Format(PyExc_TypeError,
1242 : : "make_encoder() argument 1 must be dict or None, "
1243 : 1 : "not %.200s", Py_TYPE(markers)->tp_name);
1244 : 1 : return NULL;
1245 : : }
1246 : :
1247 : 1110 : s = (PyEncoderObject *)type->tp_alloc(type, 0);
1248 [ - + ]: 1110 : if (s == NULL)
1249 : 0 : return NULL;
1250 : :
1251 : 1110 : s->markers = markers;
1252 : 1110 : s->defaultfn = defaultfn;
1253 : 1110 : s->encoder = encoder;
1254 : 1110 : s->indent = indent;
1255 : 1110 : s->key_separator = key_separator;
1256 : 1110 : s->item_separator = item_separator;
1257 : 1110 : s->sort_keys = sort_keys;
1258 : 1110 : s->skipkeys = skipkeys;
1259 : 1110 : s->allow_nan = allow_nan;
1260 : 1110 : s->fast_encode = NULL;
1261 [ + + ]: 1110 : if (PyCFunction_Check(s->encoder)) {
1262 : 1108 : PyCFunction f = PyCFunction_GetFunction(s->encoder);
1263 [ + + + - ]: 1108 : if (f == (PyCFunction)py_encode_basestring_ascii ||
1264 : : f == (PyCFunction)py_encode_basestring) {
1265 : 1108 : s->fast_encode = f;
1266 : : }
1267 : : }
1268 : :
1269 : 1110 : Py_INCREF(s->markers);
1270 : 1110 : Py_INCREF(s->defaultfn);
1271 : 1110 : Py_INCREF(s->encoder);
1272 : 1110 : Py_INCREF(s->indent);
1273 : 1110 : Py_INCREF(s->key_separator);
1274 : 1110 : Py_INCREF(s->item_separator);
1275 : 1110 : return (PyObject *)s;
1276 : : }
1277 : :
1278 : : static PyObject *
1279 : 1111 : encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds)
1280 : : {
1281 : : /* Python callable interface to encode_listencode_obj */
1282 : : static char *kwlist[] = {"obj", "_current_indent_level", NULL};
1283 : : PyObject *obj;
1284 : : Py_ssize_t indent_level;
1285 : : _PyAccu acc;
1286 [ - + ]: 1111 : if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist,
1287 : : &obj, &indent_level))
1288 : 0 : return NULL;
1289 [ - + ]: 1111 : if (_PyAccu_Init(&acc))
1290 : 0 : return NULL;
1291 [ + + ]: 1111 : if (encoder_listencode_obj(self, &acc, obj, indent_level)) {
1292 : 20 : _PyAccu_Destroy(&acc);
1293 : 20 : return NULL;
1294 : : }
1295 : 1091 : return _PyAccu_FinishAsList(&acc);
1296 : : }
1297 : :
1298 : : static PyObject *
1299 : 16650 : _encoded_const(PyObject *obj)
1300 : : {
1301 : : /* Return the JSON string representation of None, True, False */
1302 [ + + ]: 16650 : if (obj == Py_None) {
1303 : : _Py_static_string(PyId_null, "null");
1304 : 6755 : PyObject *s_null = _PyUnicode_FromId(&PyId_null);
1305 [ - + ]: 6755 : if (s_null == NULL) {
1306 : 0 : return NULL;
1307 : : }
1308 : 6755 : return Py_NewRef(s_null);
1309 : : }
1310 [ + + ]: 9895 : else if (obj == Py_True) {
1311 : : _Py_static_string(PyId_true, "true");
1312 : 969 : PyObject *s_true = _PyUnicode_FromId(&PyId_true);
1313 [ - + ]: 969 : if (s_true == NULL) {
1314 : 0 : return NULL;
1315 : : }
1316 : 969 : return Py_NewRef(s_true);
1317 : : }
1318 [ + - ]: 8926 : else if (obj == Py_False) {
1319 : : _Py_static_string(PyId_false, "false");
1320 : 8926 : PyObject *s_false = _PyUnicode_FromId(&PyId_false);
1321 [ - + ]: 8926 : if (s_false == NULL) {
1322 : 0 : return NULL;
1323 : : }
1324 : 8926 : return Py_NewRef(s_false);
1325 : : }
1326 : : else {
1327 : 0 : PyErr_SetString(PyExc_ValueError, "not a const");
1328 : 0 : return NULL;
1329 : : }
1330 : : }
1331 : :
1332 : : static PyObject *
1333 : 583 : encoder_encode_float(PyEncoderObject *s, PyObject *obj)
1334 : : {
1335 : : /* Return the JSON representation of a PyFloat. */
1336 : 583 : double i = PyFloat_AS_DOUBLE(obj);
1337 [ + + ]: 583 : if (!Py_IS_FINITE(i)) {
1338 [ + + ]: 30 : if (!s->allow_nan) {
1339 : 3 : PyErr_SetString(
1340 : : PyExc_ValueError,
1341 : : "Out of range float values are not JSON compliant"
1342 : : );
1343 : 3 : return NULL;
1344 : : }
1345 [ + + ]: 27 : if (i > 0) {
1346 : 9 : return PyUnicode_FromString("Infinity");
1347 : : }
1348 [ + + ]: 18 : else if (i < 0) {
1349 : 9 : return PyUnicode_FromString("-Infinity");
1350 : : }
1351 : : else {
1352 : 9 : return PyUnicode_FromString("NaN");
1353 : : }
1354 : : }
1355 : 553 : return PyFloat_Type.tp_repr(obj);
1356 : : }
1357 : :
1358 : : static PyObject *
1359 : 33905 : encoder_encode_string(PyEncoderObject *s, PyObject *obj)
1360 : : {
1361 : : /* Return the JSON representation of a string */
1362 : : PyObject *encoded;
1363 : :
1364 [ + + ]: 33905 : if (s->fast_encode) {
1365 : 33902 : return s->fast_encode(NULL, obj);
1366 : : }
1367 : 3 : encoded = PyObject_CallOneArg(s->encoder, obj);
1368 [ + + + - ]: 3 : if (encoded != NULL && !PyUnicode_Check(encoded)) {
1369 : 2 : PyErr_Format(PyExc_TypeError,
1370 : : "encoder() must return a string, not %.80s",
1371 : 2 : Py_TYPE(encoded)->tp_name);
1372 : 2 : Py_DECREF(encoded);
1373 : 2 : return NULL;
1374 : : }
1375 : 1 : return encoded;
1376 : : }
1377 : :
1378 : : static int
1379 : 29766 : _steal_accumulate(_PyAccu *acc, PyObject *stolen)
1380 : : {
1381 : : /* Append stolen and then decrement its reference count */
1382 : 29766 : int rval = _PyAccu_Accumulate(acc, stolen);
1383 : 29766 : Py_DECREF(stolen);
1384 : 29766 : return rval;
1385 : : }
1386 : :
1387 : : static int
1388 : 34170 : encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
1389 : : PyObject *obj, Py_ssize_t indent_level)
1390 : : {
1391 : : /* Encode Python object obj to a JSON term */
1392 : : PyObject *newobj;
1393 : : int rv;
1394 : :
1395 [ + + + + : 34170 : if (obj == Py_None || obj == Py_True || obj == Py_False) {
+ + ]
1396 : 16647 : PyObject *cstr = _encoded_const(obj);
1397 [ - + ]: 16647 : if (cstr == NULL)
1398 : 0 : return -1;
1399 : 16647 : return _steal_accumulate(acc, cstr);
1400 : : }
1401 [ + + ]: 17523 : else if (PyUnicode_Check(obj))
1402 : : {
1403 : 8285 : PyObject *encoded = encoder_encode_string(s, obj);
1404 [ + + ]: 8285 : if (encoded == NULL)
1405 : 2 : return -1;
1406 : 8283 : return _steal_accumulate(acc, encoded);
1407 : : }
1408 [ + + ]: 9238 : else if (PyLong_Check(obj)) {
1409 : 4263 : PyObject *encoded = PyLong_Type.tp_repr(obj);
1410 [ - + ]: 4263 : if (encoded == NULL)
1411 : 0 : return -1;
1412 : 4263 : return _steal_accumulate(acc, encoded);
1413 : : }
1414 [ + + ]: 4975 : else if (PyFloat_Check(obj)) {
1415 : 576 : PyObject *encoded = encoder_encode_float(s, obj);
1416 [ + + ]: 576 : if (encoded == NULL)
1417 : 3 : return -1;
1418 : 573 : return _steal_accumulate(acc, encoded);
1419 : : }
1420 [ + + + + ]: 4399 : else if (PyList_Check(obj) || PyTuple_Check(obj)) {
1421 [ + + ]: 2678 : if (_Py_EnterRecursiveCall(" while encoding a JSON object"))
1422 : 2 : return -1;
1423 : 2676 : rv = encoder_listencode_list(s, acc, obj, indent_level);
1424 : 2676 : _Py_LeaveRecursiveCall();
1425 : 2676 : return rv;
1426 : : }
1427 [ + + ]: 1721 : else if (PyDict_Check(obj)) {
1428 [ + + ]: 1218 : if (_Py_EnterRecursiveCall(" while encoding a JSON object"))
1429 : 1 : return -1;
1430 : 1217 : rv = encoder_listencode_dict(s, acc, obj, indent_level);
1431 : 1217 : _Py_LeaveRecursiveCall();
1432 : 1217 : return rv;
1433 : : }
1434 : : else {
1435 : 503 : PyObject *ident = NULL;
1436 [ + + ]: 503 : if (s->markers != Py_None) {
1437 : : int has_key;
1438 : 485 : ident = PyLong_FromVoidPtr(obj);
1439 [ - + ]: 485 : if (ident == NULL)
1440 : 0 : return -1;
1441 : 485 : has_key = PyDict_Contains(s->markers, ident);
1442 [ + + ]: 485 : if (has_key) {
1443 [ + - ]: 1 : if (has_key != -1)
1444 : 1 : PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1445 : 1 : Py_DECREF(ident);
1446 : 1 : return -1;
1447 : : }
1448 [ - + ]: 484 : if (PyDict_SetItem(s->markers, ident, obj)) {
1449 : 0 : Py_DECREF(ident);
1450 : 0 : return -1;
1451 : : }
1452 : : }
1453 : 502 : newobj = PyObject_CallOneArg(s->defaultfn, obj);
1454 [ + + ]: 502 : if (newobj == NULL) {
1455 : 4 : Py_XDECREF(ident);
1456 : 4 : return -1;
1457 : : }
1458 : :
1459 [ - + ]: 498 : if (_Py_EnterRecursiveCall(" while encoding a JSON object")) {
1460 : 0 : Py_DECREF(newobj);
1461 : 0 : Py_XDECREF(ident);
1462 : 0 : return -1;
1463 : : }
1464 : 498 : rv = encoder_listencode_obj(s, acc, newobj, indent_level);
1465 : 498 : _Py_LeaveRecursiveCall();
1466 : :
1467 : 498 : Py_DECREF(newobj);
1468 [ + + ]: 498 : if (rv) {
1469 : 19 : Py_XDECREF(ident);
1470 : 19 : return -1;
1471 : : }
1472 [ + - ]: 479 : if (ident != NULL) {
1473 [ - + ]: 479 : if (PyDict_DelItem(s->markers, ident)) {
1474 : 0 : Py_XDECREF(ident);
1475 : 0 : return -1;
1476 : : }
1477 : 479 : Py_XDECREF(ident);
1478 : : }
1479 : 479 : return rv;
1480 : : }
1481 : : }
1482 : :
1483 : : static int
1484 : 1217 : encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc,
1485 : : PyObject *dct, Py_ssize_t indent_level)
1486 : : {
1487 : : /* Encode Python dict dct a JSON term */
1488 : : _Py_static_string(PyId_open_dict, "{");
1489 : : _Py_static_string(PyId_close_dict, "}");
1490 : : _Py_static_string(PyId_empty_dict, "{}");
1491 : 1217 : PyObject *open_dict = _PyUnicode_FromId(&PyId_open_dict); // borrowed ref
1492 : 1217 : PyObject *close_dict = _PyUnicode_FromId(&PyId_close_dict); // borrowed ref
1493 : 1217 : PyObject *empty_dict = _PyUnicode_FromId(&PyId_empty_dict); // borrowed ref
1494 : 1217 : PyObject *kstr = NULL;
1495 : 1217 : PyObject *ident = NULL;
1496 : 1217 : PyObject *it = NULL;
1497 : : PyObject *items;
1498 : 1217 : PyObject *item = NULL;
1499 : : Py_ssize_t idx;
1500 : :
1501 [ + - + - : 1217 : if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) {
- + ]
1502 : 0 : return -1;
1503 : : }
1504 [ + + ]: 1217 : if (PyDict_GET_SIZE(dct) == 0) /* Fast path */
1505 : 4 : return _PyAccu_Accumulate(acc, empty_dict);
1506 : :
1507 [ + + ]: 1213 : if (s->markers != Py_None) {
1508 : : int has_key;
1509 : 1212 : ident = PyLong_FromVoidPtr(dct);
1510 [ - + ]: 1212 : if (ident == NULL)
1511 : 0 : goto bail;
1512 : 1212 : has_key = PyDict_Contains(s->markers, ident);
1513 [ + + ]: 1212 : if (has_key) {
1514 [ + - ]: 1 : if (has_key != -1)
1515 : 1 : PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1516 : 1 : goto bail;
1517 : : }
1518 [ - + ]: 1211 : if (PyDict_SetItem(s->markers, ident, dct)) {
1519 : 0 : goto bail;
1520 : : }
1521 : : }
1522 : :
1523 [ - + ]: 1212 : if (_PyAccu_Accumulate(acc, open_dict))
1524 : 0 : goto bail;
1525 : :
1526 [ - + ]: 1212 : if (s->indent != Py_None) {
1527 : : /* TODO: DOES NOT RUN */
1528 : 0 : indent_level += 1;
1529 : : /*
1530 : : newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1531 : : separator = _item_separator + newline_indent
1532 : : buf += newline_indent
1533 : : */
1534 : : }
1535 : :
1536 : 1212 : items = PyMapping_Items(dct);
1537 [ - + ]: 1212 : if (items == NULL)
1538 : 0 : goto bail;
1539 [ + + + + ]: 1212 : if (s->sort_keys && PyList_Sort(items) < 0) {
1540 : 1 : Py_DECREF(items);
1541 : 1 : goto bail;
1542 : : }
1543 : 1211 : it = PyObject_GetIter(items);
1544 : 1211 : Py_DECREF(items);
1545 [ - + ]: 1211 : if (it == NULL)
1546 : 0 : goto bail;
1547 : 1211 : idx = 0;
1548 [ + + ]: 26796 : while ((item = PyIter_Next(it)) != NULL) {
1549 : : PyObject *encoded, *key, *value;
1550 [ + - - + ]: 25623 : if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
1551 : 0 : PyErr_SetString(PyExc_ValueError, "items must return 2-tuples");
1552 : 0 : goto bail;
1553 : : }
1554 : 25623 : key = PyTuple_GET_ITEM(item, 0);
1555 [ + + ]: 25623 : if (PyUnicode_Check(key)) {
1556 : 25602 : Py_INCREF(key);
1557 : 25602 : kstr = key;
1558 : : }
1559 [ + + ]: 21 : else if (PyFloat_Check(key)) {
1560 : 7 : kstr = encoder_encode_float(s, key);
1561 [ - + ]: 7 : if (kstr == NULL)
1562 : 0 : goto bail;
1563 : : }
1564 [ + + + + : 14 : else if (key == Py_True || key == Py_False || key == Py_None) {
- + ]
1565 : : /* This must come before the PyLong_Check because
1566 : : True and False are also 1 and 0.*/
1567 : 3 : kstr = _encoded_const(key);
1568 [ - + ]: 3 : if (kstr == NULL)
1569 : 0 : goto bail;
1570 : : }
1571 [ + + ]: 11 : else if (PyLong_Check(key)) {
1572 : 8 : kstr = PyLong_Type.tp_repr(key);
1573 [ - + ]: 8 : if (kstr == NULL) {
1574 : 0 : goto bail;
1575 : : }
1576 : : }
1577 [ + + ]: 3 : else if (s->skipkeys) {
1578 : 1 : Py_DECREF(item);
1579 : 1 : continue;
1580 : : }
1581 : : else {
1582 : 2 : PyErr_Format(PyExc_TypeError,
1583 : : "keys must be str, int, float, bool or None, "
1584 : 2 : "not %.100s", Py_TYPE(key)->tp_name);
1585 : 2 : goto bail;
1586 : : }
1587 : :
1588 [ + + ]: 25620 : if (idx) {
1589 [ - + ]: 24410 : if (_PyAccu_Accumulate(acc, s->item_separator))
1590 : 0 : goto bail;
1591 : : }
1592 : :
1593 : 25620 : encoded = encoder_encode_string(s, kstr);
1594 [ + - ]: 25620 : Py_CLEAR(kstr);
1595 [ + + ]: 25620 : if (encoded == NULL)
1596 : 1 : goto bail;
1597 [ - + ]: 25619 : if (_PyAccu_Accumulate(acc, encoded)) {
1598 : 0 : Py_DECREF(encoded);
1599 : 0 : goto bail;
1600 : : }
1601 : 25619 : Py_DECREF(encoded);
1602 [ - + ]: 25619 : if (_PyAccu_Accumulate(acc, s->key_separator))
1603 : 0 : goto bail;
1604 : :
1605 : 25619 : value = PyTuple_GET_ITEM(item, 1);
1606 [ + + ]: 25619 : if (encoder_listencode_obj(s, acc, value, indent_level))
1607 : 35 : goto bail;
1608 : 25584 : idx += 1;
1609 : 25584 : Py_DECREF(item);
1610 : : }
1611 [ - + ]: 1173 : if (PyErr_Occurred())
1612 : 0 : goto bail;
1613 [ + - ]: 1173 : Py_CLEAR(it);
1614 : :
1615 [ + - ]: 1173 : if (ident != NULL) {
1616 [ - + ]: 1173 : if (PyDict_DelItem(s->markers, ident))
1617 : 0 : goto bail;
1618 [ + - ]: 1173 : Py_CLEAR(ident);
1619 : : }
1620 : : /* TODO DOES NOT RUN; dead code
1621 : : if (s->indent != Py_None) {
1622 : : indent_level -= 1;
1623 : :
1624 : : yield '\n' + (' ' * (_indent * _current_indent_level))
1625 : : }*/
1626 [ - + ]: 1173 : if (_PyAccu_Accumulate(acc, close_dict))
1627 : 0 : goto bail;
1628 : 1173 : return 0;
1629 : :
1630 : 40 : bail:
1631 : 40 : Py_XDECREF(it);
1632 : 40 : Py_XDECREF(item);
1633 : 40 : Py_XDECREF(kstr);
1634 : 40 : Py_XDECREF(ident);
1635 : 40 : return -1;
1636 : : }
1637 : :
1638 : :
1639 : : static int
1640 : 2676 : encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc,
1641 : : PyObject *seq, Py_ssize_t indent_level)
1642 : : {
1643 : : /* Encode Python list seq to a JSON term */
1644 : : _Py_static_string(PyId_open_array, "[");
1645 : : _Py_static_string(PyId_close_array, "]");
1646 : : _Py_static_string(PyId_empty_array, "[]");
1647 : 2676 : PyObject *open_array = _PyUnicode_FromId(&PyId_open_array); // borrowed ref
1648 : 2676 : PyObject *close_array = _PyUnicode_FromId(&PyId_close_array); // borrowed ref
1649 : 2676 : PyObject *empty_array = _PyUnicode_FromId(&PyId_empty_array); // borrowed ref
1650 : 2676 : PyObject *ident = NULL;
1651 : 2676 : PyObject *s_fast = NULL;
1652 : : Py_ssize_t i;
1653 : :
1654 [ + - + - : 2676 : if (open_array == NULL || close_array == NULL || empty_array == NULL) {
- + ]
1655 : 0 : return -1;
1656 : : }
1657 : 2676 : ident = NULL;
1658 : 2676 : s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence");
1659 [ - + ]: 2676 : if (s_fast == NULL)
1660 : 0 : return -1;
1661 [ + + + + ]: 2676 : if (PySequence_Fast_GET_SIZE(s_fast) == 0) {
1662 : 534 : Py_DECREF(s_fast);
1663 : 534 : return _PyAccu_Accumulate(acc, empty_array);
1664 : : }
1665 : :
1666 [ + + ]: 2142 : if (s->markers != Py_None) {
1667 : : int has_key;
1668 : 2125 : ident = PyLong_FromVoidPtr(seq);
1669 [ - + ]: 2125 : if (ident == NULL)
1670 : 0 : goto bail;
1671 : 2125 : has_key = PyDict_Contains(s->markers, ident);
1672 [ + + ]: 2125 : if (has_key) {
1673 [ + - ]: 2 : if (has_key != -1)
1674 : 2 : PyErr_SetString(PyExc_ValueError, "Circular reference detected");
1675 : 2 : goto bail;
1676 : : }
1677 [ - + ]: 2123 : if (PyDict_SetItem(s->markers, ident, seq)) {
1678 : 0 : goto bail;
1679 : : }
1680 : : }
1681 : :
1682 [ - + ]: 2140 : if (_PyAccu_Accumulate(acc, open_array))
1683 : 0 : goto bail;
1684 [ - + ]: 2140 : if (s->indent != Py_None) {
1685 : : /* TODO: DOES NOT RUN */
1686 : 0 : indent_level += 1;
1687 : : /*
1688 : : newline_indent = '\n' + (' ' * (_indent * _current_indent_level))
1689 : : separator = _item_separator + newline_indent
1690 : : buf += newline_indent
1691 : : */
1692 : : }
1693 [ + + + + ]: 9023 : for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) {
1694 [ + + ]: 6942 : PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i);
1695 [ + + ]: 6942 : if (i) {
1696 [ - + ]: 4802 : if (_PyAccu_Accumulate(acc, s->item_separator))
1697 : 0 : goto bail;
1698 : : }
1699 [ + + ]: 6942 : if (encoder_listencode_obj(s, acc, obj, indent_level))
1700 : 59 : goto bail;
1701 : : }
1702 [ + - ]: 2081 : if (ident != NULL) {
1703 [ - + ]: 2081 : if (PyDict_DelItem(s->markers, ident))
1704 : 0 : goto bail;
1705 [ + - ]: 2081 : Py_CLEAR(ident);
1706 : : }
1707 : :
1708 : : /* TODO: DOES NOT RUN
1709 : : if (s->indent != Py_None) {
1710 : : indent_level -= 1;
1711 : :
1712 : : yield '\n' + (' ' * (_indent * _current_indent_level))
1713 : : }*/
1714 [ - + ]: 2081 : if (_PyAccu_Accumulate(acc, close_array))
1715 : 0 : goto bail;
1716 : 2081 : Py_DECREF(s_fast);
1717 : 2081 : return 0;
1718 : :
1719 : 61 : bail:
1720 : 61 : Py_XDECREF(ident);
1721 : 61 : Py_DECREF(s_fast);
1722 : 61 : return -1;
1723 : : }
1724 : :
1725 : : static void
1726 : 1110 : encoder_dealloc(PyObject *self)
1727 : : {
1728 : 1110 : PyTypeObject *tp = Py_TYPE(self);
1729 : : /* bpo-31095: UnTrack is needed before calling any callbacks */
1730 : 1110 : PyObject_GC_UnTrack(self);
1731 : 1110 : encoder_clear((PyEncoderObject *)self);
1732 : 1110 : tp->tp_free(self);
1733 : 1110 : Py_DECREF(tp);
1734 : 1110 : }
1735 : :
1736 : : static int
1737 : 4 : encoder_traverse(PyEncoderObject *self, visitproc visit, void *arg)
1738 : : {
1739 [ + - - + ]: 4 : Py_VISIT(Py_TYPE(self));
1740 [ + - - + ]: 4 : Py_VISIT(self->markers);
1741 [ + - - + ]: 4 : Py_VISIT(self->defaultfn);
1742 [ + - - + ]: 4 : Py_VISIT(self->encoder);
1743 [ + - - + ]: 4 : Py_VISIT(self->indent);
1744 [ + - - + ]: 4 : Py_VISIT(self->key_separator);
1745 [ + - - + ]: 4 : Py_VISIT(self->item_separator);
1746 : 4 : return 0;
1747 : : }
1748 : :
1749 : : static int
1750 : 1110 : encoder_clear(PyEncoderObject *self)
1751 : : {
1752 : : /* Deallocate Encoder */
1753 [ + - ]: 1110 : Py_CLEAR(self->markers);
1754 [ + - ]: 1110 : Py_CLEAR(self->defaultfn);
1755 [ + - ]: 1110 : Py_CLEAR(self->encoder);
1756 [ + - ]: 1110 : Py_CLEAR(self->indent);
1757 [ + - ]: 1110 : Py_CLEAR(self->key_separator);
1758 [ + - ]: 1110 : Py_CLEAR(self->item_separator);
1759 : 1110 : return 0;
1760 : : }
1761 : :
1762 : : PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable");
1763 : :
1764 : : static PyType_Slot PyEncoderType_slots[] = {
1765 : : {Py_tp_doc, (void *)encoder_doc},
1766 : : {Py_tp_dealloc, encoder_dealloc},
1767 : : {Py_tp_call, encoder_call},
1768 : : {Py_tp_traverse, encoder_traverse},
1769 : : {Py_tp_clear, encoder_clear},
1770 : : {Py_tp_members, encoder_members},
1771 : : {Py_tp_new, encoder_new},
1772 : : {0, 0}
1773 : : };
1774 : :
1775 : : static PyType_Spec PyEncoderType_spec = {
1776 : : .name = "_json.Encoder",
1777 : : .basicsize = sizeof(PyEncoderObject),
1778 : : .itemsize = 0,
1779 : : .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1780 : : .slots = PyEncoderType_slots
1781 : : };
1782 : :
1783 : : static PyMethodDef speedups_methods[] = {
1784 : : {"encode_basestring_ascii",
1785 : : (PyCFunction)py_encode_basestring_ascii,
1786 : : METH_O,
1787 : : pydoc_encode_basestring_ascii},
1788 : : {"encode_basestring",
1789 : : (PyCFunction)py_encode_basestring,
1790 : : METH_O,
1791 : : pydoc_encode_basestring},
1792 : : {"scanstring",
1793 : : (PyCFunction)py_scanstring,
1794 : : METH_VARARGS,
1795 : : pydoc_scanstring},
1796 : : {NULL, NULL, 0, NULL}
1797 : : };
1798 : :
1799 : : PyDoc_STRVAR(module_doc,
1800 : : "json speedups\n");
1801 : :
1802 : : static int
1803 : 551 : _json_exec(PyObject *module)
1804 : : {
1805 : 551 : PyObject *PyScannerType = PyType_FromSpec(&PyScannerType_spec);
1806 [ - + ]: 551 : if (PyScannerType == NULL) {
1807 : 0 : return -1;
1808 : : }
1809 : 551 : int rc = PyModule_AddObjectRef(module, "make_scanner", PyScannerType);
1810 : 551 : Py_DECREF(PyScannerType);
1811 [ - + ]: 551 : if (rc < 0) {
1812 : 0 : return -1;
1813 : : }
1814 : :
1815 : 551 : PyObject *PyEncoderType = PyType_FromSpec(&PyEncoderType_spec);
1816 [ - + ]: 551 : if (PyEncoderType == NULL) {
1817 : 0 : return -1;
1818 : : }
1819 : 551 : rc = PyModule_AddObjectRef(module, "make_encoder", PyEncoderType);
1820 : 551 : Py_DECREF(PyEncoderType);
1821 [ - + ]: 551 : if (rc < 0) {
1822 : 0 : return -1;
1823 : : }
1824 : :
1825 : 551 : return 0;
1826 : : }
1827 : :
1828 : : static PyModuleDef_Slot _json_slots[] = {
1829 : : {Py_mod_exec, _json_exec},
1830 : : {0, NULL}
1831 : : };
1832 : :
1833 : : static struct PyModuleDef jsonmodule = {
1834 : : .m_base = PyModuleDef_HEAD_INIT,
1835 : : .m_name = "_json",
1836 : : .m_doc = module_doc,
1837 : : .m_methods = speedups_methods,
1838 : : .m_slots = _json_slots,
1839 : : };
1840 : :
1841 : : PyMODINIT_FUNC
1842 : 551 : PyInit__json(void)
1843 : : {
1844 : 551 : return PyModuleDef_Init(&jsonmodule);
1845 : : }
|