From 78725f3fcf675e721a60dad922a48b78e307163a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiemo=20M=C3=A4ttig?= Date: Mon, 11 Jul 2016 10:17:42 +0200 Subject: [PATCH] Fix integer overflow in DecimalValue --- src/DataValues/DecimalValue.php | 8 ++++---- tests/DataValues/DecimalValueTest.php | 12 +++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/DataValues/DecimalValue.php b/src/DataValues/DecimalValue.php index 96c9518..beb7e6a 100644 --- a/src/DataValues/DecimalValue.php +++ b/src/DataValues/DecimalValue.php @@ -46,7 +46,7 @@ class DecimalValue extends DataValueObject { * Constructs a new DecimalValue object, representing the given value. * * @param string|int|float $value If given as a string, the value must match - * QUANTITY_VALUE_PATTERN. + * QUANTITY_VALUE_PATTERN. The leading plus sign is optional. * * @throws IllegalValueException */ @@ -91,8 +91,8 @@ private function convertToDecimal( $number ) { throw new InvalidArgumentException( '$number must not be NAN or INF.' ); } - if ( is_int( $number ) || ( $number === floor( $number ) ) ) { - $decimal = strval( abs( (int)$number ) ); + if ( is_int( $number ) || $number === (float)(int)$number ) { + $decimal = strval( (int)abs( $number ) ); } else { $decimal = trim( number_format( abs( $number ), 100, '.', '' ), '0' ); @@ -101,7 +101,7 @@ private function convertToDecimal( $number ) { } if ( substr( $decimal, -1 ) === '.' ) { - $decimal .= '0'; + $decimal = substr( $decimal, 0, -1 ); } } diff --git a/tests/DataValues/DecimalValueTest.php b/tests/DataValues/DecimalValueTest.php index bf901c7..774d9dc 100644 --- a/tests/DataValues/DecimalValueTest.php +++ b/tests/DataValues/DecimalValueTest.php @@ -33,6 +33,7 @@ public function validConstructorArgumentsProvider() { $argLists[] = array( 4.2 ); $argLists[] = array( -4.2 ); $argLists[] = array( '+4.2' ); + $argLists[] = array( " +4.2\n" ); $argLists[] = array( 0 ); $argLists[] = array( 0.2 ); $argLists[] = array( '-0.42' ); @@ -41,9 +42,10 @@ public function validConstructorArgumentsProvider() { $argLists[] = array( '+0' ); $argLists[] = array( '+0.0' ); $argLists[] = array( '+0.000' ); + $argLists[] = array( '+1.' . str_repeat( '0', 124 ) ); $argLists[] = array( '+1.0' . str_repeat( ' ', 124 ) ); $argLists[] = array( '4.2' ); - $argLists[] = array( ' 4.2' ); + $argLists[] = array( " 4.2\n" ); return $argLists; } @@ -57,11 +59,13 @@ public function invalidConstructorArgumentsProvider() { $argLists[] = array( '--4.2' ); $argLists[] = array( '-+4.2' ); $argLists[] = array( '+-4.2' ); + $argLists[] = array( '+/-0' ); $argLists[] = array( '-.42' ); $argLists[] = array( '+.42' ); $argLists[] = array( '.42' ); $argLists[] = array( '.0' ); $argLists[] = array( '-00' ); + $argLists[] = array( '−1' ); $argLists[] = array( '+01.2' ); $argLists[] = array( 'x2' ); $argLists[] = array( '2x' ); @@ -176,6 +180,12 @@ public function getValueProvider() { $argLists[] = array( new DecimalValue( '-0' ), '+0' ); $argLists[] = array( new DecimalValue( '+0.0' ), '+0.0' ); $argLists[] = array( new DecimalValue( '+0' ), '+0' ); + $argLists[] = array( new DecimalValue( 2147483649 ), '+2147483649' ); + $argLists[] = array( new DecimalValue( 1000000000000000 ), '+1000000000000000' ); + $argLists[] = array( + new DecimalValue( 1 + 1e-14 / 3 ), + '+1.0000000000000033306690738754696212708950042724609375' + ); return $argLists; }