ResponseTooLargeError#literal_size is false (not nil) when a line exceeds max_response_size

Offen Anfängerfreundlich
#789 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
77/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
ruby
Bereich
backend, networking

Rechercherichtung

Beginne mit get_literal_size in lib/net/imap/response_reader.rb und den Tests für den Response Reader in test/net/imap/test_response_reader.rb, die beide im Issue genannt werden. Reproduziere den Fall mit der langen Zeile und prüfe, wie der zurückgegebene Wert ResponseTooLargeError#literal_size erreicht. Fertig ist die Änderung, wenn der Zeilenfall nil meldet, während Literal Responses weiterhin ihre Größe melden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

When a response exceeds max_response_size because of a long line (not a literal), Net::IMAP::ResponseTooLargeError#literal_size is false instead of nil since v0.6.4. Before v0.6.4 (and on the v0.5 / v0.4 branches) it is nil.

Reproduction
require "net/imap"
require "socket"

puts RUBY_DESCRIPTION
puts "net-imap #{Net::IMAP::VERSION}"

def try(label, payload)
  server = TCPServer.new("127.0.0.1", 0)
  th = Thread.new do
    sock = server.accept
    sock.write "* OK ready\r\n"
    sock.write payload
    sleep 1
    sock.close
  end
  imap = Net::IMAP.new("127.0.0.1", port: server.addr[1], max_response_size: 100)
  imap.noop
rescue Net::IMAP::ResponseTooLargeError => e
  printf "%-8s bytes_read=%p literal_size=%p max_response_size=%p\n",
         label, e.bytes_read, e.literal_size, e.max_response_size
ensure
  imap&.disconnect rescue nil
  th&.join
  server&.close
end

try "line",    "* " + "a" * 300 + "\r\n"
try "literal", "* 1 FETCH (BODY[] {200}\r\n" + "a" * 200 + ")\r\n"
Output
ruby 4.1.0dev (2026-11-09T07:44:48Z HEAD 4f0a0a0eca) +PRISM [x86_64-linux]
net-imap 0.6.8
line     bytes_read=100 literal_size=false max_response_size=100
literal  bytes_read=25 literal_size=200 max_response_size=100
ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [x86_64-linux]
net-imap 0.6.4.1
line     bytes_read=100 literal_size=false max_response_size=100
literal  bytes_read=25 literal_size=200 max_response_size=100
ruby 4.0.0 (2025-12-25 revision 553f1675f3) +PRISM [x86_64-linux]
net-imap 0.6.2
line     bytes_read=100 literal_size=nil max_response_size=100
literal  bytes_read=25 literal_size=200 max_response_size=100
ruby 3.4.12 (2026-10-23 revision 366f5fdc00) +PRISM [x86_64-linux]
net-imap 0.5.15
line     bytes_read=100 literal_size=nil max_response_size=100
literal  bytes_read=25 literal_size=200 max_response_size=100
Expected

literal_size is nil for the "line" case, as in v0.6.2 and v0.5.15 (and as the literal_size: nil default of ResponseTooLargeError#initialize suggests).

Cause

ResponseReader#get_literal_size returns false when the line does not end with a literal prefix:

https://github.com/ruby/net-imap/blob/v0.6.8/lib/net/imap/response_reader.rb#L50-L52

Since 6f82e28 ("Faster ResponseReader: parse literal from line", #642), read_line stores that value in @literal_size before guard_response_too_large! runs, so the false is passed to ResponseTooLargeError.new. On the v0.5 / v0.4 branches the same get_literal_size was backported, but there the error is raised before @literal_size is assigned, so they are not affected.

The error message is unaffected (response_size_msg treats false as falsy); only the attribute value differs.

Possible fix
       def get_literal_size(buff)
-        buff.end_with?("}\r\n") && buff.rindex(/\{(\d+)\}\r\n\z/n) &&
-          coerce_number64($1)
+        return unless buff.end_with?("}\r\n") && buff.rindex(/\{(\d+)\}\r\n\z/n)
+        coerce_number64($1)
       rescue DataFormatError

I can open a PR with this change and a test in test/net/imap/test_response_reader.rb if that helps.

🤖 Generated with Claude Code

Vorherrschende Sprache
Ruby
Sterne
121
Forks
47
Ø Merge
19 Std. 25 Min.
Gemergte PRs (30 T.)
3

Entwicklungsumgebung

Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus ruby/net-imap

Alle Issues in ruby/net-imap

Ähnliche Issues

Weitere Issues zu Ruby

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.