[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pecl-cvs
Subject:    [PECL-CVS] [pecl-database-dbase] master: Fix GH-1: dbase_add_record() converts passed floats and lea
From:       "Christoph M. Becker" <noreply () php ! net>
Date:       2021-10-29 15:04:40
Message-ID: 8oYtR2y0pxpBPjrriIVbW595xUtiOBiLmPjDamxBK40 () main ! php ! net
[Download RAW message or body]

Author: Christoph M. Becker (cmb69)
Date: 2021-10-29T17:05:03+02:00

Commit: https://github.com/php/pecl-database-dbase/commit/f4091907b77917e79768b0cee4eca9373b0ef013
Raw diff: https://github.com/php/pecl-database-dbase/commit/f4091907b77917e79768b0cee4eca9373b0ef013.diff

Fix GH-1: dbase_add_record() converts passed floats and leaks memory

We must not modify any elements of the passed record array.  Since
there is actually no need to modify the zval, we work with zend_strings
in the first place, what even simplifies the code a bit.

Changed paths:
  A  tests/gh-1.phpt
  M  dbase.c
  M  package.xml


Diff:

diff --git a/dbase.c b/dbase.c
index 1d1b95d..c347701 100644
--- a/dbase.c
+++ b/dbase.c
@@ -265,7 +265,7 @@ static void php_dbase_put_record(INTERNAL_FUNCTION_PARAMETERS, int replace)
 
 	dbf = dbht->db_fields;
 	for (i = 0, cur_f = dbf; cur_f < &dbf[num_fields]; i++, cur_f++) {
-		zval tmp_field;
+		zend_string *field_val;
 
 		if ((field = zend_hash_index_find(fields, i)) == NULL) {
 			php_error_docref(NULL, E_WARNING, "expected plain indexed array");
@@ -277,22 +277,16 @@ static void php_dbase_put_record(INTERNAL_FUNCTION_PARAMETERS, int replace)
 			nullable_flags[cur_f->db_fnullable / 8] |= (1 << (cur_f->db_fnullable % 8));
 		}
 
-		/* force cast to string as if in C locale */
 		if (Z_TYPE_P(field) == IS_DOUBLE && (cur_f->db_type == 'N' || cur_f->db_type == 'F')) {
-			zend_string *formatted;
-
-			formatted = _php_math_number_format_ex(Z_DVAL_P(field), cur_f->db_fdc, ".", 1, "", 0);
-			ZVAL_STRING(field, ZSTR_VAL(formatted));
-			zend_string_free(formatted);
-		}
-
-		ZVAL_COPY_VALUE(&tmp_field, field);
-		zval_copy_ctor(&tmp_field);
-		convert_to_string(&tmp_field);
-		if (EG(exception)) {
-			zval_dtor(&tmp_field);
-			efree(cp);
-			RETURN_FALSE;
+			/* convert to string as if in C locale */
+			field_val = _php_math_number_format_ex(Z_DVAL_P(field), cur_f->db_fdc, ".", 1, "", 0);
+		} else {
+			field_val = zval_get_string(field);
+			if (EG(exception)) {
+				zend_string_release(field_val);
+				efree(cp);
+				RETURN_FALSE;
+			}
 		}
 
 		switch (cur_f->db_type) {
@@ -300,16 +294,16 @@ static void php_dbase_put_record(INTERNAL_FUNCTION_PARAMETERS, int replace)
 				{
 					int jdn, msecs;
 
-					db_get_timestamp(Z_STRVAL(tmp_field), &jdn, &msecs);
+					db_get_timestamp(ZSTR_VAL(field_val), &jdn, &msecs);
 					put_long(t_cp, jdn);
 					put_long(t_cp + 4, msecs);
 				}
 				break;
 			default:
-				snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, Z_STRVAL(tmp_field));
+				snprintf(t_cp, cur_f->db_flen+1, cur_f->db_format, ZSTR_VAL(field_val));
 		}
 
-		zval_dtor(&tmp_field);
+		zend_string_release(field_val);
 		t_cp += cur_f->db_flen;
 	}
 
diff --git a/package.xml b/package.xml
index 9a97a28..5e23a1b 100644
--- a/package.xml
+++ b/package.xml
@@ -38,9 +38,9 @@ are kept until you call dbase_pack().
   <active>yes</active>
  </lead>
 
- <date>2021-06-13</date>
+ <date>2021-10-29</date>
  <version>
-  <release>7.1.0</release>
+  <release>7.1.1-dev</release>
   <api>7.1</api>
  </version>
  <stability>
@@ -50,16 +50,9 @@ are kept until you call dbase_pack().
  <license uri="http://www.php.net/license">PHP</license>
  <notes>
 <![CDATA[
-New features
-
-  - Full fledged arginfo is available under PHP 8 (Remi Collet)
-  - Calling dbase functions with wrong parameter types/values throws TypeExceptions and
-    ValueExceptions, respectively, instead of raising warnings under PHP 8 (Remi Collet)
-
 Bug Fixes
 
-  - Fixed #80156 (Incomplete records may be written)
-  - Fixed #80488 (ReflectionParameter->getDefaultValue() throws for dbase_create())
+  - Fixed GH-1 (dbase_add_record() converts passed floats and leaks memory)
 ]]>
  </notes>
 
@@ -169,6 +162,7 @@ Bug Fixes
     <file name="dbase_replace_record_variation1.phpt" role="test" />
     <file name="dbase_replace_record_variation2.phpt" role="test" />
     <file name="dbase_replace_record_variation3.phpt" role="test" />
+    <file name="gh-1.phpt" role="test" />
     <file name="example.dbf" role="test" />
     <file name="nullable.phpt" role="test" />
     <file name="type_datetime.phpt" role="test" />
@@ -191,6 +185,32 @@ Bug Fixes
  <providesextension>dbase</providesextension>
  <extsrcrelease />
    <changelog>
+    <release>
+     <date>2021-06-13</date>
+     <version>
+      <release>7.1.0</release>
+      <api>7.1</api>
+     </version>
+     <stability>
+      <release>stable</release>
+      <api>stable</api>
+     </stability>
+     <license uri="http://www.php.net/license">PHP</license>
+     <notes>
+<![CDATA[
+New features
+
+  - Full fledged arginfo is available under PHP 8 (Remi Collet)
+  - Calling dbase functions with wrong parameter types/values throws TypeExceptions and
+    ValueExceptions, respectively, instead of raising warnings under PHP 8 (Remi Collet)
+
+Bug Fixes
+
+  - Fixed #80156 (Incomplete records may be written)
+  - Fixed #80488 (ReflectionParameter->getDefaultValue() throws for dbase_create())
+]]>
+     </notes>
+    </release>
     <release>
      <date>2020-10-04</date>
      <version>
diff --git a/tests/gh-1.phpt b/tests/gh-1.phpt
new file mode 100644
index 0000000..914cd54
--- /dev/null
+++ b/tests/gh-1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+GH-1 (dbase_add_record() converts passed floats and leaks memory)
+--SKIPIF--
+<?php
+if (!extension_loaded("dbase")) die("skip dbase extension not available");
+?>
+--FILE--
+<?php
+$filename = __DIR__ . "/gh-1.dbf";
+$db = dbase_create($filename, array(array('num', 'n', 10, 1)));
+
+$record = array(1234.5);
+dbase_add_record($db, $record);
+var_dump($record);
+?>
+--EXPECT--
+array(1) {
+  [0]=>
+  float(1234.5)
+}
+--CLEAN--
+<?php
+unlink(__DIR__ . "/gh-1.dbf");
+?>

-- 
PECL CVS Mailing List 
To unsubscribe, visit: http://www.php.net/unsub.php

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic