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