Skip to content

🥅 Test for NULL bytes before sending string args - #712

Merged
nevans merged 4 commits into
masterfrom
test-for-null-bytes-in-string-args
Jul 8, 2026
Merged

🥅 Test for NULL bytes before sending string args#712
nevans merged 4 commits into
masterfrom
test-for-null-bytes-in-string-args

Conversation

@nevans

@nevans nevans commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

The latest release does validate that atoms, quoted strings, literals don't contain any NULL bytes. However generic string arguments would not be fully validated until they attempted to send (inside #send_string_data).

This change allows us to raise the exception during argument validation, rather than waiting until we are sending the command (which is too late to save the connection from being broken).

Additionally:

  • Although many other tests provide coverage for generic string arguments, I discovered that we were missing any basic test coverage for sending UTF-8 string arguments. So I added some tests to make sure we have full coverage over each case in send_string_data.
  • I added some (internal only) rdoc to clarify the difference between astring (used for generic string args) and Atom. This (or something like it) may be promoted to public rdoc in a future version.

@nevans
nevans force-pushed the test-for-null-bytes-in-string-args branch from 8385e0e to 65df95d Compare July 5, 2026 22:36
nevans added 4 commits July 8, 2026 13:30
We were missing any basic tests for sending UTF-8 strings!
Also dropped some redundant comments
These are identical regexps, make the code better self-documenting.

Note that ASTRING_SPECIALS is identical to
ResponseParser::Patterns::ASTRING_SPECIALS.
This allows us to raise the exception during argument validation, rather
than waiting until we are sending the command (which is too late to save
the connection from being corrupted).
@nevans
nevans force-pushed the test-for-null-bytes-in-string-args branch from 65df95d to 6a4dc11 Compare July 8, 2026 18:40
@nevans nevans added the bug Something isn't working label Jul 8, 2026
@nevans
nevans merged commit bf1043e into master Jul 8, 2026
39 checks passed
@nevans
nevans deleted the test-for-null-bytes-in-string-args branch July 8, 2026 19:05
Comment thread lib/net/imap/command_data.rb Outdated
end
end

UNQUOTABLE_CHARS = /\r\n/n

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops.

nevans added a commit that referenced this pull request Jul 23, 2026
This bug was introduced by a742a10.  When I extracted the
`UNQUOTABLE_CHARS` regexp into a constant, I didn't copied it exactly.
It was converted from a character class into a sequence of bytes:
```ruby
    # It should've been this:
    UNQUOTABLE_CHARS = /[\0\r\n]/n
    # But I incorrectly copied it as this:
    UNQUOTABLE_CHARS = /\0\r\n/n
```

If that regexp were the only guard, this regexp would've allowed CRLF
injections!  Fortunately, quoted strings are now sent using
`Net::IMAP::QuotedString` (since #698, released in v0.6.4.1), and that
_does_ correctly validate that the input is a valid quoted string.  So,
the string isn't _sent_ as invalid quoted data.

Unfortunately, this does result in an exception for strings that could
be valid literals.  And, because it crashes while sending command
arguments, rather than during validation, the connection will be broken.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant