diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b469d222..2bf1bb167 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 diff --git a/kernels/ZendEngine3/operators.c b/kernels/ZendEngine3/operators.c index 1cc0064ea..7b7749e93 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, 1); + 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, 1); + switch (type) { + case IS_LONG: + return (double) long_value; + + case IS_DOUBLE: + return double_value; + } } return 0; diff --git a/stub/cast.zep b/stub/cast.zep index a31e88ed4..c6fd1c9dc 100644 --- a/stub/cast.zep +++ b/stub/cast.zep @@ -483,4 +483,24 @@ class Cast return uids; } + public function testIssue828() -> array + { + array ret = []; + 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, + 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 d92482886..ca5652a4c 100644 --- a/tests/Extension/CastTest.php +++ b/tests/Extension/CastTest.php @@ -205,4 +205,17 @@ 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', 'OK', 1.0, 1, 0.0, 0], $return); + $this->assertSame('1.0 200 OK', $return[0]); + $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]); + } }