Skip to content

Commit 03c60c1

Browse files
committed
patch 8.0.0166: JSON with a duplicate key gives an internal error
Problem: JSON with a duplicate key gives an internal error. (Lcd) Solution: Give a normal error. Avoid an error when parsing JSON from a remote client fails.
1 parent f446b48 commit 03c60c1

File tree

5 files changed

+36
-5
lines changed

5 files changed

+36
-5
lines changed

src/channel.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1896,9 +1896,12 @@ channel_parse_json(channel_T *channel, ch_part_T part)
18961896

18971897
/* When a message is incomplete we wait for a short while for more to
18981898
* arrive. After the delay drop the input, otherwise a truncated string
1899-
* or list will make us hang. */
1899+
* or list will make us hang.
1900+
* Do not generate error messages, they will be written in a channel log. */
1901+
++emsg_silent;
19001902
status = json_decode(&reader, &listtv,
19011903
chanpart->ch_mode == MODE_JS ? JSON_JS : 0);
1904+
--emsg_silent;
19021905
if (status == OK)
19031906
{
19041907
/* Only accept the response when it is a list with at least two

src/evalfunc.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6818,8 +6818,7 @@ f_json_decode(typval_T *argvars, typval_T *rettv)
68186818
reader.js_buf = get_tv_string(&argvars[0]);
68196819
reader.js_fill = NULL;
68206820
reader.js_used = 0;
6821-
if (json_decode_all(&reader, rettv, 0) != OK)
6822-
EMSG(_(e_invarg));
6821+
json_decode_all(&reader, rettv, 0);
68236822
}
68246823

68256824
/*

src/json.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ json_decode_array(js_read_T *reader, typval_T *res, int options)
428428
{
429429
if (*p == NUL)
430430
return MAYBE;
431+
EMSG(_(e_invarg));
431432
return FAIL;
432433
}
433434
}
@@ -488,6 +489,7 @@ json_decode_object(js_read_T *reader, typval_T *res, int options)
488489
if (key == NULL || *key == NUL)
489490
{
490491
clear_tv(&tvkey);
492+
EMSG(_(e_invarg));
491493
return FAIL;
492494
}
493495
}
@@ -501,6 +503,7 @@ json_decode_object(js_read_T *reader, typval_T *res, int options)
501503
clear_tv(&tvkey);
502504
if (*p == NUL)
503505
return MAYBE;
506+
EMSG(_(e_invarg));
504507
return FAIL;
505508
}
506509
++reader->js_used;
@@ -514,6 +517,14 @@ json_decode_object(js_read_T *reader, typval_T *res, int options)
514517
return ret;
515518
}
516519

520+
if (res != NULL && dict_find(res->vval.v_dict, key, -1) != NULL)
521+
{
522+
EMSG2(_("E937: Duplicate key in JSON: \"%s\""), key);
523+
clear_tv(&tvkey);
524+
clear_tv(&item);
525+
return FAIL;
526+
}
527+
517528
if (res != NULL)
518529
{
519530
di = dictitem_alloc(key);
@@ -540,6 +551,7 @@ json_decode_object(js_read_T *reader, typval_T *res, int options)
540551
{
541552
if (*p == NUL)
542553
return MAYBE;
554+
EMSG(_(e_invarg));
543555
return FAIL;
544556
}
545557
}
@@ -715,7 +727,7 @@ json_decode_string(js_read_T *reader, typval_T *res)
715727
* Decode one item and put it in "res". If "res" is NULL only advance.
716728
* Must already have skipped white space.
717729
*
718-
* Return FAIL for a decoding error.
730+
* Return FAIL for a decoding error (and give an error).
719731
* Return MAYBE for an incomplete message.
720732
*/
721733
static int
@@ -739,7 +751,10 @@ json_decode_item(js_read_T *reader, typval_T *res, int options)
739751

740752
case ',': /* comma: empty item */
741753
if ((options & JSON_JS) == 0)
754+
{
755+
EMSG(_(e_invarg));
742756
return FAIL;
757+
}
743758
/* FALLTHROUGH */
744759
case NUL: /* empty */
745760
if (res != NULL)
@@ -761,7 +776,10 @@ json_decode_item(js_read_T *reader, typval_T *res, int options)
761776
if (*sp == NUL)
762777
return MAYBE;
763778
if (!VIM_ISDIGIT(*sp))
779+
{
780+
EMSG(_(e_invarg));
764781
return FAIL;
782+
}
765783
}
766784
sp = skipdigits(sp);
767785
if (*sp == '.' || *sp == 'e' || *sp == 'E')
@@ -866,6 +884,7 @@ json_decode_item(js_read_T *reader, typval_T *res, int options)
866884
res->v_type = VAR_SPECIAL;
867885
res->vval.v_number = VVAL_NONE;
868886
}
887+
EMSG(_(e_invarg));
869888
return FAIL;
870889
}
871890

@@ -884,10 +903,17 @@ json_decode_all(js_read_T *reader, typval_T *res, int options)
884903
json_skip_white(reader);
885904
ret = json_decode_item(reader, res, options);
886905
if (ret != OK)
906+
{
907+
if (ret == MAYBE)
908+
EMSG(_(e_invarg));
887909
return FAIL;
910+
}
888911
json_skip_white(reader);
889912
if (reader->js_buf[reader->js_used] != NUL)
913+
{
914+
EMSG(_(e_trailing));
890915
return FAIL;
916+
}
891917
return OK;
892918
}
893919

src/testdir/test_json.vim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ func Test_json_decode()
148148

149149
call assert_fails('call json_decode("\"")', "E474:")
150150
call assert_fails('call json_decode("blah")', "E474:")
151-
call assert_fails('call json_decode("true blah")', "E474:")
151+
call assert_fails('call json_decode("true blah")', "E488:")
152152
call assert_fails('call json_decode("<foobar>")', "E474:")
153+
call assert_fails('call json_decode("{\"a\":1,\"a\":2}")', "E937:")
153154

154155
call assert_fails('call json_decode("{")', "E474:")
155156
call assert_fails('call json_decode("{foobar}")', "E474:")

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
166,
767769
/**/
768770
165,
769771
/**/

0 commit comments

Comments
 (0)