Patch 7.4.1166
Problem:    Can't encode a Funcref into JSON.  jsonencode() doesn't handle the
            same list or dict twice properly.  (Nikolay Pavlov)
Solution:   Give an error.  Reset copyID when the list or dict is finished.
Files:      src/json.c, src/proto/json.pro, src/testdir/test_json.vim


*** ../vim-7.4.1165/src/json.c  2016-01-24 15:05:27.451868346 +0100
--- src/json.c  2016-01-24 16:40:14.781218699 +0100
***************
*** 16,21 ****
--- 16,22 ----
  #include "vim.h"
  
  #if defined(FEAT_EVAL) || defined(PROTO)
+ static int json_encode_item(garray_T *gap, typval_T *val, int copyID);
  static void json_decode_item(js_read_T *reader, typval_T *res);
  
  /*
***************
*** 83,89 ****
      }
  }
  
!     void
  json_encode_item(garray_T *gap, typval_T *val, int copyID)
  {
      char_u    numbuf[NUMBUFLEN];
--- 84,94 ----
      }
  }
  
! /*
!  * Encode "val" into "gap".
!  * Return FAIL or OK.
!  */
!     static int
  json_encode_item(garray_T *gap, typval_T *val, int copyID)
  {
      char_u    numbuf[NUMBUFLEN];
***************
*** 94,100 ****
      switch (val->v_type)
      {
        case VAR_SPECIAL:
!           switch(val->vval.v_number)
            {
                case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
                case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
--- 99,105 ----
      switch (val->v_type)
      {
        case VAR_SPECIAL:
!           switch (val->vval.v_number)
            {
                case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
                case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
***************
*** 115,122 ****
            break;
  
        case VAR_FUNC:
!           /* no JSON equivalent, skip */
!           break;
  
        case VAR_LIST:
            l = val->vval.v_list;
--- 120,128 ----
            break;
  
        case VAR_FUNC:
!           /* no JSON equivalent */
!           EMSG(_(e_invarg));
!           return FAIL;
  
        case VAR_LIST:
            l = val->vval.v_list;
***************
*** 134,145 ****
                    ga_append(gap, '[');
                    for (li = l->lv_first; li != NULL && !got_int; )
                    {
!                       json_encode_item(gap, &li->li_tv, copyID);
                        li = li->li_next;
                        if (li != NULL)
                            ga_append(gap, ',');
                    }
                    ga_append(gap, ']');
                }
            }
            break;
--- 140,153 ----
                    ga_append(gap, '[');
                    for (li = l->lv_first; li != NULL && !got_int; )
                    {
!                       if (json_encode_item(gap, &li->li_tv, copyID) == FAIL)
!                           return FAIL;
                        li = li->li_next;
                        if (li != NULL)
                            ga_append(gap, ',');
                    }
                    ga_append(gap, ']');
+                   l->lv_copyID = 0;
                }
            }
            break;
***************
*** 172,181 ****
                                ga_append(gap, ',');
                            write_string(gap, hi->hi_key);
                            ga_append(gap, ':');
!                           json_encode_item(gap, &dict_lookup(hi)->di_tv,
!                                                                     copyID);
                        }
                    ga_append(gap, '}');
                }
            }
            break;
--- 180,191 ----
                                ga_append(gap, ',');
                            write_string(gap, hi->hi_key);
                            ga_append(gap, ':');
!                           if (json_encode_item(gap, &dict_lookup(hi)->di_tv,
!                                                             copyID) == FAIL)
!                               return FAIL;
                        }
                    ga_append(gap, '}');
+                   d->dv_copyID = 0;
                }
            }
            break;
***************
*** 187,193 ****
--- 197,205 ----
            break;
  #endif
        default: EMSG2(_(e_intern2), "json_encode_item()"); break;
+                return FAIL;
      }
+     return OK;
  }
  
  /*
*** ../vim-7.4.1165/src/proto/json.pro  2016-01-23 19:45:48.626931291 +0100
--- src/proto/json.pro  2016-01-24 16:19:52.205896695 +0100
***************
*** 1,5 ****
  /* json.c */
  char_u *json_encode(typval_T *val);
- void json_encode_item(garray_T *gap, typval_T *val, int copyID);
  void json_decode(js_read_T *reader, typval_T *res);
  /* vim: set ft=c : */
--- 1,4 ----
*** ../vim-7.4.1165/src/testdir/test_json.vim   2016-01-24 15:05:27.455868305 
+0100
--- src/testdir/test_json.vim   2016-01-24 16:39:44.389533642 +0100
***************
*** 27,32 ****
--- 27,35 ----
  let l2 = ['a', s:varl2, 'c']
  let s:varl2[1] = l2
  let s:varl2x = [1, ["a", [], "c"], 3]
+ let s:jsonl3 = '[[1,2],[1,2]]'
+ let l3 = [1, 2]
+ let s:varl3 = [l3, l3]
  
  let s:jsond1 = '{"a":1,"b":"bee","c":[1,2]}'
  let s:vard1 = {"a": 1, "b": "bee","c": [1,2]}
***************
*** 36,41 ****
--- 39,47 ----
  let d2 = {"a": "aa", "b": s:vard2, "c": "cc"}
  let s:vard2["2"] = d2
  let s:vard2x = {"1": 1, "2": {"a": "aa", "b": {}, "c": "cc"}, "3": 3}
+ let d3 = {"a": 1, "b": 2}
+ let s:vard3 = {"x": d3, "y": d3}
+ let s:jsond3 = '{"x":{"a":1,"b":2},"y":{"a":1,"b":2}}'
  
  let s:jsonvals = '[true,false,,null]'
  let s:varvals = [v:true, v:false, v:none, v:null]
***************
*** 58,68 ****
--- 64,79 ----
  
    call assert_equal(s:jsonl1, jsonencode(s:varl1))
    call assert_equal(s:jsonl2, jsonencode(s:varl2))
+   call assert_equal(s:jsonl3, jsonencode(s:varl3))
  
    call assert_equal(s:jsond1, jsonencode(s:vard1))
    call assert_equal(s:jsond2, jsonencode(s:vard2))
+   call assert_equal(s:jsond3, jsonencode(s:vard3))
  
    call assert_equal(s:jsonvals, jsonencode(s:varvals))
+ 
+   call assert_fails('echo jsonencode(function("tr"))', 'E474:')
+   call assert_fails('echo jsonencode([function("tr")])', 'E474:')
  endfunc
  
  func Test_decode()
***************
*** 84,92 ****
--- 95,105 ----
    call assert_equal(s:varl1, jsondecode(s:jsonl1))
    call assert_equal(s:varl2x, jsondecode(s:jsonl2))
    call assert_equal(s:varl2x, jsondecode(s:jsonl2s))
+   call assert_equal(s:varl3, jsondecode(s:jsonl3))
  
    call assert_equal(s:vard1, jsondecode(s:jsond1))
    call assert_equal(s:vard2x, jsondecode(s:jsond2))
+   call assert_equal(s:vard3, jsondecode(s:jsond3))
  
    call assert_equal(s:varvals, jsondecode(s:jsonvals))
  
*** ../vim-7.4.1165/src/version.c       2016-01-24 15:35:55.529110654 +0100
--- src/version.c       2016-01-24 16:47:36.668640618 +0100
***************
*** 743,744 ****
--- 743,746 ----
  {   /* Add new patch number below this line */
+ /**/
+     1166,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
32. You don't know what sex three of your closest friends are, because they
    have neutral nicknames and you never bothered to ask.
  normal GA<CR><Esc>

 /// Bram Moolenaar -- b...@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    ///

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui