Skip to content

Commit 95de410

Browse files
committed
ext/gmp: Be more strict on exponent/shift value
1 parent ac2f487 commit 95de410

File tree

4 files changed

+141
-1
lines changed

4 files changed

+141
-1
lines changed

ext/gmp/gmp.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,24 @@ static zend_object *gmp_clone_obj(zend_object *obj) /* {{{ */
339339
/* }}} */
340340

341341
static void shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zval *op1, zval *op2, uint8_t opcode) {
342-
zend_long shift = zval_get_long(op2);
342+
bool failed = true;
343+
zend_long shift = zval_try_get_long(op2, &failed);
344+
if (failed) {
345+
//char operator_sigil[2];
346+
char *operator_sigil;
347+
if (opcode == ZEND_POW) {
348+
operator_sigil = "**";
349+
} else if (opcode == ZEND_SL) {
350+
operator_sigil = "<<";
351+
} else {
352+
ZEND_ASSERT(opcode == ZEND_SR);
353+
operator_sigil = ">>";
354+
}
355+
356+
zend_type_error("Unsupported operand types: GMP %s %s", operator_sigil, zend_zval_value_name(op2));
357+
ZVAL_UNDEF(return_value);
358+
return;
359+
}
343360

344361
if (shift < 0) {
345362
zend_throw_error(

ext/gmp/tests/gmp_pow_error.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Native exponential with invalid exponent
3+
--EXTENSIONS--
4+
gmp
5+
--FILE--
6+
<?php
7+
8+
try {
9+
$n = gmp_init("6");
10+
var_dump($n ** "nonsense");
11+
} catch (\Throwable $e) {
12+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
13+
}
14+
try {
15+
$n = gmp_init("6");
16+
var_dump($n ** new stdClass());
17+
} catch (\Throwable $e) {
18+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
19+
}
20+
try {
21+
$n = gmp_init("6");
22+
var_dump($n ** STDERR);
23+
} catch (\Throwable $e) {
24+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
25+
}
26+
try {
27+
$n = gmp_init("6");
28+
var_dump($n ** []);
29+
} catch (\Throwable $e) {
30+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
31+
}
32+
33+
34+
echo "Done\n";
35+
?>
36+
--EXPECT--
37+
TypeError: Unsupported operand types: GMP ** string
38+
TypeError: Unsupported operand types: GMP ** stdClass
39+
TypeError: Unsupported operand types: GMP ** resource
40+
TypeError: Unsupported operand types: GMP ** array
41+
Done
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Native shift left with invalid op2
3+
--EXTENSIONS--
4+
gmp
5+
--FILE--
6+
<?php
7+
8+
try {
9+
$n = gmp_init("6");
10+
var_dump($n << "nonsense");
11+
} catch (\Throwable $e) {
12+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
13+
}
14+
try {
15+
$n = gmp_init("6");
16+
var_dump($n << new stdClass());
17+
} catch (\Throwable $e) {
18+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
19+
}
20+
try {
21+
$n = gmp_init("6");
22+
var_dump($n << STDERR);
23+
} catch (\Throwable $e) {
24+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
25+
}
26+
try {
27+
$n = gmp_init("6");
28+
var_dump($n << []);
29+
} catch (\Throwable $e) {
30+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
31+
}
32+
33+
34+
echo "Done\n";
35+
?>
36+
--EXPECT--
37+
TypeError: Unsupported operand types: GMP << string
38+
TypeError: Unsupported operand types: GMP << stdClass
39+
TypeError: Unsupported operand types: GMP << resource
40+
TypeError: Unsupported operand types: GMP << array
41+
Done
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Native shift right with invalid op2
3+
--EXTENSIONS--
4+
gmp
5+
--FILE--
6+
<?php
7+
8+
try {
9+
$n = gmp_init("6");
10+
var_dump($n >> "nonsense");
11+
} catch (\Throwable $e) {
12+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
13+
}
14+
try {
15+
$n = gmp_init("6");
16+
var_dump($n >> new stdClass());
17+
} catch (\Throwable $e) {
18+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
19+
}
20+
try {
21+
$n = gmp_init("6");
22+
var_dump($n >> STDERR);
23+
} catch (\Throwable $e) {
24+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
25+
}
26+
try {
27+
$n = gmp_init("6");
28+
var_dump($n >> []);
29+
} catch (\Throwable $e) {
30+
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
31+
}
32+
33+
34+
echo "Done\n";
35+
?>
36+
--EXPECT--
37+
TypeError: Unsupported operand types: GMP >> string
38+
TypeError: Unsupported operand types: GMP >> stdClass
39+
TypeError: Unsupported operand types: GMP >> resource
40+
TypeError: Unsupported operand types: GMP >> array
41+
Done

0 commit comments

Comments
 (0)