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