Support CSV files with data wrapping a lot of lines

If there is "line" splited on lot of lines we can reach limit of recursion
nesting. It's better to use while instead of recursion.

Closes #1468
This commit is contained in:
drewblin 2020-05-12 11:17:07 +03:00 committed by Adrien Crivelli
parent c4931de1f9
commit 3090c1e73f
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
2 changed files with 20 additions and 21 deletions

View File

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Added ### Added
- Support writing to streams in all writers [#1292](https://github.com/PHPOffice/PhpSpreadsheet/issues/1292) - Support writing to streams in all writers [#1292](https://github.com/PHPOffice/PhpSpreadsheet/issues/1292)
- Support CSV files with data wrapping a lot of lines [#1468](https://github.com/PHPOffice/PhpSpreadsheet/pull/1468)
### Fixed ### Fixed

View File

@ -236,33 +236,31 @@ class Csv extends BaseReader
/** /**
* Get the next full line from the file. * Get the next full line from the file.
* *
* @param string $line * @return false|string
*
* @return bool|string
*/ */
private function getNextLine($line = '') private function getNextLine()
{ {
// Get the next line in the file $line = '';
$newLine = fgets($this->fileHandle); $enclosure = '(?<!' . preg_quote($this->escapeCharacter, '/') . ')' . preg_quote($this->enclosure, '/');
// Return false if there is no next line do {
if ($newLine === false) { // Get the next line in the file
return false; $newLine = fgets($this->fileHandle);
}
// Add the new line to the line passed in // Return false if there is no next line
$line = $line . $newLine; if ($newLine === false) {
return false;
}
// Drop everything that is enclosed to avoid counting false positives in enclosures // Add the new line to the line passed in
$enclosure = '(?<!' . preg_quote($this->escapeCharacter, '/') . ')' $line = $line . $newLine;
. preg_quote($this->enclosure, '/');
$line = preg_replace('/(' . $enclosure . '.*' . $enclosure . ')/Us', '', $line);
// See if we have any enclosures left in the line // Drop everything that is enclosed to avoid counting false positives in enclosures
// if we still have an enclosure then we need to read the next line as well $line = preg_replace('/(' . $enclosure . '.*' . $enclosure . ')/Us', '', $line);
if (preg_match('/(' . $enclosure . ')/', $line) > 0) {
$line = $this->getNextLine($line); // See if we have any enclosures left in the line
} // if we still have an enclosure then we need to read the next line as well
} while (preg_match('/(' . $enclosure . ')/', $line) > 0);
return $line; return $line;
} }