Improve handling of multi-line quoted values in the fallback INI parser - #30
Open
sgiehl wants to merge 3 commits into
Open
Improve handling of multi-line quoted values in the fallback INI parser#30sgiehl wants to merge 3 commits into
sgiehl wants to merge 3 commits into
Conversation
sgiehl
marked this pull request as ready for review
August 13, 2026 16:50
sgiehl
marked this pull request as draft
August 13, 2026 20:09
sgiehl
marked this pull request as ready for review
August 14, 2026 09:04
sgiehl
marked this pull request as draft
August 14, 2026 09:19
Backslashes are escaped in addition to quotes, so a value ending in a backslash cannot leave the closing quote preceded by a lone backslash, and all quotes directly before a line break are removed so none of them can end up as the last character of a line. Option names are encoded as well, keeping the characters that are valid in a name such as "." or ":". An option name that would end up empty is rejected instead of producing a file that cannot be read.
The fallback implementation read the file strictly line by line, so the lines after the opening quote of a value were taken for sections or keys of their own instead of being part of the value, unlike the native parser. Quoted values are now read up to the matching closing quote, scanning each line only once. A quote at the very end of a line ends a value that would otherwise be unterminated, so values written by an earlier version of IniWriter are still read as before. The value is taken from the unmodified line so tabs and inner whitespace are kept, "\r\n" counts as one line break, and anything after the closing quote is ignored. Lines the native parser does not accept either are now rejected: an unterminated quoted value, a quote or an assignment after a section name, and a double quote that opens a string which is never closed. readComments() skips such values as well, so it no longer reports sections and keys that readString() does not return, and values are only decoded with raw values of the same structure.
sgiehl
force-pushed
the
improve-multiline-quoted-value-handling
branch
from
August 14, 2026 09:24
a83ceb3 to
a76be7e
Compare
Runs against both the native and the fallback implementation, and pins the cases the fallback implementation cannot read the same way.
sgiehl
force-pushed
the
improve-multiline-quoted-value-handling
branch
from
August 14, 2026 09:31
a76be7e to
4690f41
Compare
sgiehl
marked this pull request as ready for review
August 14, 2026 09:50
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The fallback INI parser in
IniReader(used when PHP's nativeparse_ini_string()is not available) parsed the input strictly line by line. It therefore did not recognise quoted values that span multiple lines: the lines after the opening quote were treated as separate sections or keys, while the native parser reads them as part of the value.This aligns the fallback implementation with the native parser and makes values round-trip reliably through
IniWriter/IniReader.Changes
IniReader"and'— up to the matching closing quote, so both implementations return the same result. The value is scanned once while it is read, not from its beginning again for every line.IniWriterare still read as before.\r\ncounts as one line break so it is preserved inside a value.readComments()skips multi-line values as well, so it no longer reports sections and keys thatreadString()does not return.IniWriterIniReaderreverses this when reading..or:.Tests
Added tests that run against both the native and the fallback implementation, covering multi-line double- and single-quoted values, values containing newlines, tabs,
\r\n, backslashes (e.g. Windows paths) and INI-significant characters, option names, content after a section name or a closing quote, and unterminated quotes.vendor/bin/phpunit: 140 tests, 226 assertions, all passing (verified on PHP 8.3; CI covers 7.2-8.4).Reading Matomo's bundled
global.ini.phpand an instanceconfig.ini.phpproduces byte-identical results before and after this change, on both implementations, andreadComments()returns the same descriptions as before.