diff options
author | George Peter Banyard <girgias@php.net> | 2020-12-29 02:31:15 +0100 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-12-30 12:50:04 +0100 |
commit | abecaab09f8d39b5d2d6bc336e91595aae0d5a91 (patch) | |
tree | 7e8de63c3511a6787e82148e099c519d3965e1f1 | |
parent | da0ca53f399d0b9a8b2f3b73a9d3d7fa9f75667d (diff) | |
download | php-git-abecaab09f8d39b5d2d6bc336e91595aae0d5a91.tar.gz |
Fix #80560: Strings containing only a base prefix return 0 object
Closes GH-6549.
-rw-r--r-- | ext/gmp/gmp.c | 6 | ||||
-rw-r--r-- | ext/gmp/tests/bug80560.phpt | 222 |
2 files changed, 225 insertions, 3 deletions
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 33ed7fd93f..5bccdeca5c 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -174,7 +174,7 @@ if (IS_GMP(zval)) { \ gmp_create(return_value, &gmpnumber) static void gmp_strval(zval *result, mpz_t gmpnum, int base); -static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos); +static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos); static void gmp_cmp(zval *return_value, zval *a_arg, zval *b_arg); /* @@ -585,7 +585,7 @@ ZEND_MODULE_INFO_D(gmp) /* {{{ convert_to_gmp * Convert zval to be gmp number */ -static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos) +static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t arg_pos) { switch (Z_TYPE_P(val)) { case IS_LONG: @@ -596,7 +596,7 @@ static int convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, uint32_t a zend_bool skip_lead = 0; int ret; - if (Z_STRLEN_P(val) > 2 && numstr[0] == '0') { + if (Z_STRLEN_P(val) >= 2 && numstr[0] == '0') { if ((base == 0 || base == 16) && (numstr[1] == 'x' || numstr[1] == 'X')) { base = 16; skip_lead = 1; diff --git a/ext/gmp/tests/bug80560.phpt b/ext/gmp/tests/bug80560.phpt new file mode 100644 index 0000000000..f1bf7dc0d7 --- /dev/null +++ b/ext/gmp/tests/bug80560.phpt @@ -0,0 +1,222 @@ +--TEST-- +Bug #80560: Strings containing only a base prefix return 0 object +--SKIPIF-- +<?php if (!extension_loaded("gmp")) print "skip"; ?> +--FILE-- +<?php + +$functions1 = [ + 'gmp_init', + 'gmp_export', + 'gmp_intval', + 'gmp_strval', + 'gmp_neg', + 'gmp_abs', + 'gmp_fact', + 'gmp_sqrt', + 'gmp_sqrtrem', + 'gmp_root', + 'gmp_rootrem', + 'gmp_pow', + 'gmp_perfect_square', + 'gmp_perfect_power', + 'gmp_prob_prime', + 'gmp_sign', + 'gmp_random_seed', + 'gmp_popcount', + 'gmp_com', +]; +$functions1_need_int_2 = [ + 'gmp_testbit', + 'gmp_scan0', + 'gmp_scan1', + 'gmp_binomial', +]; +$functions2 = [ + 'gmp_add', + 'gmp_sub', + 'gmp_mul', + 'gmp_div', + 'gmp_div_q', + 'gmp_div_r', + 'gmp_div_qr', + 'gmp_divexact', + 'gmp_mod', + 'gmp_gcd', + 'gmp_gcdext', + 'gmp_lcm', + 'gmp_invert', + 'gmp_jacobi', + 'gmp_legendre', + 'gmp_kronecker', + 'gmp_cmp', + 'gmp_random_range', + 'gmp_and', + 'gmp_or', + 'gmp_xor', + 'gmp_hamdist', + 'gmp_nextprime', +]; +$functions3 = [ + 'gmp_powm', +]; + +echo 'Explicit base with gmp_init:', \PHP_EOL; +echo 'Hexadecimal', \PHP_EOL; +try { + var_dump(gmp_init('0X', 16)); +} catch (\TypeError $e) { + echo $e->getMessage(), \PHP_EOL; +} +try { + var_dump(gmp_init('0x', 16)); +} catch (\TypeError $e) { + echo $e->getMessage(), \PHP_EOL; +} + +echo 'Binary', \PHP_EOL; +try { + var_dump(gmp_init('0B', 2)); +} catch (\TypeError $e) { + echo $e->getMessage(), \PHP_EOL; +} +try { + var_dump(gmp_init('0b', 2)); +} catch (\TypeError $e) { + echo $e->getMessage(), \PHP_EOL; +} + +echo 'Fuzzing gmp functions:', \PHP_EOL; +foreach ($functions1 as $function) { + try { + $function('0B'); + echo $function, ' failed with 0B', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0b'); + echo $function, ' failed with 0b', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0X'); + echo $function, ' failed with 0X', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0x'); + echo $function, ' failed with 0x', \PHP_EOL; + } catch (\TypeError) { } +} +foreach ($functions1_need_int_2 as $function) { + try { + $function('0B', 1); + echo $function, ' failed with 0B', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0b', 1); + echo $function, ' failed with 0b', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0X', 1); + echo $function, ' failed with 0X', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0x', 1); + echo $function, ' failed with 0x', \PHP_EOL; + } catch (\TypeError) { } +} +foreach ($functions2 as $function) { + try { + $function('0B', 1); + echo $function, ' arg 1 failed with 0B', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0b', 1); + echo $function, ' arg 1 failed with 0b', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0X', 1); + echo $function, ' arg 1 failed with 0X', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0x', 1); + echo $function, ' arg 1 failed with 0x', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0B'); + echo $function, ' arg 2 failed with 0B', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0b'); + echo $function, ' arg 2 failed with 0b', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0X'); + echo $function, ' arg 2 failed with 0X', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0x'); + echo $function, ' arg 2 failed with 0x', \PHP_EOL; + } catch (\TypeError) { } +} +foreach ($functions3 as $function) { + try { + $function('0B', 1, 1); + echo $function, ' arg 1 failed with 0B', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0b', 1, 1); + echo $function, ' arg 1 failed with 0b', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0X', 1, 1); + echo $function, ' arg 1 failed with 0X', \PHP_EOL; + } catch (\TypeError) { } + try { + $function('0x', 1, 1); + echo $function, ' arg 1 failed with 0x', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0B', 1); + echo $function, ' arg 2 failed with 0B', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0b', 1); + echo $function, ' arg 2 failed with 0b', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0X', 1); + echo $function, ' arg 2 failed with 0X', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, '0x', 1); + echo $function, ' arg 2 failed with 0x', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, 1, '0B'); + echo $function, ' arg 3 failed with 0B', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, 1, '0b'); + echo $function, ' arg 3 failed with 0b', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, 1, '0X'); + echo $function, ' arg 3 failed with 0X', \PHP_EOL; + } catch (\TypeError) { } + try { + $function(1, 1, '0x'); + echo $function, ' arg 3 failed with 0x', \PHP_EOL; + } catch (\TypeError) { } +} + +echo "Done\n"; +?> +--EXPECT-- +Explicit base with gmp_init: +Hexadecimal +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string +Binary +gmp_init(): Argument #1 ($num) is not an integer string +gmp_init(): Argument #1 ($num) is not an integer string +Fuzzing gmp functions: +Done |