From 183a507bf6ae32d9194aaf1fe277e16e0ee2e8ab Mon Sep 17 00:00:00 2001 From: Anton Vasiliev Date: Sun, 4 Apr 2021 23:48:44 +0100 Subject: [PATCH 1/5] #828 - Add failing test case --- stub/cast.zep | 15 +++++++++++++++ tests/Extension/CastTest.php | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/stub/cast.zep b/stub/cast.zep index a31e88ed4d..dca30ba709 100644 --- a/stub/cast.zep +++ b/stub/cast.zep @@ -483,4 +483,19 @@ class Cast return uids; } + public function testIssue828() -> array + { + array ret = []; + var version = "1.0 200 OK", floatVersion, intVersion; + + let ret[] = version; + + let floatVersion = (double)version, + intVersion = (int)version; + + let ret[] = floatVersion; + let ret[] = intVersion; + + return ret; + } } diff --git a/tests/Extension/CastTest.php b/tests/Extension/CastTest.php index d92482886c..b05fe5442c 100644 --- a/tests/Extension/CastTest.php +++ b/tests/Extension/CastTest.php @@ -205,4 +205,14 @@ public function testArrayCast(): void $this->assertEquals((array) 'aaa', $this->test->testArrayCastFromVariableString()); $this->assertEquals((array) ['p1' => 'v1', 'p2' => 'v2'], $this->test->testArrayCastFromVariableStdClass()); } + + public function testIssue828(): void + { + $return = $this->test->testIssue828(); + + $this->assertSame(['1.0 200 OK', 1.0, 1], $return); + $this->assertSame('1.0 200 OK', $return[0]); + $this->assertSame(1.0, $return[1]); + $this->assertSame(1, $return[2]); + } } From 12fbdc5ea95fc751d5e192d9aff3a99cb14c4b74 Mon Sep 17 00:00:00 2001 From: Anton Vasiliev Date: Mon, 5 Apr 2021 21:31:56 +0100 Subject: [PATCH 2/5] #828 - Fix zephir_get_intval_ex() and zephir_get_doubleval_ex() when value IS_STRING --- kernels/ZendEngine3/operators.c | 49 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/kernels/ZendEngine3/operators.c b/kernels/ZendEngine3/operators.c index 1cc0064ead..4be3cb29b0 100755 --- a/kernels/ZendEngine3/operators.c +++ b/kernels/ZendEngine3/operators.c @@ -277,6 +277,10 @@ void zephir_convert_to_object(zval *op) */ long zephir_get_intval_ex(const zval *op) { + int type; + double double_value = 0; + zend_long long_value = 0; + switch (Z_TYPE_P(op)) { case IS_ARRAY: return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1 : 0; @@ -301,19 +305,16 @@ long zephir_get_intval_ex(const zval *op) return (long) Z_DVAL_P(op); case IS_STRING: { - zend_uchar type; - double double_value = 0; - zend_long long_value = 0; - ASSUME(Z_STRVAL_P(op) != NULL); - type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, 0); - if (type == IS_LONG) { - return long_value; - } - if (type == IS_DOUBLE) { - return (long) double_value; - } - return 0; + + type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, true); + switch (type) { + case IS_LONG: + return long_value; + + case IS_DOUBLE: + return (long) double_value; + } } } @@ -358,11 +359,10 @@ long zephir_get_charval_ex(const zval *op) double zephir_get_doubleval_ex(const zval *op) { int type; - zend_long long_value = 0; - double double_value = 0; + double double_value = 0; + zend_long long_value = 0; switch (Z_TYPE_P(op)) { - case IS_ARRAY: return zend_hash_num_elements(Z_ARRVAL_P(op)) ? (double) 1 : 0; @@ -384,17 +384,14 @@ double zephir_get_doubleval_ex(const zval *op) return Z_DVAL_P(op); case IS_STRING: - if ((type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, 0))) { - if (type == IS_LONG) { - return (double) long_value; - } else { - if (type == IS_DOUBLE) { - return double_value; - } else { - return 0; - } - } - } + type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, true); + switch (type) { + case IS_LONG: + return (double) long_value; + + case IS_DOUBLE: + return double_value; + } } return 0; From 889ef5bd39e42ba1cf2b89e463aff679773e546d Mon Sep 17 00:00:00 2001 From: Anton Vasiliev Date: Mon, 5 Apr 2021 21:37:18 +0100 Subject: [PATCH 3/5] #828 - Change `true` to `1` to be PHP7.4 complaint --- kernels/ZendEngine3/operators.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernels/ZendEngine3/operators.c b/kernels/ZendEngine3/operators.c index 4be3cb29b0..7b7749e934 100755 --- a/kernels/ZendEngine3/operators.c +++ b/kernels/ZendEngine3/operators.c @@ -307,7 +307,7 @@ long zephir_get_intval_ex(const zval *op) case IS_STRING: { ASSUME(Z_STRVAL_P(op) != NULL); - type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, true); + type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, 1); switch (type) { case IS_LONG: return long_value; @@ -384,7 +384,7 @@ double zephir_get_doubleval_ex(const zval *op) return Z_DVAL_P(op); case IS_STRING: - type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, true); + type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &long_value, &double_value, 1); switch (type) { case IS_LONG: return (double) long_value; From 5152dd9f108f100d4a6677f5e558bb4cb2f1a116 Mon Sep 17 00:00:00 2001 From: Anton Vasiliev Date: Mon, 5 Apr 2021 21:37:34 +0100 Subject: [PATCH 4/5] #828 - Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b469d2229..2bf1bb1678 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org). ## [Unreleased] ### Fixed - Fixed default value of nullable string parameter [#2180](https://github.com/zephir-lang/zephir/issues/2180) +- Fixed cast of `string` to `int` and `float` [#828](https://github.com/zephir-lang/zephir/issues/828) ## [0.13.1] - 2021-03-31 ### Added From e318c1d90fb7a7080e7aa5a924ae45813d864c55 Mon Sep 17 00:00:00 2001 From: Anton Vasiliev Date: Mon, 5 Apr 2021 21:45:42 +0100 Subject: [PATCH 5/5] #828 - Add extra test cases --- stub/cast.zep | 9 +++++++-- tests/Extension/CastTest.php | 9 ++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/stub/cast.zep b/stub/cast.zep index dca30ba709..c6fd1c9dc9 100644 --- a/stub/cast.zep +++ b/stub/cast.zep @@ -486,15 +486,20 @@ class Cast public function testIssue828() -> array { array ret = []; - var version = "1.0 200 OK", floatVersion, intVersion; + var version = "1.0 200 OK", nonNumericString = "OK", floatVersion, intVersion, floatNonNumeric, intNonNumeric; let ret[] = version; + let ret[] = nonNumericString; let floatVersion = (double)version, - intVersion = (int)version; + intVersion = (int)version, + floatNonNumeric = (double)nonNumericString, + intNonNumeric = (int)nonNumericString; let ret[] = floatVersion; let ret[] = intVersion; + let ret[] = floatNonNumeric; + let ret[] = intNonNumeric; return ret; } diff --git a/tests/Extension/CastTest.php b/tests/Extension/CastTest.php index b05fe5442c..ca5652a4c1 100644 --- a/tests/Extension/CastTest.php +++ b/tests/Extension/CastTest.php @@ -210,9 +210,12 @@ public function testIssue828(): void { $return = $this->test->testIssue828(); - $this->assertSame(['1.0 200 OK', 1.0, 1], $return); + $this->assertSame(['1.0 200 OK', 'OK', 1.0, 1, 0.0, 0], $return); $this->assertSame('1.0 200 OK', $return[0]); - $this->assertSame(1.0, $return[1]); - $this->assertSame(1, $return[2]); + $this->assertSame('OK', $return[1]); + $this->assertSame(1.0, $return[2]); + $this->assertSame(1, $return[3]); + $this->assertSame(0.0, $return[4]); + $this->assertSame(0, $return[5]); } }