Commit: 9b5cb0e8059b1e8bec096067491ed8d75f878938 Author: Adam Harvey <ahar...@php.net> Tue, 15 Jan 2013 15:17:45 +0800 Parents: e1410b5a70543856de3978603b41fbf2ca5d330c Branches: PHP-5.3 PHP-5.4 PHP-5.5 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=9b5cb0e8059b1e8bec096067491ed8d75f878938 Log: Update fputcsv() to escape all characters equally. At present, backslashes have special case handling within fputcsv(): when one is encountered within a field that's being escaped, escaping stops until the next instance of the enclosure character is hit. This can result in malformed CSV. Fixes bug #43225 (fputcsv incorrectly handles cells ending in \ followed by "). Bugs: https://bugs.php.net/43225 Changed paths: M NEWS M ext/standard/file.c M ext/standard/tests/file/fputcsv.phpt A ext/standard/tests/file/fputcsv_bug43225.phpt Diff: diff --git a/NEWS b/NEWS index e78af23..a7c2fa4 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ PHP NEWS - Core . Fixed bug #63943 (Bad warning text from strpos() on empty needle). (Laruence) + . Fixed bug #43225 (fputcsv incorrectly handles cells ending in \ followed + by "). (Adam) - cURL extension: . Fixed bug (segfault due to libcurl connection caching). (Pierrick) diff --git a/ext/standard/file.c b/ext/standard/file.c index 8b18155..fa85bf1 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1953,7 +1953,6 @@ PHP_FUNCTION(fputcsv) { char delimiter = ','; /* allow this to be set as parameter */ char enclosure = '"'; /* allow this to be set as parameter */ - const char escape_char = '\\'; php_stream *stream; int ret; zval *fp = NULL, *fields = NULL, **field_tmp = NULL, field; @@ -2008,24 +2007,19 @@ PHP_FUNCTION(fputcsv) /* enclose a field that contains a delimiter, an enclosure character, or a newline */ if (FPUTCSV_FLD_CHK(delimiter) || FPUTCSV_FLD_CHK(enclosure) || - FPUTCSV_FLD_CHK(escape_char) || FPUTCSV_FLD_CHK('\n') || FPUTCSV_FLD_CHK('\r') || FPUTCSV_FLD_CHK('\t') || + FPUTCSV_FLD_CHK('\\') || FPUTCSV_FLD_CHK(' ') ) { char *ch = Z_STRVAL(field); char *end = ch + Z_STRLEN(field); - int escaped = 0; smart_str_appendc(&csvline, enclosure); while (ch < end) { - if (*ch == escape_char) { - escaped = 1; - } else if (!escaped && *ch == enclosure) { + if (*ch == enclosure) { smart_str_appendc(&csvline, enclosure); - } else { - escaped = 0; } smart_str_appendc(&csvline, *ch); ch++; diff --git a/ext/standard/tests/file/fputcsv.phpt b/ext/standard/tests/file/fputcsv.phpt index 63c4150..d71f777 100644 --- a/ext/standard/tests/file/fputcsv.phpt +++ b/ext/standard/tests/file/fputcsv.phpt @@ -44,7 +44,7 @@ echo '$list = ';var_export($res);echo ";\n"; $fp = fopen($file, "r"); $res = array(); -while($l=fgetcsv($fp)) +while($l=fgetcsv($fp, 0, ',', '"', '"')) { $res[] = join(',',$l); } @@ -75,10 +75,10 @@ $list = array ( 13 => 'aaa,"""bbb """', 14 => '"aaa""aaa""","""bbb""bbb"', 15 => '"aaa""aaa""""""",bbb', - 16 => 'aaa,"""\\"bbb",ccc', - 17 => '"aaa""\\"a""","""bbb"""', - 18 => '"""\\"""","""aaa"""', - 19 => '"""\\"""""",aaa', + 16 => 'aaa,"""\\""bbb",ccc', + 17 => '"aaa""\\""a""","""bbb"""', + 18 => '"""\\""""","""aaa"""', + 19 => '"""\\""""""",aaa', ); $list = array ( 0 => 'aaa,bbb', diff --git a/ext/standard/tests/file/fputcsv_bug43225.phpt b/ext/standard/tests/file/fputcsv_bug43225.phpt new file mode 100644 index 0000000..1de3b5f --- /dev/null +++ b/ext/standard/tests/file/fputcsv_bug43225.phpt @@ -0,0 +1,20 @@ +--TEST-- +fputcsv(): bug #43225 (fputcsv incorrectly handles cells ending in \ followed by ") +--FILE-- +<?php + +$row = array( + 'a\\"', + 'bbb', +); + +$file = dirname(__FILE__) . 'fgetcsv_bug43225.csv'; +$fp = fopen($file, 'w'); +fputcsv($fp, $row); +fclose($fp); +readfile($file); +unlink($file); + +?> +--EXPECT-- +"a\""",bbb -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php