diff options
author | Mark Spruiell <mes@zeroc.com> | 2015-12-02 11:28:31 -0800 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2015-12-02 11:28:31 -0800 |
commit | 7ea494f049785c1adf0ec7693cae7744276e42d2 (patch) | |
tree | 889a2cdbf371c155a26b6225e2b0c03d58b840ab | |
parent | Fix for ICE-6896 - sporadic binding test failure with the Python language map... (diff) | |
download | ice-7ea494f049785c1adf0ec7693cae7744276e42d2.tar.bz2 ice-7ea494f049785c1adf0ec7693cae7744276e42d2.tar.xz ice-7ea494f049785c1adf0ec7693cae7744276e42d2.zip |
Fixes for ICE-6905 - support NaN/Infinity in scripting languages
-rw-r--r-- | CHANGELOG-3.6.md | 3 | ||||
-rw-r--r-- | js/src/Ice/BasicStream.js | 10 | ||||
-rw-r--r-- | js/test/Ice/operations/Twoways.js | 23 | ||||
-rw-r--r-- | php/src/IcePHP/Types.cpp | 2 | ||||
-rw-r--r-- | php/test/Ice/operations/Client.php | 11 | ||||
-rw-r--r-- | python/modules/IcePy/Types.cpp | 2 | ||||
-rw-r--r-- | python/test/Ice/operations/Twoways.py | 7 | ||||
-rw-r--r-- | ruby/src/IceRuby/Types.cpp | 2 | ||||
-rw-r--r-- | ruby/test/Ice/operations/Twoways.rb | 9 |
9 files changed, 54 insertions, 15 deletions
diff --git a/CHANGELOG-3.6.md b/CHANGELOG-3.6.md index 9040538c75a..ed6df276f5e 100644 --- a/CHANGELOG-3.6.md +++ b/CHANGELOG-3.6.md @@ -41,6 +41,9 @@ These are the changes since Ice 3.6.1. issue was true for exceptions with class data members deriving from exceptions with class data members. +- Fixed a bug that prevented scripting languages (Python, Ruby, Javascript and PHP) + from marshaling NaN or Infinity as a floating point value. + ## C++ Changes - Fixed El Capitan build issues caused by a new security feature that no longer diff --git a/js/src/Ice/BasicStream.js b/js/src/Ice/BasicStream.js index 97e803c3ab3..548956fc158 100644 --- a/js/src/Ice/BasicStream.js +++ b/js/src/Ice/BasicStream.js @@ -2943,9 +2943,19 @@ Ice.IntHelper = defineBuiltinHelper(stream.writeInt, stream.readInt, 4, Ice.Opti Ice.FloatHelper = defineBuiltinHelper(stream.writeFloat, stream.readFloat, 4, Ice.OptionalFormat.F4, MIN_FLOAT32_VALUE, MAX_FLOAT32_VALUE); +Ice.FloatHelper.validate = function(v) +{ + return Number.isNaN(v) || v == Number.POSITIVE_INFINITY || v == Number.NEGATIVE_INFINITY || + (v >= MIN_FLOAT32_VALUE && v <= MAX_FLOAT32_VALUE); +}; Ice.DoubleHelper = defineBuiltinHelper(stream.writeDouble, stream.readDouble, 8, Ice.OptionalFormat.F8, -Number.MAX_VALUE, Number.MAX_VALUE); +Ice.DoubleHelper.validate = function(v) +{ + return Number.isNaN(v) || v == Number.POSITIVE_INFINITY || v == Number.NEGATIVE_INFINITY || + (v >= -Number.MAX_VALUE && v <= Number.MAX_VALUE); +}; Ice.BoolHelper = defineBuiltinHelper(stream.writeBool, stream.readBool, 1, Ice.OptionalFormat.F1); Ice.LongHelper = defineBuiltinHelper(stream.writeLong, stream.readLong, 8, Ice.OptionalFormat.F8); diff --git a/js/test/Ice/operations/Twoways.js b/js/test/Ice/operations/Twoways.js index a5c78738fe9..e7bbd6bedc0 100644 --- a/js/test/Ice/operations/Twoways.js +++ b/js/test/Ice/operations/Twoways.js @@ -180,27 +180,26 @@ function(ex) { test(ex instanceof Ice.MarshalException); - return prx.opFloatDouble(0, Number.MAX_VALUE * 2); + return prx.opFloatDouble(Number.NaN, Number.NaN); } ).then( - failCB, - function(ex) + function(retval, f, d) { - test(ex instanceof Ice.MarshalException); - return prx.opFloatDouble(0, -Number.MAX_VALUE * 2); + return prx.opFloatDouble(-Number.NaN, -Number.NaN); } ).then( - failCB, - function(ex) + function(retval, f, d) { - test(ex instanceof Ice.MarshalException); - return prx.opFloatDouble(0, Number.NaN); + return prx.opFloatDouble(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); } ).then( - failCB, - function(ex) + function(retval, f, d) + { + return prx.opFloatDouble(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY); + } + ).then( + function(retval, f, d) { - test(ex instanceof Ice.MarshalException); return prx.opString("hello", "world"); } ).then( diff --git a/php/src/IcePHP/Types.cpp b/php/src/IcePHP/Types.cpp index 438541a8d5e..a3cd3fd6b58 100644 --- a/php/src/IcePHP/Types.cpp +++ b/php/src/IcePHP/Types.cpp @@ -759,7 +759,7 @@ IcePHP::PrimitiveInfo::validate(zval* zv TSRMLS_DC) if(Z_TYPE_P(zv) == IS_DOUBLE) { double val = Z_DVAL_P(zv); - return val <= numeric_limits<float>::max() && val >= -numeric_limits<float>::max(); + return (val <= numeric_limits<float>::max() && val >= -numeric_limits<float>::max()) || !isfinite(val); } break; } diff --git a/php/test/Ice/operations/Client.php b/php/test/Ice/operations/Client.php index e775a01e7ab..d653a0b194b 100644 --- a/php/test/Ice/operations/Client.php +++ b/php/test/Ice/operations/Client.php @@ -186,6 +186,17 @@ function twoways($communicator, $p) $r = $p->opFloatDouble(3.402823466E38, 0.0, $f, $d); $r = $p->opFloatDouble(-3.402823466E38, 0.0, $f, $d); + foreach(array(NAN, -NAN) as $val) + { + $r = $p->opFloatDouble($val, $val, $f, $d); + test(is_nan($r) && is_nan($f) && is_nan($d)); + } + foreach(array(INF, -INF) as $val) + { + $r = $p->opFloatDouble($val, $val, $f, $d); + test(is_infinite($r) && is_infinite($f) && is_infinite($d)); + } + try { $r = $p->opFloatDouble(3.402823466E38*2, 0.0, $f, $d); diff --git a/python/modules/IcePy/Types.cpp b/python/modules/IcePy/Types.cpp index ea749bad672..45579378801 100644 --- a/python/modules/IcePy/Types.cpp +++ b/python/modules/IcePy/Types.cpp @@ -726,7 +726,7 @@ IcePy::PrimitiveInfo::validate(PyObject* p) { // Ensure double does not exceed maximum float value before casting double val = PyFloat_AsDouble(p); - return val <= numeric_limits<float>::max() && val >= -numeric_limits<float>::max(); + return (val <= numeric_limits<float>::max() && val >= -numeric_limits<float>::max()) || !isfinite(val); } break; diff --git a/python/test/Ice/operations/Twoways.py b/python/test/Ice/operations/Twoways.py index 1299a375d7a..f02109756ed 100644 --- a/python/test/Ice/operations/Twoways.py +++ b/python/test/Ice/operations/Twoways.py @@ -141,6 +141,13 @@ def twoways(communicator, p): r, f, d = p.opFloatDouble(3.402823466E38, 0.0) r, f, d = p.opFloatDouble(-3.402823466E38, 0.0) + for val in ('inf', '-inf'): + r, f, d = p.opFloatDouble(float(val), float(val)) + test(math.isinf(r) and math.isinf(f) and math.isinf(d)) + for val in ('nan', '-nan'): + r, f, d = p.opFloatDouble(float(val), float(val)) + test(math.isnan(r) and math.isnan(f) and math.isnan(d)) + try: r, f, d = p.opFloatDouble(3.402823466E38*2, 0.0) test(False) diff --git a/ruby/src/IceRuby/Types.cpp b/ruby/src/IceRuby/Types.cpp index a0272a86967..228a202a349 100644 --- a/ruby/src/IceRuby/Types.cpp +++ b/ruby/src/IceRuby/Types.cpp @@ -596,7 +596,7 @@ IceRuby::PrimitiveInfo::marshal(VALUE p, const Ice::OutputStreamPtr& os, ObjectM } assert(TYPE(val) == T_FLOAT); double d = static_cast<double>(RFLOAT_VALUE(val)); - if(d > numeric_limits<float>::max() || d < -numeric_limits<float>::max()) + if(isfinite(d) && (d > numeric_limits<float>::max() || d < -numeric_limits<float>::max())) { throw RubyException(rb_eTypeError, "value is out of range for a float"); } diff --git a/ruby/test/Ice/operations/Twoways.rb b/ruby/test/Ice/operations/Twoways.rb index c11a4955fd5..453a048b219 100644 --- a/ruby/test/Ice/operations/Twoways.rb +++ b/ruby/test/Ice/operations/Twoways.rb @@ -135,6 +135,15 @@ def twoways(communicator, p) r, f, d = p.opFloatDouble(3.402823466E38, 0.0) r, f, d = p.opFloatDouble(-3.402823466E38, 0.0) + for val in [Float::NAN, -Float::NAN] + r, f, d = p.opFloatDouble(val, val) + test(r.nan? && f.nan? && d.nan?) + end + for val in [Float::INFINITY, -Float::INFINITY] + r, f, d = p.opFloatDouble(val, val) + test(r.infinite? != 0 && f.infinite? != 0 && d.infinite? != 0) + end + begin r, f, d = p.opFloatDouble(3.402823466E38*2, 0.0) test(false) |