Mercurial > vim
comparison src/json.c @ 8228:a0e552c51c34 v7.4.1407
commit https://github.com/vim/vim/commit/f1b6ac72293e658bb6e68c5cfd926c405b1b6f34
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Feb 23 21:26:43 2016 +0100
patch 7.4.1407
Problem: json_encode() does not handle NaN and inf properly. (David
Barnett)
Solution: For JSON turn them into "null". For JS use "NaN" and "Infinity".
Add isnan().
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 23 Feb 2016 21:30:08 +0100 |
parents | 5dacbd22fefd |
children | 51ca0cee512e |
comparison
equal
deleted
inserted
replaced
8227:f26bb0f9a8b9 | 8228:a0e552c51c34 |
---|---|
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 | |
20 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) | |
21 /* for isnan() and isinf() */ | |
22 # include <math.h> | |
23 #endif | |
24 | |
19 static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int options); | 25 static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int options); |
20 static int json_decode_item(js_read_T *reader, typval_T *res, int options); | 26 static int json_decode_item(js_read_T *reader, typval_T *res, int options); |
21 | 27 |
22 /* | 28 /* |
23 * Encode "val" into a JSON format string. | 29 * Encode "val" into a JSON format string. |
265 } | 271 } |
266 break; | 272 break; |
267 | 273 |
268 case VAR_FLOAT: | 274 case VAR_FLOAT: |
269 #ifdef FEAT_FLOAT | 275 #ifdef FEAT_FLOAT |
270 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float); | 276 # if defined(HAVE_MATH_H) |
271 ga_concat(gap, numbuf); | 277 if ((options & JSON_JS) && isnan(val->vval.v_float)) |
278 ga_concat(gap, (char_u *)"NaN"); | |
279 else if ((options & JSON_JS) && isinf(val->vval.v_float)) | |
280 ga_concat(gap, (char_u *)"Infinity"); | |
281 else if (isnan(val->vval.v_float) || isinf(val->vval.v_float)) | |
282 ga_concat(gap, (char_u *)"null"); | |
283 else | |
284 # endif | |
285 { | |
286 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", | |
287 val->vval.v_float); | |
288 ga_concat(gap, numbuf); | |
289 } | |
272 break; | 290 break; |
273 #endif | 291 #endif |
274 case VAR_UNKNOWN: | 292 case VAR_UNKNOWN: |
275 EMSG2(_(e_intern2), "json_encode_item()"); | 293 EMSG2(_(e_intern2), "json_encode_item()"); |
276 return FAIL; | 294 return FAIL; |
718 res->v_type = VAR_SPECIAL; | 736 res->v_type = VAR_SPECIAL; |
719 res->vval.v_number = VVAL_NULL; | 737 res->vval.v_number = VVAL_NULL; |
720 } | 738 } |
721 return OK; | 739 return OK; |
722 } | 740 } |
741 #ifdef FEAT_FLOAT | |
742 if (STRNICMP((char *)p, "NaN", 3) == 0) | |
743 { | |
744 reader->js_used += 3; | |
745 if (res != NULL) | |
746 { | |
747 res->v_type = VAR_FLOAT; | |
748 res->vval.v_float = 0.0 / 0.0; | |
749 } | |
750 return OK; | |
751 } | |
752 if (STRNICMP((char *)p, "Infinity", 8) == 0) | |
753 { | |
754 reader->js_used += 8; | |
755 if (res != NULL) | |
756 { | |
757 res->v_type = VAR_FLOAT; | |
758 res->vval.v_float = 1.0 / 0.0; | |
759 } | |
760 return OK; | |
761 } | |
762 #endif | |
723 /* check for truncated name */ | 763 /* check for truncated name */ |
724 len = (int)(reader->js_end - (reader->js_buf + reader->js_used)); | 764 len = (int)(reader->js_end - (reader->js_buf + reader->js_used)); |
725 if ((len < 5 && STRNICMP((char *)p, "false", len) == 0) | 765 if ( |
766 (len < 5 && STRNICMP((char *)p, "false", len) == 0) | |
767 #ifdef FEAT_FLOAT | |
768 || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0) | |
769 || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0) | |
770 #endif | |
726 || (len < 4 && (STRNICMP((char *)p, "true", len) == 0 | 771 || (len < 4 && (STRNICMP((char *)p, "true", len) == 0 |
727 || STRNICMP((char *)p, "null", len) == 0))) | 772 || STRNICMP((char *)p, "null", len) == 0))) |
728 return MAYBE; | 773 return MAYBE; |
729 break; | 774 break; |
730 } | 775 } |