-
-
Save anonymous/21c94ad05a2ab960c7631ad9999a1044 to your computer and use it in GitHub Desktop.
Patch for 72093
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit d650063a0457aec56364e4005a636dc6c401f9cd | |
Author: Stanislav Malyshev <stas@php.net> | |
Date: Sun Apr 24 18:33:32 2016 -0700 | |
Fix bug #72093: bcpowmod accepts negative scale and corrupts _one_ definition | |
We can not modify result since it can be copy of _zero_ or _one_, etc. and | |
"copy" in bcmath is just bumping the refcount. | |
diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c | |
index 02177e4..dd69115 100644 | |
--- a/ext/bcmath/bcmath.c | |
+++ b/ext/bcmath/bcmath.c | |
@@ -201,6 +201,21 @@ static void php_str2num(bc_num *num, char *str TSRMLS_DC) | |
} | |
/* }}} */ | |
+/* {{{ split_bc_num | |
+ Convert to bc_num detecting scale */ | |
+static bc_num split_bc_num(bc_num num) { | |
+ bc_num newnum; | |
+ if (num->n_refs >= 1) { | |
+ return num; | |
+ } | |
+ newnum = _bc_new_num_ex(0, 0, 0); | |
+ *newnum = *num; | |
+ newnum->n_refs = 1; | |
+ num->n_refs--; | |
+ return newnum; | |
+} | |
+/* }}} */ | |
+ | |
/* {{{ proto string bcadd(string left_operand, string right_operand [, int scale]) | |
Returns the sum of two arbitrary precision numbers */ | |
PHP_FUNCTION(bcadd) | |
@@ -214,7 +229,7 @@ PHP_FUNCTION(bcadd) | |
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
if (argc == 3) { | |
scale = (int) ((int)scale_param < 0) ? 0 : scale_param; | |
} | |
@@ -225,11 +240,12 @@ PHP_FUNCTION(bcadd) | |
php_str2num(&first, left TSRMLS_CC); | |
php_str2num(&second, right TSRMLS_CC); | |
bc_add (first, second, &result, scale); | |
- | |
+ | |
if (result->n_scale > scale) { | |
+ result = split_bc_num(result); | |
result->n_scale = scale; | |
} | |
- | |
+ | |
Z_STRVAL_P(return_value) = bc_num2str(result); | |
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); | |
Z_TYPE_P(return_value) = IS_STRING; | |
@@ -253,7 +269,7 @@ PHP_FUNCTION(bcsub) | |
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
if (argc == 3) { | |
scale = (int) ((int)scale_param < 0) ? 0 : scale_param; | |
} | |
@@ -266,6 +282,7 @@ PHP_FUNCTION(bcsub) | |
bc_sub (first, second, &result, scale); | |
if (result->n_scale > scale) { | |
+ result = split_bc_num(result); | |
result->n_scale = scale; | |
} | |
@@ -292,11 +309,11 @@ PHP_FUNCTION(bcmul) | |
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
if (argc == 3) { | |
scale = (int) ((int)scale_param < 0) ? 0 : scale_param; | |
} | |
- | |
+ | |
bc_init_num(&first TSRMLS_CC); | |
bc_init_num(&second TSRMLS_CC); | |
bc_init_num(&result TSRMLS_CC); | |
@@ -305,6 +322,7 @@ PHP_FUNCTION(bcmul) | |
bc_multiply (first, second, &result, scale TSRMLS_CC); | |
if (result->n_scale > scale) { | |
+ result = split_bc_num(result); | |
result->n_scale = scale; | |
} | |
@@ -331,11 +349,11 @@ PHP_FUNCTION(bcdiv) | |
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
if (argc == 3) { | |
scale = (int) ((int)scale_param < 0) ? 0 : scale_param; | |
} | |
- | |
+ | |
bc_init_num(&first TSRMLS_CC); | |
bc_init_num(&second TSRMLS_CC); | |
bc_init_num(&result TSRMLS_CC); | |
@@ -345,6 +363,7 @@ PHP_FUNCTION(bcdiv) | |
switch (bc_divide(first, second, &result, scale TSRMLS_CC)) { | |
case 0: /* OK */ | |
if (result->n_scale > scale) { | |
+ result = split_bc_num(result); | |
result->n_scale = scale; | |
} | |
Z_STRVAL_P(return_value) = bc_num2str(result); | |
@@ -374,13 +393,13 @@ PHP_FUNCTION(bcmod) | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &left, &left_len, &right, &right_len) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
bc_init_num(&first TSRMLS_CC); | |
bc_init_num(&second TSRMLS_CC); | |
bc_init_num(&result TSRMLS_CC); | |
bc_str2num(&first, left, 0 TSRMLS_CC); | |
bc_str2num(&second, right, 0 TSRMLS_CC); | |
- | |
+ | |
switch (bc_modulo(first, second, &result, 0 TSRMLS_CC)) { | |
case 0: | |
Z_STRVAL_P(return_value) = bc_num2str(result); | |
@@ -391,7 +410,7 @@ PHP_FUNCTION(bcmod) | |
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero"); | |
break; | |
} | |
- | |
+ | |
bc_free_num(&first); | |
bc_free_num(&second); | |
bc_free_num(&result); | |
@@ -424,8 +443,9 @@ PHP_FUNCTION(bcpowmod) | |
scale_int = (int) ((int)scale < 0) ? 0 : scale; | |
if (bc_raisemod(first, second, mod, &result, scale_int TSRMLS_CC) != -1) { | |
- if (result->n_scale > scale) { | |
- result->n_scale = scale; | |
+ if (result->n_scale > scale_int) { | |
+ result = split_bc_num(result); | |
+ result->n_scale = scale_int; | |
} | |
Z_STRVAL_P(return_value) = bc_num2str(result); | |
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); | |
@@ -433,7 +453,7 @@ PHP_FUNCTION(bcpowmod) | |
} else { | |
RETVAL_FALSE; | |
} | |
- | |
+ | |
bc_free_num(&first); | |
bc_free_num(&second); | |
bc_free_num(&mod); | |
@@ -455,7 +475,7 @@ PHP_FUNCTION(bcpow) | |
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
if (argc == 3) { | |
scale = (int) ((int)scale_param < 0) ? 0 : scale_param; | |
} | |
@@ -468,6 +488,7 @@ PHP_FUNCTION(bcpow) | |
bc_raise (first, second, &result, scale TSRMLS_CC); | |
if (result->n_scale > scale) { | |
+ result = split_bc_num(result); | |
result->n_scale = scale; | |
} | |
@@ -494,16 +515,17 @@ PHP_FUNCTION(bcsqrt) | |
if (zend_parse_parameters(argc TSRMLS_CC, "s|l", &left, &left_len, &scale_param) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
if (argc == 2) { | |
scale = (int) ((int)scale_param < 0) ? 0 : scale_param; | |
} | |
bc_init_num(&result TSRMLS_CC); | |
php_str2num(&result, left TSRMLS_CC); | |
- | |
+ | |
if (bc_sqrt (&result, scale TSRMLS_CC) != 0) { | |
if (result->n_scale > scale) { | |
+ result = split_bc_num(result); | |
result->n_scale = scale; | |
} | |
Z_STRVAL_P(return_value) = bc_num2str(result); | |
@@ -531,7 +553,7 @@ PHP_FUNCTION(bccomp) | |
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) { | |
return; | |
} | |
- | |
+ | |
if (argc == 3) { | |
scale = (int) ((int)scale_param < 0) ? 0 : scale_param; | |
} | |
@@ -555,7 +577,7 @@ PHP_FUNCTION(bccomp) | |
PHP_FUNCTION(bcscale) | |
{ | |
long new_scale; | |
- | |
+ | |
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &new_scale) == FAILURE) { | |
return; | |
} | |
diff --git a/ext/bcmath/tests/bug72093.phpt b/ext/bcmath/tests/bug72093.phpt | |
new file mode 100644 | |
index 0000000..be664b8 | |
--- /dev/null | |
+++ b/ext/bcmath/tests/bug72093.phpt | |
@@ -0,0 +1,13 @@ | |
+--TEST-- | |
+Bug 72093: bcpowmod accepts negative scale and corrupts _one_ definition | |
+--SKIPIF-- | |
+<?php if(!extension_loaded("bcmath")) print "skip"; ?> | |
+--FILE-- | |
+<?php | |
+var_dump(bcpowmod(1, "A", 128, -200)); | |
+var_dump(bcpowmod(1, 1.2, 1, 1)); | |
+?> | |
+--EXPECTF-- | |
+string(1) "1" | |
+bc math warning: non-zero scale in exponent | |
+string(3) "0.0" | |
diff --git a/main/php_version.h b/main/php_version.h | |
index f87cc38..4ebff7f 100644 | |
--- a/main/php_version.h | |
+++ b/main/php_version.h | |
@@ -2,7 +2,7 @@ | |
/* edit configure.in to change version number */ | |
#define PHP_MAJOR_VERSION 5 | |
#define PHP_MINOR_VERSION 5 | |
-#define PHP_RELEASE_VERSION 35 | |
+#define PHP_RELEASE_VERSION 27 | |
#define PHP_EXTRA_VERSION "-dev" | |
-#define PHP_VERSION "5.5.35-dev" | |
-#define PHP_VERSION_ID 50535 | |
+#define PHP_VERSION "5.5.27-dev" | |
+#define PHP_VERSION_ID 50527 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment