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

オープン 初心者向け
#789 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
77/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
ruby

調査の方向性

issueで示されているlib/net/imap/response_reader.rbのget_literal_sizeと、test/net/imap/test_response_reader.rbのレスポンスリーダーのテストから始めます。長い行のケースを再現し、返された値がどのようにResponseTooLargeError#literal_sizeに渡されるかを確認します。行のケースではnilが報告され、リテラルレスポンスでは引き続きサイズが報告されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

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

主要言語
Ruby
スター
121
フォーク
47
平均マージ
19時間 25分
マージ済み PR(30日)
3

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

ruby/net-imap のほかの issue

ruby/net-imap の issue をすべて見る

似ている issue

Ruby の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。