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