Skip to content

Commit

Permalink
Fix zephir_floor and zephir_ceil to be consistent and not dangerous t…
Browse files Browse the repository at this point in the history
…o use

Previously convert_scalar_to_number_ex was able to cause zval corruption,
when a string was passed as operand. The implementation now uses zephir
internal macro's and works as intended.
regression of fd7f8db
  • Loading branch information
steffen committed Apr 20, 2015
1 parent 941cd3e commit 1706383
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 35 deletions.
18 changes: 1 addition & 17 deletions Library/Optimizers/FunctionCall/CeilOptimizer.php
Expand Up @@ -49,25 +49,9 @@ public function optimize(array $expression, Call $call, CompilationContext $cont
return false;
}

/**
* Process the expected symbol to be returned
*/
$call->processExpectedReturn($context);

$symbolVariable = $call->getSymbolVariable(true, $context);
if ($symbolVariable->isNotVariableAndString()) {
throw new CompilerException("Returned values by functions can only be assigned to variant variables", $expression);
}

if ($call->mustInitSymbolVariable()) {
$symbolVariable->initVariant($context);
}

$context->headersManager->add('kernel/operators');
$symbolVariable->setDynamicTypes('double');

$resolvedParams = $call->getReadOnlyResolvedParams($expression['parameters'], $context, $expression);
$context->codePrinter->output('zephir_ceil(' . $symbolVariable->getName() . ', ' . $resolvedParams[0] . ' TSRMLS_CC);');
return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
return new CompiledExpression('double', 'zephir_ceil(' . $resolvedParams[0] . ' TSRMLS_CC)', $expression);
}
}
36 changes: 19 additions & 17 deletions ext/kernel/operators.c
Expand Up @@ -895,15 +895,16 @@ double zephir_safe_div_double_zval(double op1, zval *op2 TSRMLS_DC) {

double zephir_floor(zval *op1 TSRMLS_DC)
{
convert_scalar_to_number_ex(&op1);

if (Z_TYPE_PP(&op1) == IS_DOUBLE) {
return floor(Z_DVAL_PP(&op1));
} else if (Z_TYPE_PP(&op1) == IS_LONG) {
convert_to_double_ex(&op1);
return Z_DVAL_PP(&op1);
switch (Z_TYPE_P(op1)) {
case IS_LONG:
return (double) Z_LVAL_P(op1);
case IS_ARRAY:
case IS_OBJECT:
case IS_RESOURCE:
zend_error(E_WARNING, "Unsupported operand types");
break;
}
return 0;
return floor(zephir_get_numberval(op1));
}

/**
Expand Down Expand Up @@ -1022,17 +1023,18 @@ long zephir_safe_mod_double_zval(double op1, zval *op2 TSRMLS_DC) {
return (long) op1 % ((long) zephir_get_numberval(op2));
}

void zephir_ceil(zval *return_value, zval *op1 TSRMLS_DC)
double zephir_ceil(zval *op1 TSRMLS_DC)
{
convert_scalar_to_number_ex(&op1);

if (Z_TYPE_PP(&op1) == IS_DOUBLE) {
RETURN_DOUBLE(ceil(Z_DVAL_PP(&op1)));
} else if (Z_TYPE_PP(&op1) == IS_LONG) {
convert_to_double_ex(&op1);
RETURN_DOUBLE(Z_DVAL_PP(&op1));
switch (Z_TYPE_P(op1)) {
case IS_LONG:
return (double) Z_LVAL_P(op1);
case IS_ARRAY:
case IS_OBJECT:
case IS_RESOURCE:
zend_error(E_WARNING, "Unsupported operand types");
break;
}
RETURN_FALSE;
return ceil(zephir_get_numberval(op1));
}

extern double _php_math_round(double value, int places, int mode);
Expand Down
2 changes: 1 addition & 1 deletion ext/kernel/operators.h
Expand Up @@ -167,7 +167,7 @@ long zephir_safe_mod_long_zval(long op1, zval *op2 TSRMLS_DC);
long zephir_safe_mod_double_zval(double op1, zval *op2 TSRMLS_DC);

double zephir_floor(zval *op1 TSRMLS_DC);
void zephir_ceil(zval *return_value, zval *op1 TSRMLS_DC);
double zephir_ceil(zval *op1 TSRMLS_DC);
void zephir_round(zval *return_value, zval *op1, zval *op2, zval *op3 TSRMLS_DC);
void zephir_pow(zval *return_value, zval *op1, zval *op2 TSRMLS_DC);

Expand Down

0 comments on commit 1706383

Please sign in to comment.