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