summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2015-12-02 11:28:31 -0800
committerMark Spruiell <mes@zeroc.com>2015-12-02 11:28:31 -0800
commit7ea494f049785c1adf0ec7693cae7744276e42d2 (patch)
tree889a2cdbf371c155a26b6225e2b0c03d58b840ab
parentFix for ICE-6896 - sporadic binding test failure with the Python language map... (diff)
downloadice-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.md3
-rw-r--r--js/src/Ice/BasicStream.js10
-rw-r--r--js/test/Ice/operations/Twoways.js23
-rw-r--r--php/src/IcePHP/Types.cpp2
-rw-r--r--php/test/Ice/operations/Client.php11
-rw-r--r--python/modules/IcePy/Types.cpp2
-rw-r--r--python/test/Ice/operations/Twoways.py7
-rw-r--r--ruby/src/IceRuby/Types.cpp2
-rw-r--r--ruby/test/Ice/operations/Twoways.rb9
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)