0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 7.4.1278

Problem:    When jsonencode() fails it still returns something.
Solution:   Return an empty string on failure.
This commit is contained in:
Bram Moolenaar 2016-02-07 16:53:13 +01:00
parent a6f72ba7c6
commit 55fab439a6
6 changed files with 47 additions and 12 deletions

View File

@ -853,24 +853,31 @@ channel_exe_cmd(int idx, char_u *cmd, typval_T *arg2, typval_T *arg3)
{ {
typval_T *tv; typval_T *tv;
typval_T err_tv; typval_T err_tv;
char_u *json; char_u *json = NULL;
/* Don't pollute the display with errors. */ /* Don't pollute the display with errors. */
++emsg_skip; ++emsg_skip;
tv = eval_expr(arg, NULL); tv = eval_expr(arg, NULL);
--emsg_skip;
if (is_eval) if (is_eval)
{ {
if (tv == NULL) 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.v_type = VAR_STRING;
err_tv.vval.v_string = (char_u *)"ERROR"; err_tv.vval.v_string = (char_u *)"ERROR";
tv = &err_tv; tv = &err_tv;
json = json_encode_nr_expr(arg3->vval.v_number, tv);
}
if (json != NULL)
{
channel_send(idx, json, "eval");
vim_free(json);
} }
json = json_encode_nr_expr(arg3->vval.v_number, tv);
channel_send(idx, json, "eval");
vim_free(json);
} }
--emsg_skip;
if (tv != &err_tv) if (tv != &err_tv)
free_tv(tv); free_tv(tv);
} }

View File

@ -21,6 +21,8 @@ static int json_decode_item(js_read_T *reader, typval_T *res);
/* /*
* Encode "val" into a JSON format string. * Encode "val" into a JSON format string.
* The result is in allocated memory.
* The result is empty when encoding fails.
*/ */
char_u * char_u *
json_encode(typval_T *val) json_encode(typval_T *val)
@ -29,12 +31,16 @@ json_encode(typval_T *val)
/* Store bytes in the growarray. */ /* Store bytes in the growarray. */
ga_init2(&ga, 1, 4000); ga_init2(&ga, 1, 4000);
json_encode_item(&ga, val, get_copyID(), TRUE); if (json_encode_item(&ga, val, get_copyID(), TRUE) == FAIL)
{
vim_free(ga.ga_data);
return vim_strsave((char_u *)"");
}
return ga.ga_data; return ga.ga_data;
} }
/* /*
* Encode ["nr", "val"] into a JSON format string. * Encode ["nr", "val"] into a JSON format string in allocated memory.
* Returns NULL when out of memory. * Returns NULL when out of memory.
*/ */
char_u * char_u *
@ -136,8 +142,11 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int allow_none)
case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break; case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break; case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
case VVAL_NONE: if (!allow_none) case VVAL_NONE: if (!allow_none)
{
/* TODO: better error */ /* TODO: better error */
EMSG(_(e_invarg)); EMSG(_(e_invarg));
return FAIL;
}
break; break;
case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break; case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
} }
@ -155,6 +164,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int allow_none)
break; break;
case VAR_FUNC: case VAR_FUNC:
case VAR_JOB:
/* no JSON equivalent TODO: better error */ /* no JSON equivalent TODO: better error */
EMSG(_(e_invarg)); EMSG(_(e_invarg));
return FAIL; return FAIL;
@ -226,14 +236,15 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int allow_none)
} }
break; break;
#ifdef FEAT_FLOAT
case VAR_FLOAT: case VAR_FLOAT:
#ifdef FEAT_FLOAT
vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float); vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
ga_concat(gap, numbuf); ga_concat(gap, numbuf);
break; break;
#endif #endif
default: EMSG2(_(e_intern2), "json_encode_item()"); break; case VAR_UNKNOWN:
return FAIL; EMSG2(_(e_intern2), "json_encode_item()"); break;
return FAIL;
} }
return OK; return OK;
} }

View File

@ -93,6 +93,13 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
print("sending: {}".format(cmd)) print("sending: {}".format(cmd))
self.request.sendall(cmd.encode('utf-8')) self.request.sendall(cmd.encode('utf-8'))
response = "ok" 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': elif decoded[1] == 'eval-bad':
# Send an eval request missing the third argument. # Send an eval request missing the third argument.
cmd = '["eval","xxx"]' cmd = '["eval","xxx"]'

View File

@ -118,10 +118,15 @@ func Test_communicate()
sleep 10m sleep 10m
call assert_equal([-2, 'ERROR'], ch_sendexpr(handle, 'eval-result')) 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. " Send a bad eval request. There will be no response.
call assert_equal('ok', ch_sendexpr(handle, 'eval-bad')) call assert_equal('ok', ch_sendexpr(handle, 'eval-bad'))
sleep 10m sleep 10m
call assert_equal([-2, 'ERROR'], ch_sendexpr(handle, 'eval-result')) call assert_equal([-3, 'ERROR'], ch_sendexpr(handle, 'eval-result'))
" Send an expr request " Send an expr request
call assert_equal('ok', ch_sendexpr(handle, 'an expr')) call assert_equal('ok', ch_sendexpr(handle, 'an expr'))

View File

@ -75,6 +75,9 @@ func Test_encode()
call assert_fails('echo jsonencode(function("tr"))', 'E474:') call assert_fails('echo jsonencode(function("tr"))', 'E474:')
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:') call assert_fails('echo jsonencode({"key":v:none})', 'E474:')
silent! let res = jsonencode(function("tr"))
call assert_equal("", res)
endfunc endfunc
func Test_decode() func Test_decode()

View File

@ -747,6 +747,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1278,
/**/ /**/
1277, 1277,
/**/ /**/