comparison src/json.c @ 7736:f2ddad8cbce7 v7.4.1166

commit https://github.com/vim/vim/commit/fcaaae6b3fdbf3421a1ff95a25ae16d82381c39a Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 24 16:49:11 2016 +0100 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.
author Christian Brabandt <cb@256bit.org>
date Sun, 24 Jan 2016 17:00:04 +0100
parents 4a4f1dd1abe8
children 3a99194bd187
comparison
equal deleted inserted replaced
7735:b0fb25b27d3f 7736:f2ddad8cbce7
14 */ 14 */
15 15
16 #include "vim.h" 16 #include "vim.h"
17 17
18 #if defined(FEAT_EVAL) || defined(PROTO) 18 #if defined(FEAT_EVAL) || defined(PROTO)
19 static int json_encode_item(garray_T *gap, typval_T *val, int copyID);
19 static void json_decode_item(js_read_T *reader, typval_T *res); 20 static void json_decode_item(js_read_T *reader, typval_T *res);
20 21
21 /* 22 /*
22 * Encode "val" into a JSON format string. 23 * Encode "val" into a JSON format string.
23 */ 24 */
81 } 82 }
82 ga_append(gap, '"'); 83 ga_append(gap, '"');
83 } 84 }
84 } 85 }
85 86
86 void 87 /*
88 * Encode "val" into "gap".
89 * Return FAIL or OK.
90 */
91 static int
87 json_encode_item(garray_T *gap, typval_T *val, int copyID) 92 json_encode_item(garray_T *gap, typval_T *val, int copyID)
88 { 93 {
89 char_u numbuf[NUMBUFLEN]; 94 char_u numbuf[NUMBUFLEN];
90 char_u *res; 95 char_u *res;
91 list_T *l; 96 list_T *l;
92 dict_T *d; 97 dict_T *d;
93 98
94 switch (val->v_type) 99 switch (val->v_type)
95 { 100 {
96 case VAR_SPECIAL: 101 case VAR_SPECIAL:
97 switch(val->vval.v_number) 102 switch (val->vval.v_number)
98 { 103 {
99 case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break; 104 case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
100 case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break; 105 case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
101 case VVAL_NONE: break; 106 case VVAL_NONE: break;
102 case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break; 107 case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
113 res = val->vval.v_string; 118 res = val->vval.v_string;
114 write_string(gap, res); 119 write_string(gap, res);
115 break; 120 break;
116 121
117 case VAR_FUNC: 122 case VAR_FUNC:
118 /* no JSON equivalent, skip */ 123 /* no JSON equivalent */
119 break; 124 EMSG(_(e_invarg));
125 return FAIL;
120 126
121 case VAR_LIST: 127 case VAR_LIST:
122 l = val->vval.v_list; 128 l = val->vval.v_list;
123 if (l == NULL) 129 if (l == NULL)
124 ga_concat(gap, (char_u *)"null"); 130 ga_concat(gap, (char_u *)"null");
132 138
133 l->lv_copyID = copyID; 139 l->lv_copyID = copyID;
134 ga_append(gap, '['); 140 ga_append(gap, '[');
135 for (li = l->lv_first; li != NULL && !got_int; ) 141 for (li = l->lv_first; li != NULL && !got_int; )
136 { 142 {
137 json_encode_item(gap, &li->li_tv, copyID); 143 if (json_encode_item(gap, &li->li_tv, copyID) == FAIL)
144 return FAIL;
138 li = li->li_next; 145 li = li->li_next;
139 if (li != NULL) 146 if (li != NULL)
140 ga_append(gap, ','); 147 ga_append(gap, ',');
141 } 148 }
142 ga_append(gap, ']'); 149 ga_append(gap, ']');
150 l->lv_copyID = 0;
143 } 151 }
144 } 152 }
145 break; 153 break;
146 154
147 case VAR_DICT: 155 case VAR_DICT:
170 first = FALSE; 178 first = FALSE;
171 else 179 else
172 ga_append(gap, ','); 180 ga_append(gap, ',');
173 write_string(gap, hi->hi_key); 181 write_string(gap, hi->hi_key);
174 ga_append(gap, ':'); 182 ga_append(gap, ':');
175 json_encode_item(gap, &dict_lookup(hi)->di_tv, 183 if (json_encode_item(gap, &dict_lookup(hi)->di_tv,
176 copyID); 184 copyID) == FAIL)
185 return FAIL;
177 } 186 }
178 ga_append(gap, '}'); 187 ga_append(gap, '}');
188 d->dv_copyID = 0;
179 } 189 }
180 } 190 }
181 break; 191 break;
182 192
183 #ifdef FEAT_FLOAT 193 #ifdef FEAT_FLOAT
185 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float); 195 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
186 ga_concat(gap, numbuf); 196 ga_concat(gap, numbuf);
187 break; 197 break;
188 #endif 198 #endif
189 default: EMSG2(_(e_intern2), "json_encode_item()"); break; 199 default: EMSG2(_(e_intern2), "json_encode_item()"); break;
190 } 200 return FAIL;
201 }
202 return OK;
191 } 203 }
192 204
193 /* 205 /*
194 * Skip white space in "reader". 206 * Skip white space in "reader".
195 */ 207 */