Patch 7.4.1278
Problem: When jsonencode() fails it still returns something.
Solution: Return an empty string on failure.
Files: src/json.c, src/channel.c, src/testdir/test_json.vim,
src/testdir/test_channel.vim, src/testdir/test_channel.py
*** ../vim-7.4.1277/src/json.c 2016-02-06 18:42:01.647993424 +0100
--- src/json.c 2016-02-07 16:28:58.598382166 +0100
***************
*** 21,26 ****
--- 21,28 ----
/*
* Encode "val" into a JSON format string.
+ * The result is in allocated memory.
+ * The result is empty when encoding fails.
*/
char_u *
json_encode(typval_T *val)
***************
*** 29,40 ****
/* Store bytes in the growarray. */
ga_init2(&ga, 1, 4000);
! json_encode_item(&ga, val, get_copyID(), TRUE);
return ga.ga_data;
}
/*
! * Encode ["nr", "val"] into a JSON format string.
* Returns NULL when out of memory.
*/
char_u *
--- 31,46 ----
/* Store bytes in the growarray. */
ga_init2(&ga, 1, 4000);
! if (json_encode_item(&ga, val, get_copyID(), TRUE) == FAIL)
! {
! vim_free(ga.ga_data);
! return vim_strsave((char_u *)"");
! }
return ga.ga_data;
}
/*
! * Encode ["nr", "val"] into a JSON format string in allocated memory.
* Returns NULL when out of memory.
*/
char_u *
***************
*** 136,143 ****
--- 142,152 ----
case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
case VVAL_NONE: if (!allow_none)
+ {
/* TODO: better error */
EMSG(_(e_invarg));
+ return FAIL;
+ }
break;
case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
}
***************
*** 155,160 ****
--- 164,170 ----
break;
case VAR_FUNC:
+ case VAR_JOB:
/* no JSON equivalent TODO: better error */
EMSG(_(e_invarg));
return FAIL;
***************
*** 226,239 ****
}
break;
- #ifdef FEAT_FLOAT
case VAR_FLOAT:
vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
ga_concat(gap, numbuf);
break;
#endif
! default: EMSG2(_(e_intern2), "json_encode_item()"); break;
! return FAIL;
}
return OK;
}
--- 236,250 ----
}
break;
case VAR_FLOAT:
+ #ifdef FEAT_FLOAT
vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
ga_concat(gap, numbuf);
break;
#endif
! case VAR_UNKNOWN:
! EMSG2(_(e_intern2), "json_encode_item()"); break;
! return FAIL;
}
return OK;
}
*** ../vim-7.4.1277/src/channel.c 2016-02-07 15:13:56.081193256 +0100
--- src/channel.c 2016-02-07 16:47:38.494808347 +0100
***************
*** 853,876 ****
{
typval_T *tv;
typval_T err_tv;
! char_u *json;
/* Don't pollute the display with errors. */
++emsg_skip;
tv = eval_expr(arg, NULL);
- --emsg_skip;
if (is_eval)
{
! if (tv == NULL)
{
err_tv.v_type = VAR_STRING;
err_tv.vval.v_string = (char_u *)"ERROR";
tv = &err_tv;
}
- json = json_encode_nr_expr(arg3->vval.v_number, tv);
- channel_send(idx, json, "eval");
- vim_free(json);
}
if (tv != &err_tv)
free_tv(tv);
}
--- 853,883 ----
{
typval_T *tv;
typval_T err_tv;
! char_u *json = NULL;
/* Don't pollute the display with errors. */
++emsg_skip;
tv = eval_expr(arg, NULL);
if (is_eval)
{
! if (tv != NULL)
! json = json_encode_nr_expr(arg3->vval.v_number, tv);
! if (tv == NULL || (json != NULL && *json == NUL))
{
+ /* If evaluation failed or the result can't be encoded
+ * then return the string "ERROR". */
err_tv.v_type = VAR_STRING;
err_tv.vval.v_string = (char_u *)"ERROR";
tv = &err_tv;
+ json = json_encode_nr_expr(arg3->vval.v_number, tv);
+ }
+ if (json != NULL)
+ {
+ channel_send(idx, json, "eval");
+ vim_free(json);
}
}
+ --emsg_skip;
if (tv != &err_tv)
free_tv(tv);
}
*** ../vim-7.4.1277/src/testdir/test_json.vim 2016-02-06 18:42:01.647993424
+0100
--- src/testdir/test_json.vim 2016-02-07 16:40:25.747281312 +0100
***************
*** 75,80 ****
--- 75,83 ----
call assert_fails('echo jsonencode(function("tr"))', 'E474:')
call assert_fails('echo jsonencode([function("tr")])', 'E474:')
call assert_fails('echo jsonencode({"key":v:none})', 'E474:')
+
+ silent! let res = jsonencode(function("tr"))
+ call assert_equal("", res)
endfunc
func Test_decode()
*** ../vim-7.4.1277/src/testdir/test_channel.vim 2016-02-07
14:26:12.183053965 +0100
--- src/testdir/test_channel.vim 2016-02-07 16:44:54.184506982 +0100
***************
*** 118,127 ****
sleep 10m
call assert_equal([-2, 'ERROR'], ch_sendexpr(handle, 'eval-result'))
" Send a bad eval request. There will be no response.
call assert_equal('ok', ch_sendexpr(handle, 'eval-bad'))
sleep 10m
! call assert_equal([-2, 'ERROR'], ch_sendexpr(handle, 'eval-result'))
" Send an expr request
call assert_equal('ok', ch_sendexpr(handle, 'an expr'))
--- 118,132 ----
sleep 10m
call assert_equal([-2, 'ERROR'], ch_sendexpr(handle, 'eval-result'))
+ " Send an eval request that works but can't be encoded.
+ call assert_equal('ok', ch_sendexpr(handle, 'eval-error'))
+ sleep 10m
+ call assert_equal([-3, 'ERROR'], ch_sendexpr(handle, 'eval-result'))
+
" Send a bad eval request. There will be no response.
call assert_equal('ok', ch_sendexpr(handle, 'eval-bad'))
sleep 10m
! call assert_equal([-3, 'ERROR'], ch_sendexpr(handle, 'eval-result'))
" Send an expr request
call assert_equal('ok', ch_sendexpr(handle, 'an expr'))
*** ../vim-7.4.1277/src/testdir/test_channel.py 2016-02-05 23:09:07.381093948
+0100
--- src/testdir/test_channel.py 2016-02-07 16:49:06.701896324 +0100
***************
*** 93,98 ****
--- 93,105 ----
print("sending: {}".format(cmd))
self.request.sendall(cmd.encode('utf-8'))
response = "ok"
+ elif decoded[1] == 'eval-error':
+ # Send an eval request that works but the result can't
+ # be encoded.
+ cmd = '["eval","function(\\"tr\\")", -3]'
+ print("sending: {}".format(cmd))
+ self.request.sendall(cmd.encode('utf-8'))
+ response = "ok"
elif decoded[1] == 'eval-bad':
# Send an eval request missing the third argument.
cmd = '["eval","xxx"]'
*** ../vim-7.4.1277/src/version.c 2016-02-07 15:56:55.930329022 +0100
--- src/version.c 2016-02-07 16:29:37.593978740 +0100
***************
*** 749,750 ****
--- 749,752 ----
{ /* Add new patch number below this line */
+ /**/
+ 1278,
/**/
--
Apathy Error: Don't bother striking any key.
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.