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