From cff692d97665209e6440f0913645babd4c0268d4 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Thu, 5 Jun 2014 01:07:31 +0100 Subject: [PATCH] Fix issue when CSV data does not end with a newline If CSV data didn't end with "\n", "\r", or "\r\n" the last line of the CSV would be ignored, as the parser wouldn't trigger end of row logic for the last row. This change forces the parser to process the end of the CSV data as it's own character (false), and deals with end of data just like it treats end of row. --- parsecsv.lib.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/parsecsv.lib.php b/parsecsv.lib.php index 37d9ed7..11d33c8 100644 --- a/parsecsv.lib.php +++ b/parsecsv.lib.php @@ -666,9 +666,16 @@ class parseCSV { $was_enclosed = false; $strlen = strlen($data); + // force the parser to process end of data as a character (false) when + // data does not end with a line feed or carriage return character. + $lch = $data{$strlen-1}; + if ($lch != "\n" && $lch != "\r") { + $strlen++; + } + // walk through each character for ( $i=0; $i < $strlen; $i++ ) { - $ch = $data{$i}; + $ch = ( isset($data{$i}) ) ? $data{$i} : false ; $nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ; $pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ; @@ -734,9 +741,9 @@ class parseCSV { $enclosed = false; } - // end of field/row + // end of field/row/csv } - elseif ( ($ch == $this->delimiter || $ch == "\n" || $ch == "\r") && !$enclosed ) { + elseif ( ($ch == $this->delimiter || $ch == "\n" || $ch == "\r" || $ch === false) && !$enclosed ) { $key = ( !empty($head[$col]) ) ? $head[$col] : $col ; $row[$key] = ( $was_enclosed ) ? $current : trim($current) ; $current = ''; @@ -744,7 +751,7 @@ class parseCSV { $col++; // end of row - if ( $ch == "\n" || $ch == "\r" ) { + if ( $ch == "\n" || $ch == "\r" || $ch === false ) { if ( $this->_validate_offset($row_count) && $this->_validate_row_conditions($row, $this->conditions) ) { if ( $this->heading && empty($head) ) { $head = $row;