Zend: Use a dedicated enum for the status of the result of a division (#16020)

This commit is contained in:
Gina Peter Banyard 2024-09-24 20:43:06 +01:00 committed by GitHub
parent 623c327d12
commit d95e222402
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1389,10 +1389,13 @@ ZEND_API zend_result ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *o
}
/* }}} */
/* Returns SUCCESS/TYPES_NOT_HANDLED/DIV_BY_ZERO */
#define TYPES_NOT_HANDLED 1
#define DIV_BY_ZERO 2
static int ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval *op2) /* {{{ */
typedef enum {
DIV_SUCCESS,
DIV_BY_ZERO,
DIV_TYPES_NOT_HANDLED
} zend_div_status;
static zend_div_status ZEND_FASTCALL div_function_base(zval *result, const zval *op1, const zval *op2) /* {{{ */
{
uint8_t type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2));
@ -1402,34 +1405,34 @@ static int ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval *op2) /
} else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN) {
/* Prevent overflow error/crash */
ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
return SUCCESS;
return DIV_SUCCESS;
}
if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
} else {
ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
}
return SUCCESS;
return DIV_SUCCESS;
} else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) {
if (Z_DVAL_P(op2) == 0) {
return DIV_BY_ZERO;
}
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
return SUCCESS;
return DIV_SUCCESS;
} else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) {
if (Z_LVAL_P(op2) == 0) {
return DIV_BY_ZERO;
}
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
return SUCCESS;
return DIV_SUCCESS;
} else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) {
if (Z_DVAL_P(op2) == 0) {
return DIV_BY_ZERO;
}
ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
return SUCCESS;
return DIV_SUCCESS;
} else {
return TYPES_NOT_HANDLED;
return DIV_TYPES_NOT_HANDLED;
}
}
/* }}} */
@ -1439,8 +1442,8 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o
ZVAL_DEREF(op1);
ZVAL_DEREF(op2);
int retval = div_function_base(result, op1, op2);
if (EXPECTED(retval == SUCCESS)) {
zend_div_status retval = div_function_base(result, op1, op2);
if (EXPECTED(retval == DIV_SUCCESS)) {
return SUCCESS;
}
@ -1461,7 +1464,7 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o
}
retval = div_function_base(&result_copy, &op1_copy, &op2_copy);
if (retval == SUCCESS) {
if (retval == DIV_SUCCESS) {
if (result == op1) {
zval_ptr_dtor(result);
}
@ -1470,7 +1473,7 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o
}
div_by_zero:
ZEND_ASSERT(retval == DIV_BY_ZERO && "TYPES_NOT_HANDLED should not occur here");
ZEND_ASSERT(retval == DIV_BY_ZERO && "DIV_TYPES_NOT_HANDLED should not occur here");
if (result != op1) {
ZVAL_UNDEF(result);
}