Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions Zend/zend_operators.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand All @@ -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;
}
}
/* }}} */
Expand All @@ -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;
}

Expand All @@ -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);
}
Expand All @@ -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);
}
Expand Down
Loading