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