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().
Files: src/eval.c, src/json.c, src/testdir/test_json.vim
*** ../vim-7.4.1406/src/eval.c 2016-02-23 17:13:56.877032330 +0100
--- src/eval.c 2016-02-23 21:19:22.203128950 +0100
***************
*** 628,633 ****
--- 628,636 ----
static void f_invert(typval_T *argvars, typval_T *rettv);
static void f_isdirectory(typval_T *argvars, typval_T *rettv);
static void f_islocked(typval_T *argvars, typval_T *rettv);
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+ static void f_isnan(typval_T *argvars, typval_T *rettv);
+ #endif
static void f_items(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_JOB
# ifdef FEAT_CHANNEL
***************
*** 8320,8325 ****
--- 8323,8331 ----
{"invert", 1, 1, f_invert},
{"isdirectory", 1, 1, f_isdirectory},
{"islocked", 1, 1, f_islocked},
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+ {"isnan", 1, 1, f_isnan},
+ #endif
{"items", 1, 1, f_items},
#ifdef FEAT_JOB
# ifdef FEAT_CHANNEL
***************
*** 14740,14745 ****
--- 14746,14763 ----
clear_lval(&lv);
}
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+ /*
+ * "isnan()" function
+ */
+ static void
+ f_isnan(typval_T *argvars, typval_T *rettv)
+ {
+ rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
+ && isnan(argvars[0].vval.v_float);
+ }
+ #endif
+
static void dict_list(typval_T *argvars, typval_T *rettv, int what);
/*
*** ../vim-7.4.1406/src/json.c 2016-02-20 15:26:38.299827771 +0100
--- src/json.c 2016-02-23 21:11:39.991974796 +0100
***************
*** 16,21 ****
--- 16,27 ----
#include "vim.h"
#if defined(FEAT_EVAL) || defined(PROTO)
+
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+ /* for isnan() and isinf() */
+ # include <math.h>
+ #endif
+
static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int
options);
static int json_decode_item(js_read_T *reader, typval_T *res, int options);
***************
*** 267,274 ****
case VAR_FLOAT:
#ifdef FEAT_FLOAT
! vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
! ga_concat(gap, numbuf);
break;
#endif
case VAR_UNKNOWN:
--- 273,292 ----
case VAR_FLOAT:
#ifdef FEAT_FLOAT
! # if defined(HAVE_MATH_H)
! if ((options & JSON_JS) && isnan(val->vval.v_float))
! ga_concat(gap, (char_u *)"NaN");
! else if ((options & JSON_JS) && isinf(val->vval.v_float))
! ga_concat(gap, (char_u *)"Infinity");
! else if (isnan(val->vval.v_float) || isinf(val->vval.v_float))
! ga_concat(gap, (char_u *)"null");
! else
! # endif
! {
! vim_snprintf((char *)numbuf, NUMBUFLEN, "%g",
! val->vval.v_float);
! ga_concat(gap, numbuf);
! }
break;
#endif
case VAR_UNKNOWN:
***************
*** 720,728 ****
}
return OK;
}
/* check for truncated name */
len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
! if ((len < 5 && STRNICMP((char *)p, "false", len) == 0)
|| (len < 4 && (STRNICMP((char *)p, "true", len) == 0
|| STRNICMP((char *)p, "null", len) == 0)))
return MAYBE;
--- 738,773 ----
}
return OK;
}
+ #ifdef FEAT_FLOAT
+ if (STRNICMP((char *)p, "NaN", 3) == 0)
+ {
+ reader->js_used += 3;
+ if (res != NULL)
+ {
+ res->v_type = VAR_FLOAT;
+ res->vval.v_float = 0.0 / 0.0;
+ }
+ return OK;
+ }
+ if (STRNICMP((char *)p, "Infinity", 8) == 0)
+ {
+ reader->js_used += 8;
+ if (res != NULL)
+ {
+ res->v_type = VAR_FLOAT;
+ res->vval.v_float = 1.0 / 0.0;
+ }
+ return OK;
+ }
+ #endif
/* check for truncated name */
len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
! if (
! (len < 5 && STRNICMP((char *)p, "false", len) == 0)
! #ifdef FEAT_FLOAT
! || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
! || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
! #endif
|| (len < 4 && (STRNICMP((char *)p, "true", len) == 0
|| STRNICMP((char *)p, "null", len) == 0)))
return MAYBE;
*** ../vim-7.4.1406/src/testdir/test_json.vim 2016-02-11 21:08:27.544531244
+0100
--- src/testdir/test_json.vim 2016-02-23 21:25:52.651035682 +0100
***************
*** 16,23 ****
let s:varmb = "s¢cĴgё"
let s:jsonnr = '1234'
let s:varnr = 1234
! let s:jsonfl = '12.34'
! let s:varfl = 12.34
let s:jsonl1 = '[1,"a",3]'
let s:varl1 = [1, "a", 3]
--- 16,31 ----
let s:varmb = "s¢cĴgё"
let s:jsonnr = '1234'
let s:varnr = 1234
! if has('float')
! let s:jsonfl = '12.34'
! let s:varfl = 12.34
! let s:jsoninf = 'null'
! let s:jsinf = 'Infinity'
! let s:varinf = 1.0 / 0.0
! let s:jsonnan = 'null'
! let s:jsnan = 'NaN'
! let s:varnan = 0.0 / 0.0
! endif
let s:jsonl1 = '[1,"a",3]'
let s:varl1 = [1, "a", 3]
***************
*** 68,73 ****
--- 76,83 ----
call assert_equal(s:jsonnr, json_encode(s:varnr))
if has('float')
call assert_equal(s:jsonfl, json_encode(s:varfl))
+ call assert_equal(s:jsoninf, json_encode(s:varinf))
+ call assert_equal(s:jsonnan, json_encode(s:varnan))
endif
call assert_equal(s:jsonl1, json_encode(s:varl1))
***************
*** 165,170 ****
--- 175,182 ----
call assert_equal(s:jsonnr, js_encode(s:varnr))
if has('float')
call assert_equal(s:jsonfl, js_encode(s:varfl))
+ call assert_equal(s:jsinf, js_encode(s:varinf))
+ call assert_equal(s:jsnan, js_encode(s:varnan))
endif
call assert_equal(s:jsonl1, js_encode(s:varl1))
***************
*** 201,206 ****
--- 213,220 ----
call assert_equal(s:varnr, js_decode(s:jsonnr))
if has('float')
call assert_equal(s:varfl, js_decode(s:jsonfl))
+ call assert_equal(s:varinf, js_decode(s:jsinf))
+ call assert_true(isnan(js_decode(s:jsnan)))
endif
call assert_equal(s:varl1, js_decode(s:jsonl1))
*** ../vim-7.4.1406/src/version.c 2016-02-23 20:43:58.725419739 +0100
--- src/version.c 2016-02-23 21:24:12.216088576 +0100
***************
*** 750,751 ****
--- 750,753 ----
{ /* Add new patch number below this line */
+ /**/
+ 1407,
/**/
--
Two cows are standing together in a field. One asks the other:
"So what do you think about this Mad Cow Disease?"
The other replies: "That doesn't concern me. I'm a helicopter."
/// Bram Moolenaar -- [email protected] -- 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 [email protected].
For more options, visit https://groups.google.com/d/optout.