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.

Raspunde prin e-mail lui