]> granicus.if.org Git - php/commitdiff
- MFH: Fixed unexpected zval changes
authorFelipe Pena <felipe@php.net>
Fri, 12 Sep 2008 01:16:55 +0000 (01:16 +0000)
committerFelipe Pena <felipe@php.net>
Fri, 12 Sep 2008 01:16:55 +0000 (01:16 +0000)
ext/standard/file.c
ext/standard/tests/file/fputcsv_002.phpt [new file with mode: 0644]

index e16c432e7c085c426879c64a571425e5590051de..3cfc41e13466344624750a61b4b5da49d186b9f6 100644 (file)
@@ -1919,7 +1919,7 @@ quit_loop:
 }
 /* }}} */
 
-#define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL_PP(field), c, Z_STRLEN_PP(field))
+#define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL(field), c, Z_STRLEN(field))
 
 /* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])
    Format line as CSV and write to file pointer */
@@ -1930,7 +1930,7 @@ PHP_FUNCTION(fputcsv)
        const char escape_char = '\\';
        php_stream *stream;
        int ret;
-       zval *fp = NULL, *fields = NULL, **field = NULL;
+       zval *fp = NULL, *fields = NULL, **field_tmp = NULL, field;
        char *delimiter_str = NULL, *enclosure_str = NULL;
        int delimiter_str_len, enclosure_str_len;
        HashPosition pos;
@@ -1971,11 +1971,14 @@ PHP_FUNCTION(fputcsv)
 
        count = zend_hash_num_elements(Z_ARRVAL_P(fields));
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field, &pos) == SUCCESS) {
-               if (Z_TYPE_PP(field) != IS_STRING) {
-                       SEPARATE_ZVAL(field);
-                       convert_to_string(*field);
-               } 
+       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), (void **) &field_tmp, &pos) == SUCCESS) {
+               field = **field_tmp;
+
+               if (Z_TYPE_PP(field_tmp) != IS_STRING) {
+                       zval_copy_ctor(&field);
+                       convert_to_string(&field);
+               }
+
                /* enclose a field that contains a delimiter, an enclosure character, or a newline */
                if (FPUTCSV_FLD_CHK(delimiter) ||
                    FPUTCSV_FLD_CHK(enclosure) ||
@@ -1984,8 +1987,8 @@ PHP_FUNCTION(fputcsv)
                    FPUTCSV_FLD_CHK('\r') ||
                    FPUTCSV_FLD_CHK('\t') ||
                    FPUTCSV_FLD_CHK(' ')) {
-                       char *ch  = Z_STRVAL_PP(field);
-                       char *end = ch + Z_STRLEN_PP(field);
+                       char *ch  = Z_STRVAL(field);
+                       char *end = ch + Z_STRLEN(field);
                        int escaped = 0;
 
                        smart_str_appendc(&csvline, enclosure);
@@ -2002,13 +2005,17 @@ PHP_FUNCTION(fputcsv)
                        }
                        smart_str_appendc(&csvline, enclosure);
                } else {
-                       smart_str_appendl(&csvline, Z_STRVAL_PP(field), Z_STRLEN_PP(field));
+                       smart_str_appendl(&csvline, Z_STRVAL(field), Z_STRLEN(field));
                }
 
                if (++i != count) {
                        smart_str_appendl(&csvline, &delimiter, 1);
                }
                zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos);
+               
+               if (Z_TYPE_PP(field_tmp) != IS_STRING) {
+                       zval_dtor(&field);
+               }
        }
 
        smart_str_appendc(&csvline, '\n');
diff --git a/ext/standard/tests/file/fputcsv_002.phpt b/ext/standard/tests/file/fputcsv_002.phpt
new file mode 100644 (file)
index 0000000..544ad30
--- /dev/null
@@ -0,0 +1,43 @@
+--TEST--
+fputcsv(): Checking data after calling the function
+--FILE--
+<?php
+
+$file = dirname(__FILE__) .'/fgetcsv-test.csv';
+
+$data = array(1, 2, 'foo', 'haha', array(4, 5, 6), 1.3, null);
+
+$fp = fopen($file, 'w');
+
+fputcsv($fp, $data);
+
+var_dump($data);
+
+@unlink($file);
+
+?>
+--EXPECTF--
+Notice: Array to string conversion in %s on line %d
+array(7) {
+  [0]=>
+  int(1)
+  [1]=>
+  int(2)
+  [2]=>
+  string(3) "foo"
+  [3]=>
+  string(4) "haha"
+  [4]=>
+  array(3) {
+    [0]=>
+    int(4)
+    [1]=>
+    int(5)
+    [2]=>
+    int(6)
+  }
+  [5]=>
+  float(1.3)
+  [6]=>
+  NULL
+}