Skip to content

Commit

Permalink
Merge pull request #2194 from zephir-lang/#828-string-cast-int-float
Browse files Browse the repository at this point in the history
#828 - Fix cast `string` to `int` and `float`
  • Loading branch information
AlexNDRmac authored Apr 6, 2021
2 parents 96aa055 + e318c1d commit 3053aa8
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 23 additions & 26 deletions kernels/ZendEngine3/operators.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
}

Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions stub/cast.zep
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
13 changes: 13 additions & 0 deletions tests/Extension/CastTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
}

0 comments on commit 3053aa8

Please sign in to comment.