summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-12-02 12:34:46 +0300
committerDmitry Stogov <dmitry@zend.com>2016-12-02 12:34:46 +0300
commit67d90a4870499f53faefc3314f50181d4150d7d0 (patch)
tree55b8880f0209ab442cb345f5cb9a6e1aef03f18b
parentfcaccbaa22784084d2cb59821b4e66c230702851 (diff)
downloadphp-git-67d90a4870499f53faefc3314f50181d4150d7d0.tar.gz
Fixed possible memory leak in &=, |=, ^=.
-rw-r--r--Zend/tests/self_and.phpt10
-rw-r--r--Zend/tests/self_or.phpt10
-rw-r--r--Zend/tests/self_xor.phpt12
-rw-r--r--Zend/zend_operators.c9
4 files changed, 40 insertions, 1 deletions
diff --git a/Zend/tests/self_and.phpt b/Zend/tests/self_and.phpt
index cdcde77992..e9ddc849eb 100644
--- a/Zend/tests/self_and.phpt
+++ b/Zend/tests/self_and.phpt
@@ -6,6 +6,8 @@ ANDing strings
$s = "123";
$s1 = "test";
$s2 = "45345some";
+$s3 = str_repeat("f", 1);
+$s4 = str_repeat("f", 2);
$s &= 22;
var_dump($s);
@@ -16,10 +18,18 @@ var_dump($s1);
$s2 &= 33;
var_dump($s2);
+$s3 &= " ";
+var_dump($s3);
+
+$s4 &= " ";
+var_dump($s4);
+
echo "Done\n";
?>
--EXPECTF--
int(18)
int(0)
int(33)
+string(1) " "
+string(2) " "
Done
diff --git a/Zend/tests/self_or.phpt b/Zend/tests/self_or.phpt
index ae667bff16..991aafa980 100644
--- a/Zend/tests/self_or.phpt
+++ b/Zend/tests/self_or.phpt
@@ -6,6 +6,8 @@ ORing strings
$s = "123";
$s1 = "test";
$s2 = "45345some";
+$s3 = str_repeat("f", 1);
+$s4 = str_repeat("f", 2);
$s |= 22;
var_dump($s);
@@ -16,10 +18,18 @@ var_dump($s1);
$s2 |= 33;
var_dump($s2);
+$s3 |= " ";
+var_dump($s3);
+
+$s4 |= " ";
+var_dump($s4);
+
echo "Done\n";
?>
--EXPECTF--
int(127)
int(11)
int(45345)
+string(1) "f"
+string(2) "ff"
Done
diff --git a/Zend/tests/self_xor.phpt b/Zend/tests/self_xor.phpt
index a7e43f539d..1577690a89 100644
--- a/Zend/tests/self_xor.phpt
+++ b/Zend/tests/self_xor.phpt
@@ -6,6 +6,8 @@ XORing strings
$s = "123";
$s1 = "test";
$s2 = "45345some";
+$s3 = str_repeat("f", 1);
+$s4 = str_repeat("f", 2);
$s ^= 22;
var_dump($s);
@@ -16,10 +18,18 @@ var_dump($s1);
$s2 ^= 33;
var_dump($s2);
+$s3 |= " ";
+var_dump($s3);
+
+$s4 |= " ";
+var_dump($s4);
+
echo "Done\n";
?>
--EXPECTF--
int(109)
int(11)
int(45312)
-Done
+string(1) "f"
+string(2) "ff"
+Done \ No newline at end of file
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index a02551b1bd..2d7fd96279 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1349,6 +1349,9 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
zend_uchar or = (zend_uchar) (*Z_STRVAL_P(op1) | *Z_STRVAL_P(op2));
+ if (result==op1) {
+ zend_string_release(Z_STR_P(result));
+ }
if (CG(one_char_string)[or]) {
ZVAL_INTERNED_STR(result, CG(one_char_string)[or]);
} else {
@@ -1416,6 +1419,9 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
zend_uchar and = (zend_uchar) (*Z_STRVAL_P(op1) & *Z_STRVAL_P(op2));
+ if (result==op1) {
+ zend_string_release(Z_STR_P(result));
+ }
if (CG(one_char_string)[and]) {
ZVAL_INTERNED_STR(result, CG(one_char_string)[and]);
} else {
@@ -1483,6 +1489,9 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
zend_uchar xor = (zend_uchar) (*Z_STRVAL_P(op1) ^ *Z_STRVAL_P(op2));
+ if (result==op1) {
+ zend_string_release(Z_STR_P(result));
+ }
if (CG(one_char_string)[xor]) {
ZVAL_INTERNED_STR(result, CG(one_char_string)[xor]);
} else {