Skip to content

Quote logfmt values that contain tabs or other whitespace - #847

Open
spicysharkco wants to merge 3 commits into
hynek:mainfrom
spicysharkco:fix-logfmt-quote-whitespace
Open

spicysharkco wants to merge 3 commits into
hynek:mainfrom
spicysharkco:fix-logfmt-quote-whitespace

Conversation

@spicysharkco

@spicysharkco spicysharkco commented Oct 17, 2026 •

Copy link
Copy Markdown

Summary

LogfmtRenderer quotes a value only when it contains a space, = or ". A tab or carriage return is written bare, so {"k": "a\tb", "after": "x"} renders as k=a<TAB>b after=x, and go-logfmt reads that back as k=a, b="" and after=x.

Values containing any character from NUL to space are now quoted, the same range the renderer already rejects in keys. Newline is left out of that check because it is escaped as \n, as before.

Inside the quotes, control characters are escaped as \t, \r or \u00XX rather than written raw. go-logfmt rejects a quoted value that holds a raw control character together with an escape, so a stack trace line such as "Foo\n\tat_bar" would make it drop the rest of the record. go-logfmt's own encoder escapes tab and carriage return the same way. The new rows in test_escaping (a tab, a carriage return, a tab next to a newline, and \x01) fail without the change.

Pull Request Checklist

  • I acknowledge this project's AI policy.
  • This pull request is not from my main branch.
  • There's tests for all new and changed code.
  • New APIs are added to our typing tests in api.py. (n/a, no new APIs)
  • Updated documentation for changed code. (n/a, no documented behavior changed)
    • New functions/classes have to be added to docs/api.rst by hand. (n/a)
    • Changed/added classes/methods/functions have appropriate versionadded, versionchanged, or deprecated directives. (n/a)
      • The next version is the second number in the current release + 1. The first number represents the current year. So if the current version on PyPI is 26.1.0, the next version is gonna be 26.2.0. If the next version is the first in the new year, it'll be 27.1.0.
  • Documentation in .rst and .md files is written using semantic newlines.
  • Changes (and possible deprecations) are documented in the changelog.

LogfmtRenderer only quoted values containing a space, "=" or a double
quote, so a tab or carriage return split the value when the line was
parsed back. Quote any value with a character up to a space, except
newline, which stays escaped.
@codspeed

codspeed Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 1 benchmark spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

✅ 11 untouched benchmarks


Comparing spicysharkco:fix-logfmt-quote-whitespace (0213389) with main (19c4f21)

Open in CodSpeed

go-logfmt rejects a quoted value that holds a raw control character
next to an escape, so a value such as "Foo\n\tat_bar" made the parser
drop the rest of the record. Write tab, carriage return and the other
characters below space as \t, \r and \u00XX, as go-logfmt's own encoder
does for tab and carriage return.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant