xref: /vim-8.2.3635/src/json.c (revision d0bce504)
1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * json.c: Encoding and decoding JSON.
12  *
13  * Follows this standard: https://tools.ietf.org/html/rfc7159.html
14  */
15 #define USING_FLOAT_STUFF
16 
17 #include "vim.h"
18 
19 #if defined(FEAT_EVAL) || defined(PROTO)
20 
21 static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int options);
22 
23 static char e_json_error[] = N_("E491: json decode error at '%s'");
24 
25 /*
26  * Encode "val" into a JSON format string.
27  * The result is added to "gap"
28  * Returns FAIL on failure and makes gap->ga_data empty.
29  */
30     static int
31 json_encode_gap(garray_T *gap, typval_T *val, int options)
32 {
33     if (json_encode_item(gap, val, get_copyID(), options) == FAIL)
34     {
35 	ga_clear(gap);
36 	gap->ga_data = vim_strsave((char_u *)"");
37 	return FAIL;
38     }
39     return OK;
40 }
41 
42 /*
43  * Encode "val" into a JSON format string.
44  * The result is in allocated memory.
45  * The result is empty when encoding fails.
46  * "options" can contain JSON_JS, JSON_NO_NONE and JSON_NL.
47  */
48     char_u *
49 json_encode(typval_T *val, int options)
50 {
51     garray_T ga;
52 
53     // Store bytes in the growarray.
54     ga_init2(&ga, 1, 4000);
55     json_encode_gap(&ga, val, options);
56     ga_append(&ga, NUL);
57     return ga.ga_data;
58 }
59 
60 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
61 /*
62  * Encode ["nr", "val"] into a JSON format string in allocated memory.
63  * "options" can contain JSON_JS, JSON_NO_NONE and JSON_NL.
64  * Returns NULL when out of memory.
65  */
66     char_u *
67 json_encode_nr_expr(int nr, typval_T *val, int options)
68 {
69     typval_T	listtv;
70     typval_T	nrtv;
71     garray_T	ga;
72 
73     nrtv.v_type = VAR_NUMBER;
74     nrtv.vval.v_number = nr;
75     if (rettv_list_alloc(&listtv) == FAIL)
76 	return NULL;
77     if (list_append_tv(listtv.vval.v_list, &nrtv) == FAIL
78 	    || list_append_tv(listtv.vval.v_list, val) == FAIL)
79     {
80 	list_unref(listtv.vval.v_list);
81 	return NULL;
82     }
83 
84     ga_init2(&ga, 1, 4000);
85     if (json_encode_gap(&ga, &listtv, options) == OK && (options & JSON_NL))
86 	ga_append(&ga, '\n');
87     list_unref(listtv.vval.v_list);
88     ga_append(&ga, NUL);
89     return ga.ga_data;
90 }
91 #endif
92 
93     static void
94 write_string(garray_T *gap, char_u *str)
95 {
96     char_u	*res = str;
97     char_u	numbuf[NUMBUFLEN];
98 
99     if (res == NULL)
100 	ga_concat(gap, (char_u *)"\"\"");
101     else
102     {
103 #if defined(USE_ICONV)
104 	vimconv_T   conv;
105 	char_u	    *converted = NULL;
106 
107 	if (!enc_utf8)
108 	{
109 	    // Convert the text from 'encoding' to utf-8, the JSON string is
110 	    // always utf-8.
111 	    conv.vc_type = CONV_NONE;
112 	    convert_setup(&conv, p_enc, (char_u*)"utf-8");
113 	    if (conv.vc_type != CONV_NONE)
114 		converted = res = string_convert(&conv, res, NULL);
115 	    convert_setup(&conv, NULL, NULL);
116 	}
117 #endif
118 	ga_append(gap, '"');
119 	while (*res != NUL)
120 	{
121 	    int c;
122 	    // always use utf-8 encoding, ignore 'encoding'
123 	    c = utf_ptr2char(res);
124 
125 	    switch (c)
126 	    {
127 		case 0x08:
128 		    ga_append(gap, '\\'); ga_append(gap, 'b'); break;
129 		case 0x09:
130 		    ga_append(gap, '\\'); ga_append(gap, 't'); break;
131 		case 0x0a:
132 		    ga_append(gap, '\\'); ga_append(gap, 'n'); break;
133 		case 0x0c:
134 		    ga_append(gap, '\\'); ga_append(gap, 'f'); break;
135 		case 0x0d:
136 		    ga_append(gap, '\\'); ga_append(gap, 'r'); break;
137 		case 0x22: // "
138 		case 0x5c: // backslash
139 		    ga_append(gap, '\\');
140 		    ga_append(gap, c);
141 		    break;
142 		default:
143 		    if (c >= 0x20)
144 		    {
145 			numbuf[utf_char2bytes(c, numbuf)] = NUL;
146 			ga_concat(gap, numbuf);
147 		    }
148 		    else
149 		    {
150 			vim_snprintf((char *)numbuf, NUMBUFLEN,
151 							 "\\u%04lx", (long)c);
152 			ga_concat(gap, numbuf);
153 		    }
154 	    }
155 	    res += utf_ptr2len(res);
156 	}
157 	ga_append(gap, '"');
158 #if defined(USE_ICONV)
159 	vim_free(converted);
160 #endif
161     }
162 }
163 
164 /*
165  * Return TRUE if "key" can be used without quotes.
166  * That is when it starts with a letter and only contains letters, digits and
167  * underscore.
168  */
169     static int
170 is_simple_key(char_u *key)
171 {
172     char_u *p;
173 
174     if (!ASCII_ISALPHA(*key))
175 	return FALSE;
176     for (p = key + 1; *p != NUL; ++p)
177 	if (!ASCII_ISALPHA(*p) && *p != '_' && !vim_isdigit(*p))
178 	    return FALSE;
179     return TRUE;
180 }
181 
182 /*
183  * Encode "val" into "gap".
184  * Return FAIL or OK.
185  */
186     static int
187 json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
188 {
189     char_u	numbuf[NUMBUFLEN];
190     char_u	*res;
191     blob_T	*b;
192     list_T	*l;
193     dict_T	*d;
194     int		i;
195 
196     switch (val->v_type)
197     {
198 	case VAR_BOOL:
199 	    switch ((long)val->vval.v_number)
200 	    {
201 		case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
202 		case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
203 	    }
204 	    break;
205 
206 	case VAR_SPECIAL:
207 	    switch ((long)val->vval.v_number)
208 	    {
209 		case VVAL_NONE: if ((options & JSON_JS) != 0
210 					     && (options & JSON_NO_NONE) == 0)
211 				    // empty item
212 				    break;
213 				// FALLTHROUGH
214 		case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
215 	    }
216 	    break;
217 
218 	case VAR_NUMBER:
219 	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld",
220 					      (varnumber_T)val->vval.v_number);
221 	    ga_concat(gap, numbuf);
222 	    break;
223 
224 	case VAR_STRING:
225 	    res = val->vval.v_string;
226 	    write_string(gap, res);
227 	    break;
228 
229 	case VAR_FUNC:
230 	case VAR_PARTIAL:
231 	case VAR_JOB:
232 	case VAR_CHANNEL:
233 	    semsg(_(e_cannot_json_encode_str), vartype_name(val->v_type));
234 	    return FAIL;
235 
236 	case VAR_BLOB:
237 	    b = val->vval.v_blob;
238 	    if (b == NULL || b->bv_ga.ga_len == 0)
239 		ga_concat(gap, (char_u *)"[]");
240 	    else
241 	    {
242 		ga_append(gap, '[');
243 		for (i = 0; i < b->bv_ga.ga_len; i++)
244 		{
245 		    if (i > 0)
246 			ga_concat(gap, (char_u *)",");
247 		    vim_snprintf((char *)numbuf, NUMBUFLEN, "%d",
248 			    (int)blob_get(b, i));
249 		    ga_concat(gap, numbuf);
250 		}
251 		ga_append(gap, ']');
252 	    }
253 	    break;
254 
255 	case VAR_LIST:
256 	    l = val->vval.v_list;
257 	    if (l == NULL)
258 		ga_concat(gap, (char_u *)"[]");
259 	    else
260 	    {
261 		if (l->lv_copyID == copyID)
262 		    ga_concat(gap, (char_u *)"[]");
263 		else
264 		{
265 		    listitem_T	*li;
266 
267 		    l->lv_copyID = copyID;
268 		    ga_append(gap, '[');
269 		    CHECK_LIST_MATERIALIZE(l);
270 		    for (li = l->lv_first; li != NULL && !got_int; )
271 		    {
272 			if (json_encode_item(gap, &li->li_tv, copyID,
273 						   options & JSON_JS) == FAIL)
274 			    return FAIL;
275 			if ((options & JSON_JS)
276 				&& li->li_next == NULL
277 				&& li->li_tv.v_type == VAR_SPECIAL
278 				&& li->li_tv.vval.v_number == VVAL_NONE)
279 			    // add an extra comma if the last item is v:none
280 			    ga_append(gap, ',');
281 			li = li->li_next;
282 			if (li != NULL)
283 			    ga_append(gap, ',');
284 		    }
285 		    ga_append(gap, ']');
286 		    l->lv_copyID = 0;
287 		}
288 	    }
289 	    break;
290 
291 	case VAR_DICT:
292 	    d = val->vval.v_dict;
293 	    if (d == NULL)
294 		ga_concat(gap, (char_u *)"{}");
295 	    else
296 	    {
297 		if (d->dv_copyID == copyID)
298 		    ga_concat(gap, (char_u *)"{}");
299 		else
300 		{
301 		    int		first = TRUE;
302 		    int		todo = (int)d->dv_hashtab.ht_used;
303 		    hashitem_T	*hi;
304 
305 		    d->dv_copyID = copyID;
306 		    ga_append(gap, '{');
307 
308 		    for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int;
309 									 ++hi)
310 			if (!HASHITEM_EMPTY(hi))
311 			{
312 			    --todo;
313 			    if (first)
314 				first = FALSE;
315 			    else
316 				ga_append(gap, ',');
317 			    if ((options & JSON_JS)
318 						 && is_simple_key(hi->hi_key))
319 				ga_concat(gap, hi->hi_key);
320 			    else
321 				write_string(gap, hi->hi_key);
322 			    ga_append(gap, ':');
323 			    if (json_encode_item(gap, &dict_lookup(hi)->di_tv,
324 				      copyID, options | JSON_NO_NONE) == FAIL)
325 				return FAIL;
326 			}
327 		    ga_append(gap, '}');
328 		    d->dv_copyID = 0;
329 		}
330 	    }
331 	    break;
332 
333 	case VAR_FLOAT:
334 #ifdef FEAT_FLOAT
335 # if defined(HAVE_MATH_H)
336 	    if (isnan(val->vval.v_float))
337 		ga_concat(gap, (char_u *)"NaN");
338 	    else if (isinf(val->vval.v_float))
339 	    {
340 		if (val->vval.v_float < 0.0)
341 		    ga_concat(gap, (char_u *)"-Infinity");
342 		else
343 		    ga_concat(gap, (char_u *)"Infinity");
344 	    }
345 	    else
346 # endif
347 	    {
348 		vim_snprintf((char *)numbuf, NUMBUFLEN, "%g",
349 							   val->vval.v_float);
350 		ga_concat(gap, numbuf);
351 	    }
352 	    break;
353 #endif
354 	case VAR_UNKNOWN:
355 	case VAR_ANY:
356 	case VAR_VOID:
357 	    internal_error_no_abort("json_encode_item()");
358 	    return FAIL;
359     }
360     return OK;
361 }
362 
363 /*
364  * When "reader" has less than NUMBUFLEN bytes available, call the fill
365  * callback to get more.
366  */
367     static void
368 fill_numbuflen(js_read_T *reader)
369 {
370     if (reader->js_fill != NULL && (int)(reader->js_end - reader->js_buf)
371 						- reader->js_used < NUMBUFLEN)
372     {
373 	if (reader->js_fill(reader))
374 	    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
375     }
376 }
377 
378 /*
379  * Skip white space in "reader".  All characters <= space are considered white
380  * space.
381  * Also tops up readahead when needed.
382  */
383     static void
384 json_skip_white(js_read_T *reader)
385 {
386     int c;
387 
388     for (;;)
389     {
390 	c = reader->js_buf[reader->js_used];
391 	if (reader->js_fill != NULL && c == NUL)
392 	{
393 	    if (reader->js_fill(reader))
394 	    {
395 		reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
396 		continue;
397 	    }
398 	}
399 	if (c == NUL || c > ' ')
400 	    break;
401 	++reader->js_used;
402     }
403     fill_numbuflen(reader);
404 }
405 
406     static int
407 json_decode_string(js_read_T *reader, typval_T *res, int quote)
408 {
409     garray_T    ga;
410     int		len;
411     char_u	*p;
412     int		c;
413     varnumber_T	nr;
414 
415     if (res != NULL)
416 	ga_init2(&ga, 1, 200);
417 
418     p = reader->js_buf + reader->js_used + 1; // skip over " or '
419     while (*p != quote)
420     {
421 	// The JSON is always expected to be utf-8, thus use utf functions
422 	// here. The string is converted below if needed.
423 	if (*p == NUL || p[1] == NUL || utf_ptr2len(p) < utf_byte2len(*p))
424 	{
425 	    // Not enough bytes to make a character or end of the string. Get
426 	    // more if possible.
427 	    if (reader->js_fill == NULL)
428 		break;
429 	    len = (int)(reader->js_end - p);
430 	    reader->js_used = (int)(p - reader->js_buf);
431 	    if (!reader->js_fill(reader))
432 		break; // didn't get more
433 	    p = reader->js_buf + reader->js_used;
434 	    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
435 	    continue;
436 	}
437 
438 	if (*p == '\\')
439 	{
440 	    c = -1;
441 	    switch (p[1])
442 	    {
443 		case '\\': c = '\\'; break;
444 		case '"': c = '"'; break;
445 		case 'b': c = BS; break;
446 		case 't': c = TAB; break;
447 		case 'n': c = NL; break;
448 		case 'f': c = FF; break;
449 		case 'r': c = CAR; break;
450 		case 'u':
451 		    if (reader->js_fill != NULL
452 				     && (int)(reader->js_end - p) < NUMBUFLEN)
453 		    {
454 			reader->js_used = (int)(p - reader->js_buf);
455 			if (reader->js_fill(reader))
456 			{
457 			    p = reader->js_buf + reader->js_used;
458 			    reader->js_end = reader->js_buf
459 						     + STRLEN(reader->js_buf);
460 			}
461 		    }
462 		    nr = 0;
463 		    len = 0;
464 		    vim_str2nr(p + 2, NULL, &len,
465 			     STR2NR_HEX + STR2NR_FORCE, &nr, NULL, 4, TRUE);
466 		    if (len == 0)
467 		    {
468 			if (res != NULL)
469 			    ga_clear(&ga);
470 			return FAIL;
471 		    }
472 		    p += len + 2;
473 		    if (0xd800 <= nr && nr <= 0xdfff
474 			    && (int)(reader->js_end - p) >= 6
475 			    && *p == '\\' && *(p+1) == 'u')
476 		    {
477 			varnumber_T	nr2 = 0;
478 
479 			// decode surrogate pair: \ud812\u3456
480 			len = 0;
481 			vim_str2nr(p + 2, NULL, &len,
482 			     STR2NR_HEX + STR2NR_FORCE, &nr2, NULL, 4, TRUE);
483 			if (len == 0)
484 			{
485 			    if (res != NULL)
486 				ga_clear(&ga);
487 			    return FAIL;
488 			}
489 			if (0xdc00 <= nr2 && nr2 <= 0xdfff)
490 			{
491 			    p += len + 2;
492 			    nr = (((nr - 0xd800) << 10) |
493 				((nr2 - 0xdc00) & 0x3ff)) + 0x10000;
494 			}
495 		    }
496 		    if (res != NULL)
497 		    {
498 			char_u	buf[NUMBUFLEN];
499 
500 			buf[utf_char2bytes((int)nr, buf)] = NUL;
501 			ga_concat(&ga, buf);
502 		    }
503 		    break;
504 		default:
505 		    // not a special char, skip over backslash
506 		    ++p;
507 		    continue;
508 	    }
509 	    if (c > 0)
510 	    {
511 		p += 2;
512 		if (res != NULL)
513 		    ga_append(&ga, c);
514 	    }
515 	}
516 	else
517 	{
518 	    len = utf_ptr2len(p);
519 	    if (res != NULL)
520 	    {
521 		if (ga_grow(&ga, len) == FAIL)
522 		{
523 		    ga_clear(&ga);
524 		    return FAIL;
525 		}
526 		mch_memmove((char *)ga.ga_data + ga.ga_len, p, (size_t)len);
527 		ga.ga_len += len;
528 	    }
529 	    p += len;
530 	}
531     }
532 
533     reader->js_used = (int)(p - reader->js_buf);
534     if (*p == quote)
535     {
536 	++reader->js_used;
537 	if (res != NULL)
538 	{
539 	    ga_append(&ga, NUL);
540 	    res->v_type = VAR_STRING;
541 #if defined(USE_ICONV)
542 	    if (!enc_utf8)
543 	    {
544 		vimconv_T   conv;
545 
546 		// Convert the utf-8 string to 'encoding'.
547 		conv.vc_type = CONV_NONE;
548 		convert_setup(&conv, (char_u*)"utf-8", p_enc);
549 		if (conv.vc_type != CONV_NONE)
550 		{
551 		    res->vval.v_string =
552 				      string_convert(&conv, ga.ga_data, NULL);
553 		    vim_free(ga.ga_data);
554 		}
555 		convert_setup(&conv, NULL, NULL);
556 	    }
557 	    else
558 #endif
559 		res->vval.v_string = ga.ga_data;
560 	}
561 	return OK;
562     }
563     if (res != NULL)
564     {
565 	res->v_type = VAR_SPECIAL;
566 	res->vval.v_number = VVAL_NONE;
567 	ga_clear(&ga);
568     }
569     return MAYBE;
570 }
571 
572 typedef enum {
573     JSON_ARRAY,		// parsing items in an array
574     JSON_OBJECT_KEY,	// parsing key of an object
575     JSON_OBJECT		// parsing item in an object, after the key
576 } json_decode_T;
577 
578 typedef struct {
579     json_decode_T jd_type;
580     typval_T	  jd_tv;	// the list or dict
581     typval_T	  jd_key_tv;
582     char_u	  *jd_key;
583 } json_dec_item_T;
584 
585 /*
586  * Decode one item and put it in "res".  If "res" is NULL only advance.
587  * Must already have skipped white space.
588  *
589  * Return FAIL for a decoding error (and give an error).
590  * Return MAYBE for an incomplete message.
591  */
592     static int
593 json_decode_item(js_read_T *reader, typval_T *res, int options)
594 {
595     char_u	*p;
596     int		i;
597     int		len;
598     int		retval;
599     garray_T	stack;
600     typval_T	item;
601     typval_T	*cur_item;
602     json_dec_item_T *top_item;
603     char_u	key_buf[NUMBUFLEN];
604 
605     ga_init2(&stack, sizeof(json_dec_item_T), 100);
606     cur_item = res;
607     init_tv(&item);
608     if (res != NULL)
609     init_tv(res);
610 
611     fill_numbuflen(reader);
612     p = reader->js_buf + reader->js_used;
613     for (;;)
614     {
615 	top_item = NULL;
616 	if (stack.ga_len > 0)
617 	{
618 	    top_item = ((json_dec_item_T *)stack.ga_data) + stack.ga_len - 1;
619 	    json_skip_white(reader);
620 	    p = reader->js_buf + reader->js_used;
621 	    if (*p == NUL)
622 	    {
623 		retval = MAYBE;
624 		goto theend;
625 	    }
626 	    if (top_item->jd_type == JSON_OBJECT_KEY
627 					    || top_item->jd_type == JSON_ARRAY)
628 	    {
629 		// Check for end of object or array.
630 		if (*p == (top_item->jd_type == JSON_ARRAY ? ']' : '}'))
631 		{
632 		    ++reader->js_used; // consume the ']' or '}'
633 		    --stack.ga_len;
634 		    if (stack.ga_len == 0)
635 		    {
636 			retval = OK;
637 			goto theend;
638 		    }
639 		    if (cur_item != NULL)
640 			cur_item = &top_item->jd_tv;
641 		    goto item_end;
642 		}
643 	    }
644 	}
645 
646 	if (top_item != NULL && top_item->jd_type == JSON_OBJECT_KEY
647 		&& (options & JSON_JS)
648 		&& reader->js_buf[reader->js_used] != '"'
649 		&& reader->js_buf[reader->js_used] != '\''
650 		&& reader->js_buf[reader->js_used] != '['
651 		&& reader->js_buf[reader->js_used] != '{')
652 	{
653 	    char_u *key;
654 
655 	    // accept an object key that is not in quotes
656 	    key = p = reader->js_buf + reader->js_used;
657 	    while (*p != NUL && *p != ':' && *p > ' ')
658 		++p;
659 	    if (cur_item != NULL)
660 	    {
661 		cur_item->v_type = VAR_STRING;
662 		cur_item->vval.v_string = vim_strnsave(key, p - key);
663 		top_item->jd_key = cur_item->vval.v_string;
664 	    }
665 	    reader->js_used += (int)(p - key);
666 	}
667 	else
668 	{
669 	    switch (*p)
670 	    {
671 		case '[': // start of array
672 		    if (top_item && top_item->jd_type == JSON_OBJECT_KEY)
673 		    {
674 			retval = FAIL;
675 			break;
676 		    }
677 		    if (ga_grow(&stack, 1) == FAIL)
678 		    {
679 			retval = FAIL;
680 			break;
681 		    }
682 		    if (cur_item != NULL && rettv_list_alloc(cur_item) == FAIL)
683 		    {
684 			cur_item->v_type = VAR_SPECIAL;
685 			cur_item->vval.v_number = VVAL_NONE;
686 			retval = FAIL;
687 			break;
688 		    }
689 
690 		    ++reader->js_used; // consume the '['
691 		    top_item = ((json_dec_item_T *)stack.ga_data)
692 								+ stack.ga_len;
693 		    top_item->jd_type = JSON_ARRAY;
694 		    ++stack.ga_len;
695 		    if (cur_item != NULL)
696 		    {
697 			top_item->jd_tv = *cur_item;
698 			cur_item = &item;
699 		    }
700 		    continue;
701 
702 		case '{': // start of object
703 		    if (top_item && top_item->jd_type == JSON_OBJECT_KEY)
704 		    {
705 			retval = FAIL;
706 			break;
707 		    }
708 		    if (ga_grow(&stack, 1) == FAIL)
709 		    {
710 			retval = FAIL;
711 			break;
712 		    }
713 		    if (cur_item != NULL && rettv_dict_alloc(cur_item) == FAIL)
714 		    {
715 			cur_item->v_type = VAR_SPECIAL;
716 			cur_item->vval.v_number = VVAL_NONE;
717 			retval = FAIL;
718 			break;
719 		    }
720 
721 		    ++reader->js_used; // consume the '{'
722 		    top_item = ((json_dec_item_T *)stack.ga_data)
723 								+ stack.ga_len;
724 		    top_item->jd_type = JSON_OBJECT_KEY;
725 		    ++stack.ga_len;
726 		    if (cur_item != NULL)
727 		    {
728 			top_item->jd_tv = *cur_item;
729 			cur_item = &top_item->jd_key_tv;
730 		    }
731 		    continue;
732 
733 		case '"': // string
734 		    retval = json_decode_string(reader, cur_item, *p);
735 		    break;
736 
737 		case '\'':
738 		    if (options & JSON_JS)
739 			retval = json_decode_string(reader, cur_item, *p);
740 		    else
741 		    {
742 			semsg(_(e_json_error), p);
743 			retval = FAIL;
744 		    }
745 		    break;
746 
747 		case ',': // comma: empty item
748 		    if ((options & JSON_JS) == 0)
749 		    {
750 			semsg(_(e_json_error), p);
751 			retval = FAIL;
752 			break;
753 		    }
754 		    // FALLTHROUGH
755 		case NUL: // empty
756 		    if (cur_item != NULL)
757 		    {
758 			cur_item->v_type = VAR_SPECIAL;
759 			cur_item->vval.v_number = VVAL_NONE;
760 		    }
761 		    retval = OK;
762 		    break;
763 
764 		default:
765 		    if (VIM_ISDIGIT(*p) || (*p == '-'
766 					&& (VIM_ISDIGIT(p[1]) || p[1] == NUL)))
767 		    {
768 			char_u  *sp = p;
769 
770 			if (*sp == '-')
771 			{
772 			    ++sp;
773 			    if (*sp == NUL)
774 			    {
775 				retval = MAYBE;
776 				break;
777 			    }
778 			    if (!VIM_ISDIGIT(*sp))
779 			    {
780 				semsg(_(e_json_error), p);
781 				retval = FAIL;
782 				break;
783 			    }
784 			}
785 			sp = skipdigits(sp);
786 #ifdef FEAT_FLOAT
787 			if (*sp == '.' || *sp == 'e' || *sp == 'E')
788 			{
789 			    if (cur_item == NULL)
790 			    {
791 				float_T f;
792 
793 				len = string2float(p, &f);
794 			    }
795 			    else
796 			    {
797 				cur_item->v_type = VAR_FLOAT;
798 				len = string2float(p, &cur_item->vval.v_float);
799 			    }
800 			}
801 			else
802 #endif
803 			{
804 			    varnumber_T nr;
805 
806 			    vim_str2nr(reader->js_buf + reader->js_used,
807 				    NULL, &len, 0, // what
808 				    &nr, NULL, 0, TRUE);
809 			    if (len == 0)
810 			    {
811 				semsg(_(e_json_error), p);
812 				retval = FAIL;
813 				goto theend;
814 			    }
815 			    if (cur_item != NULL)
816 			    {
817 				cur_item->v_type = VAR_NUMBER;
818 				cur_item->vval.v_number = nr;
819 			    }
820 			}
821 			reader->js_used += len;
822 			retval = OK;
823 			break;
824 		    }
825 		    if (STRNICMP((char *)p, "false", 5) == 0)
826 		    {
827 			reader->js_used += 5;
828 			if (cur_item != NULL)
829 			{
830 			    cur_item->v_type = VAR_BOOL;
831 			    cur_item->vval.v_number = VVAL_FALSE;
832 			}
833 			retval = OK;
834 			break;
835 		    }
836 		    if (STRNICMP((char *)p, "true", 4) == 0)
837 		    {
838 			reader->js_used += 4;
839 			if (cur_item != NULL)
840 			{
841 			    cur_item->v_type = VAR_BOOL;
842 			    cur_item->vval.v_number = VVAL_TRUE;
843 			}
844 			retval = OK;
845 			break;
846 		    }
847 		    if (STRNICMP((char *)p, "null", 4) == 0)
848 		    {
849 			reader->js_used += 4;
850 			if (cur_item != NULL)
851 			{
852 			    cur_item->v_type = VAR_SPECIAL;
853 			    cur_item->vval.v_number = VVAL_NULL;
854 			}
855 			retval = OK;
856 			break;
857 		    }
858 #ifdef FEAT_FLOAT
859 		    if (STRNICMP((char *)p, "NaN", 3) == 0)
860 		    {
861 			reader->js_used += 3;
862 			if (cur_item != NULL)
863 			{
864 			    cur_item->v_type = VAR_FLOAT;
865 			    cur_item->vval.v_float = NAN;
866 			}
867 			retval = OK;
868 			break;
869 		    }
870 		    if (STRNICMP((char *)p, "-Infinity", 9) == 0)
871 		    {
872 			reader->js_used += 9;
873 			if (cur_item != NULL)
874 			{
875 			    cur_item->v_type = VAR_FLOAT;
876 			    cur_item->vval.v_float = -INFINITY;
877 			}
878 			retval = OK;
879 			break;
880 		    }
881 		    if (STRNICMP((char *)p, "Infinity", 8) == 0)
882 		    {
883 			reader->js_used += 8;
884 			if (cur_item != NULL)
885 			{
886 			    cur_item->v_type = VAR_FLOAT;
887 			    cur_item->vval.v_float = INFINITY;
888 			}
889 			retval = OK;
890 			break;
891 		    }
892 #endif
893 		    // check for truncated name
894 		    len = (int)(reader->js_end
895 					 - (reader->js_buf + reader->js_used));
896 		    if (
897 			    (len < 5 && STRNICMP((char *)p, "false", len) == 0)
898 #ifdef FEAT_FLOAT
899 			    || (len < 9 && STRNICMP((char *)p, "-Infinity", len) == 0)
900 			    || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
901 			    || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
902 #endif
903 			    || (len < 4 && (STRNICMP((char *)p, "true", len) == 0
904 				       ||  STRNICMP((char *)p, "null", len) == 0)))
905 
906 			retval = MAYBE;
907 		    else
908 			retval = FAIL;
909 		    break;
910 	    }
911 
912 	    // We are finished when retval is FAIL or MAYBE and when at the
913 	    // toplevel.
914 	    if (retval == FAIL)
915 		break;
916 	    if (retval == MAYBE || stack.ga_len == 0)
917 		goto theend;
918 
919 	    if (top_item != NULL && top_item->jd_type == JSON_OBJECT_KEY
920 		    && cur_item != NULL)
921 	    {
922 		top_item->jd_key = tv_get_string_buf_chk(cur_item, key_buf);
923 		if (top_item->jd_key == NULL)
924 		{
925 		    emsg(_(e_invarg));
926 		    retval = FAIL;
927 		    goto theend;
928 		}
929 	    }
930 	}
931 
932 item_end:
933 	top_item = ((json_dec_item_T *)stack.ga_data) + stack.ga_len - 1;
934 	switch (top_item->jd_type)
935 	{
936 	    case JSON_ARRAY:
937 		if (res != NULL)
938 		{
939 		    listitem_T	*li = listitem_alloc();
940 
941 		    if (li == NULL)
942 		    {
943 			clear_tv(cur_item);
944 			retval = FAIL;
945 			goto theend;
946 		    }
947 		    li->li_tv = *cur_item;
948 		    list_append(top_item->jd_tv.vval.v_list, li);
949 		}
950 		if (cur_item != NULL)
951 		    cur_item = &item;
952 
953 		json_skip_white(reader);
954 		p = reader->js_buf + reader->js_used;
955 		if (*p == ',')
956 		    ++reader->js_used;
957 		else if (*p != ']')
958 		{
959 		    if (*p == NUL)
960 			retval = MAYBE;
961 		    else
962 		    {
963 			semsg(_(e_json_error), p);
964 			retval = FAIL;
965 		    }
966 		    goto theend;
967 		}
968 		break;
969 
970 	    case JSON_OBJECT_KEY:
971 		json_skip_white(reader);
972 		p = reader->js_buf + reader->js_used;
973 		if (*p != ':')
974 		{
975 		    if (cur_item != NULL)
976 			clear_tv(cur_item);
977 		    if (*p == NUL)
978 			retval = MAYBE;
979 		    else
980 		    {
981 			semsg(_(e_json_error), p);
982 			retval = FAIL;
983 		    }
984 		    goto theend;
985 		}
986 		++reader->js_used;
987 		json_skip_white(reader);
988 		top_item->jd_type = JSON_OBJECT;
989 		if (cur_item != NULL)
990 		    cur_item = &item;
991 		break;
992 
993 	    case JSON_OBJECT:
994 		if (cur_item != NULL
995 			&& dict_find(top_item->jd_tv.vval.v_dict,
996 						 top_item->jd_key, -1) != NULL)
997 		{
998 		    semsg(_("E938: Duplicate key in JSON: \"%s\""),
999 							     top_item->jd_key);
1000 		    clear_tv(cur_item);
1001 		    retval = FAIL;
1002 		    goto theend;
1003 		}
1004 
1005 		if (cur_item != NULL)
1006 		{
1007 		    dictitem_T *di = dictitem_alloc(top_item->jd_key);
1008 
1009 		    clear_tv(&top_item->jd_key_tv);
1010 		    if (di == NULL)
1011 		    {
1012 			clear_tv(cur_item);
1013 			retval = FAIL;
1014 			goto theend;
1015 		    }
1016 		    di->di_tv = *cur_item;
1017 		    di->di_tv.v_lock = 0;
1018 		    if (dict_add(top_item->jd_tv.vval.v_dict, di) == FAIL)
1019 		    {
1020 			dictitem_free(di);
1021 			retval = FAIL;
1022 			goto theend;
1023 		    }
1024 		}
1025 
1026 		json_skip_white(reader);
1027 		p = reader->js_buf + reader->js_used;
1028 		if (*p == ',')
1029 		    ++reader->js_used;
1030 		else if (*p != '}')
1031 		{
1032 		    if (*p == NUL)
1033 			retval = MAYBE;
1034 		    else
1035 		    {
1036 			semsg(_(e_json_error), p);
1037 			retval = FAIL;
1038 		    }
1039 		    goto theend;
1040 		}
1041 		top_item->jd_type = JSON_OBJECT_KEY;
1042 		if (cur_item != NULL)
1043 		    cur_item = &top_item->jd_key_tv;
1044 		break;
1045 	}
1046     }
1047 
1048     // Get here when parsing failed.
1049     if (res != NULL)
1050     {
1051 	clear_tv(res);
1052 	res->v_type = VAR_SPECIAL;
1053 	res->vval.v_number = VVAL_NONE;
1054     }
1055     semsg(_(e_json_error), p);
1056 
1057 theend:
1058     for (i = 0; i < stack.ga_len; i++)
1059 	clear_tv(&(((json_dec_item_T *)stack.ga_data) + i)->jd_key_tv);
1060     ga_clear(&stack);
1061 
1062     return retval;
1063 }
1064 
1065 /*
1066  * Decode the JSON from "reader" and store the result in "res".
1067  * "options" can be JSON_JS or zero;
1068  * Return FAIL if not the whole message was consumed.
1069  */
1070     static int
1071 json_decode_all(js_read_T *reader, typval_T *res, int options)
1072 {
1073     int ret;
1074 
1075     // We find the end once, to avoid calling strlen() many times.
1076     reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
1077     json_skip_white(reader);
1078     ret = json_decode_item(reader, res, options);
1079     if (ret != OK)
1080     {
1081 	if (ret == MAYBE)
1082 	    semsg(_(e_json_error), reader->js_buf);
1083 	return FAIL;
1084     }
1085     json_skip_white(reader);
1086     if (reader->js_buf[reader->js_used] != NUL)
1087     {
1088 	semsg(_(e_trailing_arg), reader->js_buf + reader->js_used);
1089 	return FAIL;
1090     }
1091     return OK;
1092 }
1093 
1094 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
1095 /*
1096  * Decode the JSON from "reader" and store the result in "res".
1097  * "options" can be JSON_JS or zero;
1098  * Return FAIL for a decoding error.
1099  * Return MAYBE for an incomplete message.
1100  * Consumes the message anyway.
1101  */
1102     int
1103 json_decode(js_read_T *reader, typval_T *res, int options)
1104 {
1105     int ret;
1106 
1107     // We find the end once, to avoid calling strlen() many times.
1108     reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
1109     json_skip_white(reader);
1110     ret = json_decode_item(reader, res, options);
1111     json_skip_white(reader);
1112 
1113     return ret;
1114 }
1115 #endif
1116 
1117 /*
1118  * Decode the JSON from "reader" to find the end of the message.
1119  * "options" can be JSON_JS or zero.
1120  * This is only used for testing.
1121  * Return FAIL if the message has a decoding error.
1122  * Return MAYBE if the message is truncated, need to read more.
1123  * This only works reliable if the message contains an object, array or
1124  * string.  A number might be truncated without knowing.
1125  * Does not advance the reader.
1126  */
1127     int
1128 json_find_end(js_read_T *reader, int options)
1129 {
1130     int used_save = reader->js_used;
1131     int ret;
1132 
1133     // We find the end once, to avoid calling strlen() many times.
1134     reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
1135     json_skip_white(reader);
1136     ret = json_decode_item(reader, NULL, options);
1137     reader->js_used = used_save;
1138     return ret;
1139 }
1140 
1141 /*
1142  * "js_decode()" function
1143  */
1144     void
1145 f_js_decode(typval_T *argvars, typval_T *rettv)
1146 {
1147     js_read_T	reader;
1148 
1149     reader.js_buf = tv_get_string(&argvars[0]);
1150     reader.js_fill = NULL;
1151     reader.js_used = 0;
1152     if (json_decode_all(&reader, rettv, JSON_JS) != OK)
1153 	emsg(_(e_invarg));
1154 }
1155 
1156 /*
1157  * "js_encode()" function
1158  */
1159     void
1160 f_js_encode(typval_T *argvars, typval_T *rettv)
1161 {
1162     rettv->v_type = VAR_STRING;
1163     rettv->vval.v_string = json_encode(&argvars[0], JSON_JS);
1164 }
1165 
1166 /*
1167  * "json_decode()" function
1168  */
1169     void
1170 f_json_decode(typval_T *argvars, typval_T *rettv)
1171 {
1172     js_read_T	reader;
1173 
1174     reader.js_buf = tv_get_string(&argvars[0]);
1175     reader.js_fill = NULL;
1176     reader.js_used = 0;
1177     json_decode_all(&reader, rettv, 0);
1178 }
1179 
1180 /*
1181  * "json_encode()" function
1182  */
1183     void
1184 f_json_encode(typval_T *argvars, typval_T *rettv)
1185 {
1186     rettv->v_type = VAR_STRING;
1187     rettv->vval.v_string = json_encode(&argvars[0], 0);
1188 }
1189 #endif
1190