Permalink
Browse files

Fix zephir_floor and zephir_ceil to be consistent and not dangerous t…

…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
steffen committed Apr 20, 2015
1 parent 941cd3e commit 17063834f12c30e73b768c5bffc6a2c0437777cf
Showing with 21 additions and 35 deletions.
  1. +1 −17 Library/Optimizers/FunctionCall/CeilOptimizer.php
  2. +19 −17 ext/kernel/operators.c
  3. +1 −1 ext/kernel/operators.h
@@ -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);
}
}
@@ -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));
}
/**
@@ -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);
@@ -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);

0 comments on commit 1706383

Please sign in to comment.