Mercurial > vim
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 */ |