Library name and version
- Kros.KORM 7.4.0 (still present on
main)
Description
ParamEnumerator extracts parameter names from raw SQL (Query<T>().Sql(...), ExecuteNonQueryAsync(...)) after normalizing line endings with sql.Replace(Environment.NewLine, " "), and treats only space, , and ) as token delimiters. Parameter parsing therefore silently depends on the SQL string's line endings matching the host platform's Environment.NewLine. SQL text with bare LF line endings (e.g. compiled from sources checked out with eol=lf in .gitattributes) is parsed incorrectly on Windows hosts.
Steps To Reproduce
- Build an app from sources with LF line endings (
*.cs text eol=lf in .gitattributes), so a verbatim SQL string literal contains bare \n.
- Run it on Windows (
Environment.NewLine == "\r\n").
- Execute a query whose parameter is followed by a line break and a TAB-indented (or unindented) continuation line:
database.Query<Row>().Sql("SELECT * FROM T WHERE Id = @1\n\tAND Date < @2", id, date).ToArray();
- See error.
Expected behavior
Parameters @1 and @2 are extracted and bound regardless of the SQL string's line endings; the query executes.
Actual behavior
The extracted parameter name is "@1\n\tAND" — the token runs to the first space, and the final Trim() cannot remove the embedded \n\t. The command's parameter collection does not contain @1 and SQL Server fails with:
Must declare the scalar variable "@1".
Related edge cases:
- A parameter followed directly by a TAB (
... = @1\tAND ...) fails the same way on every platform.
- The reverse mismatch (CRLF SQL on a Linux host) survives only by accident: the leftover
\r ends up at the end of the token and is removed by Trim().
- The bug is easy to miss in tests: line endings of verbatim string literals follow the checkout, which follows the platform, so they normally match
Environment.NewLine. It typically surfaces only when .gitattributes forces line endings (our production case after switching the repository to eol=lf).
Library name and version
main)Description
ParamEnumeratorextracts parameter names from raw SQL (Query<T>().Sql(...),ExecuteNonQueryAsync(...)) after normalizing line endings withsql.Replace(Environment.NewLine, " "), and treats only space,,and)as token delimiters. Parameter parsing therefore silently depends on the SQL string's line endings matching the host platform'sEnvironment.NewLine. SQL text with bare LF line endings (e.g. compiled from sources checked out witheol=lfin.gitattributes) is parsed incorrectly on Windows hosts.Steps To Reproduce
*.cs text eol=lfin.gitattributes), so a verbatim SQL string literal contains bare\n.Environment.NewLine == "\r\n").database.Query<Row>().Sql("SELECT * FROM T WHERE Id = @1\n\tAND Date < @2", id, date).ToArray();Expected behavior
Parameters
@1and@2are extracted and bound regardless of the SQL string's line endings; the query executes.Actual behavior
The extracted parameter name is
"@1\n\tAND"— the token runs to the first space, and the finalTrim()cannot remove the embedded\n\t. The command's parameter collection does not contain@1and SQL Server fails with:Related edge cases:
... = @1\tAND ...) fails the same way on every platform.\rends up at the end of the token and is removed byTrim().Environment.NewLine. It typically surfaces only when.gitattributesforces line endings (our production case after switching the repository toeol=lf).