From cae2bff83705c2d8d7fe9ef3f6592bbe33e062f0 Mon Sep 17 00:00:00 2001 From: nick evans Date: Mon, 14 Apr 2025 09:23:58 -0400 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Save=20ResponseReader=20iv?= =?UTF-8?q?ars:=20@buff=20&=20@literal=5Fsize?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids the need to pass these to every method that uses them. That's not a big deal now, but it simplifies the next few changes. Also added a missing test for empty literals: "{0}\r\n" --- lib/net/imap/response_reader.rb | 20 ++++++++++++++------ test/net/imap/test_response_reader.rb | 3 +++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/net/imap/response_reader.rb b/lib/net/imap/response_reader.rb index 57770e3b8..7d3a53685 100644 --- a/lib/net/imap/response_reader.rb +++ b/lib/net/imap/response_reader.rb @@ -11,26 +11,34 @@ def initialize(client, sock) end def read_response_buffer - buff = String.new + @buff = String.new catch :eof do while true - read_line(buff) - break unless /\{(\d+)\}\r\n\z/n =~ buff - read_literal(buff, $1.to_i) + read_line + break unless (@literal_size = get_literal_size) + read_literal end end buff + ensure + @buff = nil end private - def read_line(buff) + attr_reader :buff, :literal_size + + def get_literal_size = /\{(\d+)\}\r\n\z/n =~ buff && $1.to_i + + def read_line buff << (@sock.gets(CRLF) or throw :eof) end - def read_literal(buff, literal_size) + def read_literal literal = String.new(capacity: literal_size) buff << (@sock.read(literal_size, literal) or throw :eof) + ensure + @literal_size = nil end end diff --git a/test/net/imap/test_response_reader.rb b/test/net/imap/test_response_reader.rb index c24f1269d..159002c3d 100644 --- a/test/net/imap/test_response_reader.rb +++ b/test/net/imap/test_response_reader.rb @@ -24,6 +24,7 @@ def literal(str) = "{#{str.bytesize}}\r\n#{str}" long_line = "tag ok #{aaaaaaaaa} #{aaaaaaaaa}\r\n" literal_aaaa = "* fake #{literal aaaaaaaaa}\r\n" literal_crlf = "tag ok #{literal many_crlfs} #{literal many_crlfs}\r\n" + zero_literal = "tag ok #{literal ""} #{literal ""}\r\n" illegal_crs = "tag ok #{many_crs} #{many_crs}\r\n" illegal_lfs = "tag ok #{literal "\r"}\n#{literal "\r"}\n\r\n" io = StringIO.new([ @@ -31,6 +32,7 @@ def literal(str) = "{#{str.bytesize}}\r\n#{str}" long_line, literal_aaaa, literal_crlf, + zero_literal, illegal_crs, illegal_lfs, simple, @@ -40,6 +42,7 @@ def literal(str) = "{#{str.bytesize}}\r\n#{str}" assert_equal long_line, rcvr.read_response_buffer.to_str assert_equal literal_aaaa, rcvr.read_response_buffer.to_str assert_equal literal_crlf, rcvr.read_response_buffer.to_str + assert_equal zero_literal, rcvr.read_response_buffer.to_str assert_equal illegal_crs, rcvr.read_response_buffer.to_str assert_equal illegal_lfs, rcvr.read_response_buffer.to_str assert_equal simple, rcvr.read_response_buffer.to_str