Skip to content

Commit 9f2d061

Browse files
committed
Added deprecation Division by zero when using power with zero as base and negative exponent
1 parent 1d641f6 commit 9f2d061

File tree

8 files changed

+811
-41
lines changed

8 files changed

+811
-41
lines changed

Zend/tests/runtime_compile_time_binary_operands.phpt

Lines changed: 710 additions & 1 deletion
Large diffs are not rendered by default.

Zend/zend_compile.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8730,6 +8730,10 @@ ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, const zval *op1, co
87308730
/* Division by zero throws an error. */
87318731
return 1;
87328732
}
8733+
if ((opcode == ZEND_POW) && zval_get_long(op1) == 0 && zval_get_long(op2) <= 0) {
8734+
/* 0 ** (<=0) throws a division by zero error. */
8735+
zend_error(E_DEPRECATED, "Power of base 0 and negative exponent is deprecated");
8736+
}
87338737
if ((opcode == ZEND_SL || opcode == ZEND_SR) && zval_get_long(op2) < 0) {
87348738
/* Shift by negative number throws an error. */
87358739
return 1;

Zend/zend_operators.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,21 @@ ZEND_API zend_result ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *o
12871287
}
12881288
/* }}} */
12891289

1290+
static void ZEND_COLD zend_power_base_0_exponent_lt_eq_0_error(void)
1291+
{
1292+
zend_error(E_DEPRECATED, "Power of base 0 and negative exponent is deprecated");
1293+
}
1294+
1295+
static zend_result safe_pow(double *result, double base, double exponent)
1296+
{
1297+
if (base == 0.0 && exponent <= 0.0) {
1298+
zend_power_base_0_exponent_lt_eq_0_error();
1299+
}
1300+
1301+
*result = pow(base, exponent);
1302+
return SUCCESS;
1303+
}
1304+
12901305
static zend_result ZEND_FASTCALL pow_function_base(zval *result, zval *op1, zval *op2) /* {{{ */
12911306
{
12921307
uint8_t type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2));
@@ -1311,32 +1326,44 @@ static zend_result ZEND_FASTCALL pow_function_base(zval *result, zval *op1, zval
13111326
--i;
13121327
ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
13131328
if (overflow) {
1314-
ZVAL_DOUBLE(result, dval * pow(l2, i));
1329+
double pow_result;
1330+
safe_pow(&pow_result, l2, i);
1331+
ZVAL_DOUBLE(result, dval * pow_result);
13151332
return SUCCESS;
13161333
}
13171334
} else {
13181335
i /= 2;
13191336
ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
13201337
if (overflow) {
1321-
ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
1338+
double pow_result;
1339+
safe_pow(&pow_result, dval, i);
1340+
ZVAL_DOUBLE(result, (double)l1 * pow_result);
13221341
return SUCCESS;
13231342
}
13241343
}
13251344
}
13261345
/* i == 0 */
13271346
ZVAL_LONG(result, l1);
13281347
} else {
1329-
ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
1348+
double pow_result;
1349+
safe_pow(&pow_result, (double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2));
1350+
ZVAL_DOUBLE(result, pow_result);
13301351
}
13311352
return SUCCESS;
13321353
} else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) {
1333-
ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
1354+
double pow_result;
1355+
safe_pow(&pow_result, Z_DVAL_P(op1), Z_DVAL_P(op2));
1356+
ZVAL_DOUBLE(result, pow_result);
13341357
return SUCCESS;
13351358
} else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) {
1336-
ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
1359+
double pow_result;
1360+
safe_pow(&pow_result, (double)Z_LVAL_P(op1), Z_DVAL_P(op2));
1361+
ZVAL_DOUBLE(result, pow_result);
13371362
return SUCCESS;
13381363
} else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) {
1339-
ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
1364+
double pow_result;
1365+
safe_pow(&pow_result, Z_DVAL_P(op1), (double)Z_LVAL_P(op2));
1366+
ZVAL_DOUBLE(result, pow_result);
13401367
return SUCCESS;
13411368
} else {
13421369
return FAILURE;
@@ -1372,7 +1399,7 @@ ZEND_API zend_result ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *o
13721399
return SUCCESS;
13731400
}
13741401

1375-
ZEND_ASSERT(0 && "Operation must succeed");
1402+
ZVAL_UNDEF(result);
13761403
return FAILURE;
13771404
}
13781405
/* }}} */

ext/standard/tests/math/bug45712.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var_dump($inf==='abc');
4242
var_dump($inf===$inf);
4343

4444
?>
45-
--EXPECT--
45+
--EXPECTF--
4646
float(NAN)
4747
bool(true)
4848
bool(false)
@@ -57,6 +57,8 @@ bool(false)
5757
bool(false)
5858
bool(false)
5959
bool(false)
60+
61+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
6062
float(INF)
6163
bool(true)
6264
bool(false)

ext/standard/tests/math/is_finite_basic.phpt

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,29 @@
22
Test is_finite() - basic function test is_finite()
33
--FILE--
44
<?php
5-
$values = array(234,
6-
-234,
7-
23.45e1,
8-
-23.45e1,
9-
0xEA,
10-
0352,
11-
"234",
12-
"234.5",
13-
"23.45e1",
14-
true,
15-
false,
16-
pow(0, -2),
17-
acos(1.01));
18-
;
5+
$values = [
6+
234,
7+
-234,
8+
23.45e1,
9+
-23.45e1,
10+
0xea,
11+
0352,
12+
"234",
13+
"234.5",
14+
"23.45e1",
15+
true,
16+
false,
17+
pow(0, -2),
18+
acos(1.01),
19+
];
1920
for ($i = 0; $i < count($values); $i++) {
2021
$res = is_finite($values[$i]);
2122
var_dump($res);
2223
}
2324
?>
24-
--EXPECT--
25+
--EXPECTF--
26+
27+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
2528
bool(true)
2629
bool(true)
2730
bool(true)

ext/standard/tests/math/is_infinite_basic.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ for ($i = 0; $i < count($values); $i++) {
2121
var_dump($res);
2222
}
2323
?>
24-
--EXPECT--
24+
--EXPECTF--
25+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
2526
bool(false)
2627
bool(false)
2728
bool(false)

ext/standard/tests/math/is_nan_basic.phpt

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,30 @@
22
Test is_nan() - basic function test is_nan()
33
--FILE--
44
<?php
5-
$values = array(234,
6-
-234,
7-
23.45e1,
8-
-23.45e1,
9-
0xEA,
10-
0352,
11-
"234",
12-
"234.5",
13-
"23.45e1",
14-
true,
15-
false,
16-
pow(0, -2),
17-
acos(1.01));
18-
5+
$values = [
6+
234,
7+
-234,
8+
23.45e1,
9+
-23.45e1,
10+
0xea,
11+
0352,
12+
"234",
13+
"234.5",
14+
"23.45e1",
15+
true,
16+
false,
17+
pow(0, -2),
18+
acos(1.01),
19+
];
1920

2021
for ($i = 0; $i < count($values); $i++) {
2122
$res = is_nan($values[$i]);
2223
var_dump($res);
2324
}
2425

2526
?>
26-
--EXPECT--
27+
--EXPECTF--
28+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
2729
bool(false)
2830
bool(false)
2931
bool(false)

ext/standard/tests/math/pow.phpt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ var_dump(epsilon_equal( LONG_MAX*LONG_MAX , pow(LONG_MAX,2.0) ));
143143
var_dump(epsilon_equal( LONG_MIN*LONG_MIN , pow(LONG_MIN,2.0) ));
144144

145145
?>
146-
--EXPECT--
146+
--EXPECTF--
147147
1,1,0,0
148148
bool(true)
149149
bool(true)
@@ -155,7 +155,11 @@ bool(true)
155155
bool(true)
156156
bool(true)
157157
bool(true)
158+
159+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
158160
bool(true)
161+
162+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
159163
bool(true)
160164
bool(true)
161165
bool(true)
@@ -180,8 +184,14 @@ bool(true)
180184
bool(true)
181185
bool(true)
182186
bool(true)
187+
188+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
183189
bool(true)
190+
191+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
184192
bool(true)
193+
194+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
185195
bool(true)
186196
bool(true)
187197
bool(true)
@@ -212,8 +222,14 @@ bool(true)
212222
bool(true)
213223
bool(true)
214224
bool(true)
225+
226+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
215227
bool(true)
228+
229+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
216230
bool(true)
231+
232+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
217233
bool(true)
218234
bool(true)
219235
bool(true)
@@ -237,8 +253,14 @@ bool(true)
237253
bool(true)
238254
bool(true)
239255
bool(true)
256+
257+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
240258
bool(true)
259+
260+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
241261
bool(true)
262+
263+
Deprecated: Power of base 0 and negative exponent is deprecated in %s on line %d
242264
bool(true)
243265
bool(true)
244266
bool(true)

0 commit comments

Comments
 (0)