Merge pull request #19678 from woocommerce/fix/19514

Handle escape characters for fputcsv
This commit is contained in:
Claudiu Lodromanean 2018-04-13 12:01:32 -07:00 committed by GitHub
commit 1d6ee4736b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 4 deletions

View File

@ -245,7 +245,7 @@ abstract class WC_CSV_Exporter {
$export_row[] = $this->format_data( $column_name );
}
fputcsv( $buffer, $export_row ); // @codingStandardsIgnoreLine
$this->fputcsv( $buffer, $export_row );
return ob_get_clean();
}
@ -299,7 +299,8 @@ abstract class WC_CSV_Exporter {
}
}
fputcsv( $buffer, $export_row ); // @codingStandardsIgnoreLine
$this->fputcsv( $buffer, $export_row );
++ $this->exported_row_count;
}
@ -456,4 +457,32 @@ abstract class WC_CSV_Exporter {
return implode( ', ', $values_to_implode );
}
/**
* Write to the CSV file, ensuring escaping works across versions of
* PHP.
*
* PHP 5.5.4 uses '\' as the default escape character. This is not RFC-4180 compliant.
* \0 disables the escape character.
*
* @see https://bugs.php.net/bug.php?id=43225
* @see https://bugs.php.net/bug.php?id=50686
* @see https://github.com/woocommerce/woocommerce/issues/19514
* @since 3.4.0
* @param resource $buffer Resource we are writing to.
* @param array $export_row Row to export.
*/
protected function fputcsv( $buffer, $export_row ) {
if ( version_compare( PHP_VERSION, '5.5.4', '<' ) ) {
ob_start();
$temp = fopen( 'php://output', 'w' ); // @codingStandardsIgnoreLine
fputcsv( $temp, $export_row, ",", '"' ); // @codingStandardsIgnoreLine
fclose( $temp ); // @codingStandardsIgnoreLine
$row = ob_get_clean();
$row = str_replace( '\\"', '\\""', $row );
fwrite( $buffer, $row ); // @codingStandardsIgnoreLine
} else {
fputcsv( $buffer, $export_row, ",", '"', "\0" ); // @codingStandardsIgnoreLine
}
}
}

View File

@ -46,6 +46,7 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
'delimiter' => ',', // CSV delimiter.
'prevent_timeouts' => true, // Check memory and time usage and abort if reaching limit.
'enclosure' => '"', // The character used to wrap text in the CSV.
'escape' => "\0", // PHP uses '\' as the default escape character. This is not RFC-4180 compliant. This disables the escape character.
);
$this->params = wp_parse_args( $params, $default_args );
@ -65,7 +66,7 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
$handle = fopen( $this->file, 'r' ); // @codingStandardsIgnoreLine.
if ( false !== $handle ) {
$this->raw_keys = fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'] );
$this->raw_keys = version_compare( PHP_VERSION, '5.3', '>=' ) ? fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'], $this->params['escape'] ) : fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'] ); // @codingStandardsIgnoreLine
// Remove BOM signature from the first item.
if ( isset( $this->raw_keys[0] ) ) {
@ -77,7 +78,7 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
}
while ( 1 ) {
$row = fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'] );
$row = version_compare( PHP_VERSION, '5.3', '>=' ) ? fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'], $this->params['escape'] ) : fgetcsv( $handle, 0, $this->params['delimiter'], $this->params['enclosure'] ); // @codingStandardsIgnoreLine
if ( false !== $row ) {
$this->raw_data[] = $row;