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 }