To: vim_dev@googlegroups.com Subject: Patch 8.0.0166 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0166 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. Files: src/evalfunc.c, src/json.c, src/channel.c, src/testdir/test_json.vim *** ../vim-8.0.0165/src/evalfunc.c 2017-01-08 13:25:47.626339783 +0100 --- src/evalfunc.c 2017-01-10 14:19:11.339009907 +0100 *************** *** 6818,6825 **** reader.js_buf = get_tv_string(&argvars[0]); reader.js_fill = NULL; reader.js_used = 0; ! if (json_decode_all(&reader, rettv, 0) != OK) ! EMSG(_(e_invarg)); } /* --- 6818,6824 ---- reader.js_buf = get_tv_string(&argvars[0]); reader.js_fill = NULL; reader.js_used = 0; ! json_decode_all(&reader, rettv, 0); } /* *** ../vim-8.0.0165/src/json.c 2016-11-10 20:01:41.193582919 +0100 --- src/json.c 2017-01-10 14:25:22.032328415 +0100 *************** *** 428,433 **** --- 428,434 ---- { if (*p == NUL) return MAYBE; + EMSG(_(e_invarg)); return FAIL; } } *************** *** 488,493 **** --- 489,495 ---- if (key == NULL || *key == NUL) { clear_tv(&tvkey); + EMSG(_(e_invarg)); return FAIL; } } *************** *** 501,506 **** --- 503,509 ---- clear_tv(&tvkey); if (*p == NUL) return MAYBE; + EMSG(_(e_invarg)); return FAIL; } ++reader->js_used; *************** *** 514,519 **** --- 517,530 ---- return ret; } + if (res != NULL && dict_find(res->vval.v_dict, key, -1) != NULL) + { + EMSG2(_("E937: Duplicate key in JSON: \"%s\""), key); + clear_tv(&tvkey); + clear_tv(&item); + return FAIL; + } + if (res != NULL) { di = dictitem_alloc(key); *************** *** 540,545 **** --- 551,557 ---- { if (*p == NUL) return MAYBE; + EMSG(_(e_invarg)); return FAIL; } } *************** *** 715,721 **** * Decode one item and put it in "res". If "res" is NULL only advance. * Must already have skipped white space. * ! * Return FAIL for a decoding error. * Return MAYBE for an incomplete message. */ static int --- 727,733 ---- * Decode one item and put it in "res". If "res" is NULL only advance. * Must already have skipped white space. * ! * Return FAIL for a decoding error (and give an error). * Return MAYBE for an incomplete message. */ static int *************** *** 739,745 **** --- 751,760 ---- case ',': /* comma: empty item */ if ((options & JSON_JS) == 0) + { + EMSG(_(e_invarg)); return FAIL; + } /* FALLTHROUGH */ case NUL: /* empty */ if (res != NULL) *************** *** 761,767 **** --- 776,785 ---- if (*sp == NUL) return MAYBE; if (!VIM_ISDIGIT(*sp)) + { + EMSG(_(e_invarg)); return FAIL; + } } sp = skipdigits(sp); if (*sp == '.' || *sp == 'e' || *sp == 'E') *************** *** 866,871 **** --- 884,890 ---- res->v_type = VAR_SPECIAL; res->vval.v_number = VVAL_NONE; } + EMSG(_(e_invarg)); return FAIL; } *************** *** 884,893 **** --- 903,919 ---- json_skip_white(reader); ret = json_decode_item(reader, res, options); if (ret != OK) + { + if (ret == MAYBE) + EMSG(_(e_invarg)); return FAIL; + } json_skip_white(reader); if (reader->js_buf[reader->js_used] != NUL) + { + EMSG(_(e_trailing)); return FAIL; + } return OK; } *** ../vim-8.0.0165/src/channel.c 2017-01-08 20:50:47.433486722 +0100 --- src/channel.c 2017-01-10 14:51:11.216941142 +0100 *************** *** 1896,1904 **** /* When a message is incomplete we wait for a short while for more to * arrive. After the delay drop the input, otherwise a truncated string ! * or list will make us hang. */ status = json_decode(&reader, &listtv, chanpart->ch_mode == MODE_JS ? JSON_JS : 0); if (status == OK) { /* Only accept the response when it is a list with at least two --- 1896,1907 ---- /* When a message is incomplete we wait for a short while for more to * arrive. After the delay drop the input, otherwise a truncated string ! * or list will make us hang. ! * Do not generate error messages, they will be written in a channel log. */ ! ++emsg_silent; status = json_decode(&reader, &listtv, chanpart->ch_mode == MODE_JS ? JSON_JS : 0); + --emsg_silent; if (status == OK) { /* Only accept the response when it is a list with at least two *** ../vim-8.0.0165/src/testdir/test_json.vim 2016-07-21 20:10:29.000000000 +0200 --- src/testdir/test_json.vim 2017-01-10 14:26:22.407891917 +0100 *************** *** 148,155 **** call assert_fails('call json_decode("\"")', "E474:") call assert_fails('call json_decode("blah")', "E474:") ! call assert_fails('call json_decode("true blah")', "E474:") call assert_fails('call json_decode("")', "E474:") call assert_fails('call json_decode("{")', "E474:") call assert_fails('call json_decode("{foobar}")', "E474:") --- 148,156 ---- call assert_fails('call json_decode("\"")', "E474:") call assert_fails('call json_decode("blah")', "E474:") ! call assert_fails('call json_decode("true blah")', "E488:") call assert_fails('call json_decode("")', "E474:") + call assert_fails('call json_decode("{\"a\":1,\"a\":2}")', "E937:") call assert_fails('call json_decode("{")', "E474:") call assert_fails('call json_decode("{foobar}")', "E474:") *** ../vim-8.0.0165/src/version.c 2017-01-10 13:55:11.373452931 +0100 --- src/version.c 2017-01-10 15:13:45.582924948 +0100 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 166, /**/ -- Marriage isn't a word. It's a sentence. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///