Skip to content

Commit abecaab

Browse files
Girgiascmb69
authored andcommitted
Fix #80560: Strings containing only a base prefix return 0 object
Closes GH-6549.
1 parent da0ca53 commit abecaab

File tree

2 files changed

+225
-3
lines changed

2 files changed

+225
-3
lines changed

ext/gmp/gmp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ if (IS_GMP(zval)) { \
174174
gmp_create(return_value, &gmpnumber)
175175

176176
static void gmp_strval(zval *result, mpz_t gmpnum, int base);
177-
static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos);
177+
static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos);
178178
static void gmp_cmp(zval *return_value, zval *a_arg, zval *b_arg);
179179

180180
/*
@@ -585,7 +585,7 @@ ZEND_MODULE_INFO_D(gmp)
585585

586586
/* {{{ convert_to_gmp
587587
* Convert zval to be gmp number */
588-
static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos)
588+
static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos)
589589
{
590590
switch (Z_TYPE_P(val)) {
591591
case IS_LONG:
@@ -596,7 +596,7 @@ static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t a
596596
zend_bool skip_lead = 0;
597597
int ret;
598598

599-
if (Z_STRLEN_P(val) > 2 && numstr[0] == '0') {
599+
if (Z_STRLEN_P(val) >= 2 && numstr[0] == '0') {
600600
if ((base == 0 || base == 16) && (numstr[1] == 'x' || numstr[1] == 'X')) {
601601
base = 16;
602602
skip_lead = 1;

ext/gmp/tests/bug80560.phpt

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
--TEST--
2+
Bug #80560: Strings containing only a base prefix return 0 object
3+
--SKIPIF--
4+
<?php if (!extension_loaded("gmp")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
8+
$functions1 = [
9+
'gmp_init',
10+
'gmp_export',
11+
'gmp_intval',
12+
'gmp_strval',
13+
'gmp_neg',
14+
'gmp_abs',
15+
'gmp_fact',
16+
'gmp_sqrt',
17+
'gmp_sqrtrem',
18+
'gmp_root',
19+
'gmp_rootrem',
20+
'gmp_pow',
21+
'gmp_perfect_square',
22+
'gmp_perfect_power',
23+
'gmp_prob_prime',
24+
'gmp_sign',
25+
'gmp_random_seed',
26+
'gmp_popcount',
27+
'gmp_com',
28+
];
29+
$functions1_need_int_2 = [
30+
'gmp_testbit',
31+
'gmp_scan0',
32+
'gmp_scan1',
33+
'gmp_binomial',
34+
];
35+
$functions2 = [
36+
'gmp_add',
37+
'gmp_sub',
38+
'gmp_mul',
39+
'gmp_div',
40+
'gmp_div_q',
41+
'gmp_div_r',
42+
'gmp_div_qr',
43+
'gmp_divexact',
44+
'gmp_mod',
45+
'gmp_gcd',
46+
'gmp_gcdext',
47+
'gmp_lcm',
48+
'gmp_invert',
49+
'gmp_jacobi',
50+
'gmp_legendre',
51+
'gmp_kronecker',
52+
'gmp_cmp',
53+
'gmp_random_range',
54+
'gmp_and',
55+
'gmp_or',
56+
'gmp_xor',
57+
'gmp_hamdist',
58+
'gmp_nextprime',
59+
];
60+
$functions3 = [
61+
'gmp_powm',
62+
];
63+
64+
echo 'Explicit base with gmp_init:', \PHP_EOL;
65+
echo 'Hexadecimal', \PHP_EOL;
66+
try {
67+
var_dump(gmp_init('0X', 16));
68+
} catch (\TypeError $e) {
69+
echo $e->getMessage(), \PHP_EOL;
70+
}
71+
try {
72+
var_dump(gmp_init('0x', 16));
73+
} catch (\TypeError $e) {
74+
echo $e->getMessage(), \PHP_EOL;
75+
}
76+
77+
echo 'Binary', \PHP_EOL;
78+
try {
79+
var_dump(gmp_init('0B', 2));
80+
} catch (\TypeError $e) {
81+
echo $e->getMessage(), \PHP_EOL;
82+
}
83+
try {
84+
var_dump(gmp_init('0b', 2));
85+
} catch (\TypeError $e) {
86+
echo $e->getMessage(), \PHP_EOL;
87+
}
88+
89+
echo 'Fuzzing gmp functions:', \PHP_EOL;
90+
foreach ($functions1 as $function) {
91+
try {
92+
$function('0B');
93+
echo $function, ' failed with 0B', \PHP_EOL;
94+
} catch (\TypeError) { }
95+
try {
96+
$function('0b');
97+
echo $function, ' failed with 0b', \PHP_EOL;
98+
} catch (\TypeError) { }
99+
try {
100+
$function('0X');
101+
echo $function, ' failed with 0X', \PHP_EOL;
102+
} catch (\TypeError) { }
103+
try {
104+
$function('0x');
105+
echo $function, ' failed with 0x', \PHP_EOL;
106+
} catch (\TypeError) { }
107+
}
108+
foreach ($functions1_need_int_2 as $function) {
109+
try {
110+
$function('0B', 1);
111+
echo $function, ' failed with 0B', \PHP_EOL;
112+
} catch (\TypeError) { }
113+
try {
114+
$function('0b', 1);
115+
echo $function, ' failed with 0b', \PHP_EOL;
116+
} catch (\TypeError) { }
117+
try {
118+
$function('0X', 1);
119+
echo $function, ' failed with 0X', \PHP_EOL;
120+
} catch (\TypeError) { }
121+
try {
122+
$function('0x', 1);
123+
echo $function, ' failed with 0x', \PHP_EOL;
124+
} catch (\TypeError) { }
125+
}
126+
foreach ($functions2 as $function) {
127+
try {
128+
$function('0B', 1);
129+
echo $function, ' arg 1 failed with 0B', \PHP_EOL;
130+
} catch (\TypeError) { }
131+
try {
132+
$function('0b', 1);
133+
echo $function, ' arg 1 failed with 0b', \PHP_EOL;
134+
} catch (\TypeError) { }
135+
try {
136+
$function('0X', 1);
137+
echo $function, ' arg 1 failed with 0X', \PHP_EOL;
138+
} catch (\TypeError) { }
139+
try {
140+
$function('0x', 1);
141+
echo $function, ' arg 1 failed with 0x', \PHP_EOL;
142+
} catch (\TypeError) { }
143+
try {
144+
$function(1, '0B');
145+
echo $function, ' arg 2 failed with 0B', \PHP_EOL;
146+
} catch (\TypeError) { }
147+
try {
148+
$function(1, '0b');
149+
echo $function, ' arg 2 failed with 0b', \PHP_EOL;
150+
} catch (\TypeError) { }
151+
try {
152+
$function(1, '0X');
153+
echo $function, ' arg 2 failed with 0X', \PHP_EOL;
154+
} catch (\TypeError) { }
155+
try {
156+
$function(1, '0x');
157+
echo $function, ' arg 2 failed with 0x', \PHP_EOL;
158+
} catch (\TypeError) { }
159+
}
160+
foreach ($functions3 as $function) {
161+
try {
162+
$function('0B', 1, 1);
163+
echo $function, ' arg 1 failed with 0B', \PHP_EOL;
164+
} catch (\TypeError) { }
165+
try {
166+
$function('0b', 1, 1);
167+
echo $function, ' arg 1 failed with 0b', \PHP_EOL;
168+
} catch (\TypeError) { }
169+
try {
170+
$function('0X', 1, 1);
171+
echo $function, ' arg 1 failed with 0X', \PHP_EOL;
172+
} catch (\TypeError) { }
173+
try {
174+
$function('0x', 1, 1);
175+
echo $function, ' arg 1 failed with 0x', \PHP_EOL;
176+
} catch (\TypeError) { }
177+
try {
178+
$function(1, '0B', 1);
179+
echo $function, ' arg 2 failed with 0B', \PHP_EOL;
180+
} catch (\TypeError) { }
181+
try {
182+
$function(1, '0b', 1);
183+
echo $function, ' arg 2 failed with 0b', \PHP_EOL;
184+
} catch (\TypeError) { }
185+
try {
186+
$function(1, '0X', 1);
187+
echo $function, ' arg 2 failed with 0X', \PHP_EOL;
188+
} catch (\TypeError) { }
189+
try {
190+
$function(1, '0x', 1);
191+
echo $function, ' arg 2 failed with 0x', \PHP_EOL;
192+
} catch (\TypeError) { }
193+
try {
194+
$function(1, 1, '0B');
195+
echo $function, ' arg 3 failed with 0B', \PHP_EOL;
196+
} catch (\TypeError) { }
197+
try {
198+
$function(1, 1, '0b');
199+
echo $function, ' arg 3 failed with 0b', \PHP_EOL;
200+
} catch (\TypeError) { }
201+
try {
202+
$function(1, 1, '0X');
203+
echo $function, ' arg 3 failed with 0X', \PHP_EOL;
204+
} catch (\TypeError) { }
205+
try {
206+
$function(1, 1, '0x');
207+
echo $function, ' arg 3 failed with 0x', \PHP_EOL;
208+
} catch (\TypeError) { }
209+
}
210+
211+
echo "Done\n";
212+
?>
213+
--EXPECT--
214+
Explicit base with gmp_init:
215+
Hexadecimal
216+
gmp_init(): Argument #1 ($num) is not an integer string
217+
gmp_init(): Argument #1 ($num) is not an integer string
218+
Binary
219+
gmp_init(): Argument #1 ($num) is not an integer string
220+
gmp_init(): Argument #1 ($num) is not an integer string
221+
Fuzzing gmp functions:
222+
Done

0 commit comments

Comments
 (0)