From 5f6b379ff3e34297d171635933f907ec80ed4f05 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 12 Jan 2019 14:24:27 +0100 Subject: [PATCH] patch 8.1.0731: JS encoding does not handle negative infinity Problem: JS encoding does not handle negative infinity. Solution: Add support for negative infinity for JS encoding. (Dominique Pelle, closes #3792) --- runtime/doc/eval.txt | 4 +++- src/json.c | 23 ++++++++++++++++++++--- src/testdir/test_json.vim | 15 ++++++++++----- src/version.c | 2 ++ 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 14d6bb4db..86026239a 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -5726,7 +5726,8 @@ json_decode({string}) *json_decode()* "[1, 2, ]" is the same as "[1, 2]". - More floating point numbers are recognized, e.g. "1." for "1.0", or "001.2" for "1.2". Special floating point values - "Infinity" and "NaN" (capitalization ignored) are accepted. + "Infinity", "-Infinity" and "NaN" (capitalization ignored) + are accepted. - Leading zeroes in integer numbers are ignored, e.g. "012" for "12" or "-012" for "-12". - Capitalization is ignored in literal names null, true or @@ -5755,6 +5756,7 @@ json_encode({expr}) *json_encode()* Float floating point number Float nan "NaN" Float inf "Infinity" + Float -inf "-Infinity" String in double quotes (possibly null) Funcref not possible, error List as an array (possibly null); when diff --git a/src/json.c b/src/json.c index 60637714a..d9da10d35 100644 --- a/src/json.c +++ b/src/json.c @@ -316,7 +316,12 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options) if (isnan(val->vval.v_float)) ga_concat(gap, (char_u *)"NaN"); else if (isinf(val->vval.v_float)) - ga_concat(gap, (char_u *)"Infinity"); + { + if (val->vval.v_float < 0.0) + ga_concat(gap, (char_u *)"-Infinity"); + else + ga_concat(gap, (char_u *)"Infinity"); + } else # endif { @@ -736,7 +741,7 @@ json_decode_item(js_read_T *reader, typval_T *res, int options) break; default: - if (VIM_ISDIGIT(*p) || *p == '-') + if (VIM_ISDIGIT(*p) || (*p == '-' && VIM_ISDIGIT(p[1]))) { #ifdef FEAT_FLOAT char_u *sp = p; @@ -834,6 +839,17 @@ json_decode_item(js_read_T *reader, typval_T *res, int options) retval = OK; break; } + if (STRNICMP((char *)p, "-Infinity", 9) == 0) + { + reader->js_used += 9; + if (cur_item != NULL) + { + cur_item->v_type = VAR_FLOAT; + cur_item->vval.v_float = -INFINITY; + } + retval = OK; + break; + } if (STRNICMP((char *)p, "Infinity", 8) == 0) { reader->js_used += 8; @@ -851,6 +867,7 @@ json_decode_item(js_read_T *reader, typval_T *res, int options) if ( (len < 5 && STRNICMP((char *)p, "false", len) == 0) #ifdef FEAT_FLOAT + || (len < 9 && STRNICMP((char *)p, "-Infinity", len) == 0) || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0) || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0) #endif @@ -1072,7 +1089,7 @@ json_decode(js_read_T *reader, typval_T *res, int options) * Return FAIL if the message has a decoding error. * Return MAYBE if the message is truncated, need to read more. * This only works reliable if the message contains an object, array or - * string. A number might be trucated without knowing. + * string. A number might be truncated without knowing. * Does not advance the reader. */ int diff --git a/src/testdir/test_json.vim b/src/testdir/test_json.vim index 396651e6b..e0a550c84 100644 --- a/src/testdir/test_json.vim +++ b/src/testdir/test_json.vim @@ -29,8 +29,10 @@ let s:varnr = 1234 if has('float') let s:jsonfl = '12.34' let s:varfl = 12.34 - let s:jsoninf = 'Infinity' - let s:varinf = 1.0 / 0.0 + let s:jsonneginf = '-Infinity' + let s:jsonposinf = 'Infinity' + let s:varneginf = -1.0 / 0.0 + let s:varposinf = 1.0 / 0.0 let s:jsonnan = 'NaN' let s:varnan = 0.0 / 0.0 endif @@ -85,7 +87,8 @@ func Test_json_encode() 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:jsonneginf, json_encode(s:varneginf)) + call assert_equal(s:jsonposinf, json_encode(s:varposinf)) call assert_equal(s:jsonnan, json_encode(s:varnan)) endif @@ -202,7 +205,8 @@ func Test_js_encode() 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:jsoninf, js_encode(s:varinf)) + call assert_equal(s:jsonneginf, js_encode(s:varneginf)) + call assert_equal(s:jsonposinf, js_encode(s:varposinf)) call assert_equal(s:jsonnan, js_encode(s:varnan)) endif @@ -242,7 +246,8 @@ func Test_js_decode() 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:jsoninf)) + call assert_equal(s:varneginf, js_decode(s:jsonneginf)) + call assert_equal(s:varposinf, js_decode(s:jsonposinf)) call assert_true(isnan(js_decode(s:jsonnan))) endif diff --git a/src/version.c b/src/version.c index 7aeaa4869..d7c610bc9 100644 --- a/src/version.c +++ b/src/version.c @@ -795,6 +795,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 731, /**/ 730, /**/ -- 2.40.0