From 8fc29bd1b16c3dc6dc4ecf0e74cbfa72ac7b8c4a Mon Sep 17 00:00:00 2001 From: Adrien Crivelli Date: Mon, 1 Aug 2016 02:42:58 +0900 Subject: [PATCH] Fix unit tests for all base conversion functions This include cases were artificial constraints were not checked (eg: between -512 and 511 for `DECBIN`) and some bugs were 32 bits platform were assumed. The following are covered: `BIN2DEC`, `BIN2HEX`, `BIN2OCT`, `DEC2BIN`, `DEC2HEX`, `DEC2OCT`, `HEX2BIN`, `HEX2DEC`, `HEX2OCT`, `OCT2BIN`, `OCT2DEC`, `OCT2HEX` --- .../Calculation/Engineering.php | 38 +++++++++++-------- .../src/Calculation/EngineeringTest.php | 5 --- .../Calculation/Engineering/DEC2BIN.data | 4 +- .../Calculation/Engineering/HEX2BIN.data | 8 +++- .../Calculation/Engineering/HEX2DEC.data | 6 ++- .../Calculation/Engineering/OCT2BIN.data | 4 ++ 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Engineering.php b/src/PhpSpreadsheet/Calculation/Engineering.php index b3305464..0d1cca46 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering.php +++ b/src/PhpSpreadsheet/Calculation/Engineering.php @@ -1327,12 +1327,16 @@ class Engineering if (strlen($x) > preg_match_all('/[-0123456789.]/', $x, $out)) { return Functions::VALUE(); } + $x = (string)floor($x); + if ($x < -512 || $x > 511) { + return Functions::NAN(); + } + $r = decbin($x); - if (strlen($r) == 32) { - // Two's Complement - $r = substr($r, -10); - } elseif (strlen($r) >= 11) { + // Two's Complement + $r = substr($r, -10); + if (strlen($r) >= 11) { return Functions::NAN(); } @@ -1491,11 +1495,8 @@ class Engineering if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { return Functions::NAN(); } - if (hexdec($x) > 0x1FF) { - return Functions::NAN(); - } - $binVal = decbin(hexdec($x)); - return substr(self::nbrConversionFormat($binVal, $places), -10); + + return self::DECTOBIN(self::HEXTODEC($x), $places); } @@ -1529,9 +1530,14 @@ class Engineering if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { return Functions::NAN(); } + + if (strlen($x)> 10) { + return Functions::NAN(); + } + $binX = ''; foreach (str_split($x) as $char) { - $binX .= str_pad(base_convert($char, 16, 2), 3, '0', STR_PAD_LEFT); + $binX .= str_pad(base_convert($char, 16, 2), 4, '0', STR_PAD_LEFT); } if (strlen($binX) == 40 && $binX[0] == '1') { for ($i = 0; $i < 40; $i++) { @@ -1587,12 +1593,15 @@ class Engineering if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/', strtoupper($x), $out)) { return Functions::NAN(); } - $octVal = decoct(hexdec($x)); - return self::nbrConversionFormat($octVal, $places); + $decimal = self::HEXTODEC($x); + if ($decimal < -536870912 || $decimal > 536870911) { + return Functions::NAN(); + } + + return self::DECTOOCT($decimal, $places); } - /** * OCTTOBIN * @@ -1639,9 +1648,8 @@ class Engineering if (preg_match_all('/[01234567]/', $x, $out) != strlen($x)) { return Functions::NAN(); } - $r = decbin(octdec($x)); - return self::nbrConversionFormat($r, $places); + return self::DECTOBIN(self::OCTTODEC($x), $places); } diff --git a/unitTests/Classes/src/Calculation/EngineeringTest.php b/unitTests/Classes/src/Calculation/EngineeringTest.php index b5b03ab5..75a85474 100644 --- a/unitTests/Classes/src/Calculation/EngineeringTest.php +++ b/unitTests/Classes/src/Calculation/EngineeringTest.php @@ -472,7 +472,6 @@ class EngineeringTest extends \PHPUnit_Framework_TestCase /** * @dataProvider providerDEC2BIN - * @group fail19 */ public function testDEC2BIN() { @@ -521,7 +520,6 @@ class EngineeringTest extends \PHPUnit_Framework_TestCase /** * @dataProvider providerHEX2BIN - * @group fail19 */ public function testHEX2BIN() { @@ -538,7 +536,6 @@ class EngineeringTest extends \PHPUnit_Framework_TestCase /** * @dataProvider providerHEX2DEC - * @group fail19 */ public function testHEX2DEC() { @@ -555,7 +552,6 @@ class EngineeringTest extends \PHPUnit_Framework_TestCase /** * @dataProvider providerHEX2OCT - * @group fail19 */ public function testHEX2OCT() { @@ -572,7 +568,6 @@ class EngineeringTest extends \PHPUnit_Framework_TestCase /** * @dataProvider providerOCT2BIN - * @group fail19 */ public function testOCT2BIN() { diff --git a/unitTests/rawTestData/Calculation/Engineering/DEC2BIN.data b/unitTests/rawTestData/Calculation/Engineering/DEC2BIN.data index 403ced63..a93cadce 100644 --- a/unitTests/rawTestData/Calculation/Engineering/DEC2BIN.data +++ b/unitTests/rawTestData/Calculation/Engineering/DEC2BIN.data @@ -1,5 +1,6 @@ 357, "101100101" -1357, "#NUM!" // Too large +512, "#NUM!" // Too large +-513, "#NUM!" // Too small 9, 4, "1001" 9, 8, "00001001" 9, 6.75, "001001" // Leading places as a float @@ -14,3 +15,4 @@ TRUE, "#VALUE!" // Non string -100, "1110011100" // 2's Complement -107, "1110010101" // 2's Complement +-512, "1000000000" // 2's Complement diff --git a/unitTests/rawTestData/Calculation/Engineering/HEX2BIN.data b/unitTests/rawTestData/Calculation/Engineering/HEX2BIN.data index b4a5e71e..e0e91707 100644 --- a/unitTests/rawTestData/Calculation/Engineering/HEX2BIN.data +++ b/unitTests/rawTestData/Calculation/Engineering/HEX2BIN.data @@ -1,3 +1,8 @@ +"FF", "11111111" +"1FF", "111111111" +"200", "#NUM!" +"FFFFFFFE00", "1000000000" // 2's Complement +"FFFFFFFDFF", "#NUM!" // 2's Complement "01AB", "110101011" "ABCD", "#NUM!" "F6", "11110110" @@ -9,5 +14,4 @@ "0", "0" "G3579A", "#NUM!" TRUE, "#VALUE!" -"-107", "#NUM!" -"FFFFFFFFFF", "1111111111" // 2's Complement +"-107", "#NUM!" \ No newline at end of file diff --git a/unitTests/rawTestData/Calculation/Engineering/HEX2DEC.data b/unitTests/rawTestData/Calculation/Engineering/HEX2DEC.data index 84dd3391..45bfddf1 100644 --- a/unitTests/rawTestData/Calculation/Engineering/HEX2DEC.data +++ b/unitTests/rawTestData/Calculation/Engineering/HEX2DEC.data @@ -9,5 +9,7 @@ TRUE, "#VALUE!" "-107", "#NUM!" "A5", "165" -"FFFFFFFF5B", "-165" -"3DA408B9", "1034160313" // 2's Complement +"3DA408B9", "1034160313" +"FFFFFFFF5B", "-165" // 2's Complement +"FFFFFFFFFF", "-1" // 2's Complement +"1FFFFFFFFFF", "#NUM!" // Too large diff --git a/unitTests/rawTestData/Calculation/Engineering/OCT2BIN.data b/unitTests/rawTestData/Calculation/Engineering/OCT2BIN.data index 58a49e9e..0573b9fd 100644 --- a/unitTests/rawTestData/Calculation/Engineering/OCT2BIN.data +++ b/unitTests/rawTestData/Calculation/Engineering/OCT2BIN.data @@ -7,3 +7,7 @@ TRUE, "#VALUE!" "3579", "#NUM!" "7777777000", "1000000000" // 2's Complement +"7777777777", "1111111111" // 2's Complement +"17777777777", "#NUM!" // Too small +"777", "111111111" +"1777", "#NUM!" // Too large