From d6ddd294c588578f6d8dad588716c62f424af2f7 Mon Sep 17 00:00:00 2001 From: nick evans Date: Mon, 11 May 2026 08:51:25 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Prevent=20trailing=20`{0}`=20in?= =?UTF-8?q?=20RawData=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zero-length literals are explicitly allowed by the RFCs and this did not catch text that ends with `{0}` or `{0+}`. This leaves RawData able to absorb the `CRLF` that ends the command, and thus absorb the following command into itself. Ultimately, we don't care if the `number64` is encoded correctly nor whether it claims to be a binary literal. So I've simplified the regexp by dropping `~?` and using `\d+` for the number. --- lib/net/imap/command_data.rb | 2 +- test/net/imap/test_command_data.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/net/imap/command_data.rb b/lib/net/imap/command_data.rb index 9a5749b5..f97fda44 100644 --- a/lib/net/imap/command_data.rb +++ b/lib/net/imap/command_data.rb @@ -212,7 +212,7 @@ def send_data(imap, tag) = data.each do _1.send_data(imap, tag) end def validate return unless data.last in RawText(data: text) - if text.rindex(/~?\{[1-9]\d*\+?\}\z/n) + if text.rindex(/\{\d+\+?\}\z/n) raise DataFormatError, "RawData cannot end with literal continuation" end end diff --git a/test/net/imap/test_command_data.rb b/test/net/imap/test_command_data.rb index 59419899..4d5ab858 100644 --- a/test/net/imap/test_command_data.rb +++ b/test/net/imap/test_command_data.rb @@ -366,6 +366,13 @@ class RawDataTest < CommandDataTest assert_raise(DataFormatError) do RawData.new(data: "~literal+ ~{123+}") end raw = RawData.new(data: " {123} ") assert_equal [RawText[" {123} "]], raw.data + + assert_raise(DataFormatError) do RawData.new(data: "literal {0}") end + assert_raise(DataFormatError) do RawData.new(data: "literal+ {0+}") end + assert_raise(DataFormatError) do RawData.new(data: "~literal ~{0}") end + assert_raise(DataFormatError) do RawData.new(data: "~literal+ ~{0+}") end + raw = RawData.new(data: " {0} ") + assert_equal [RawText[" {0} "]], raw.data end data(