From e787360795b0ad5d1da1c8bfc52fa3cee504af3e Mon Sep 17 00:00:00 2001
From: Shugo Maeda <shugo@ruby-lang.org>
Date: Thu, 23 May 2024 12:06:54 +0900
Subject: [PATCH 1/2] Use String#byteindex instead of String#index

Because String#index takes O(N), where N is the second argument, while String#byteindex takes O(1).
---
 lib/net/imap/response_parser.rb | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/lib/net/imap/response_parser.rb b/lib/net/imap/response_parser.rb
index 84f6cf79..39fbafca 100644
--- a/lib/net/imap/response_parser.rb
+++ b/lib/net/imap/response_parser.rb
@@ -2023,16 +2023,16 @@ def nil_atom
       # This advances @pos directly so it's safe before changing @lex_state.
       def accept_spaces
         return false unless SP?
-        @str.index(SPACES_REGEXP, @pos) and
-          @pos = $~.end(0)
+        @str.byteindex(SPACES_REGEXP, @pos) and
+          @pos = $~.byteoffset(0)[1]
         true
       end
 
       def next_token
         case @lex_state
         when EXPR_BEG
-          if @str.index(BEG_REGEXP, @pos)
-            @pos = $~.end(0)
+          if @str.byteindex(BEG_REGEXP, @pos)
+            @pos = $~.byteoffset(0)[1]
             if $1
               return Token.new(T_SPACE, $+)
             elsif $2
@@ -2081,12 +2081,12 @@ def next_token
               parse_error("[Net::IMAP BUG] BEG_REGEXP is invalid")
             end
           else
-            @str.index(/\S*/n, @pos)
+            @str.byteindex(/\S*/n, @pos)
             parse_error("unknown token - %s", $&.dump)
           end
         when EXPR_DATA
-          if @str.index(DATA_REGEXP, @pos)
-            @pos = $~.end(0)
+          if @str.byteindex(DATA_REGEXP, @pos)
+            @pos = $~.byteoffset(0)[1]
             if $1
               return Token.new(T_SPACE, $+)
             elsif $2
@@ -2108,7 +2108,7 @@ def next_token
               parse_error("[Net::IMAP BUG] DATA_REGEXP is invalid")
             end
           else
-            @str.index(/\S*/n, @pos)
+            @str.byteindex(/\S*/n, @pos)
             parse_error("unknown token - %s", $&.dump)
           end
         else

From 3243709a62e1a6ca98ba3000a0603bdc7f358ada Mon Sep 17 00:00:00 2001
From: Shugo Maeda <shugo@ruby-lang.org>
Date: Tue, 13 Aug 2024 14:28:51 +0900
Subject: [PATCH 2/2] byteslice should be used instead of String#[]

---
 lib/net/imap/response_parser.rb | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/net/imap/response_parser.rb b/lib/net/imap/response_parser.rb
index 39fbafca..3d352cbb 100644
--- a/lib/net/imap/response_parser.rb
+++ b/lib/net/imap/response_parser.rb
@@ -2037,7 +2037,7 @@ def next_token
               return Token.new(T_SPACE, $+)
             elsif $2
               len = $+.to_i
-              val = @str[@pos, len]
+              val = @str.byteslice(@pos, len)
               @pos += len
               return Token.new(T_LITERAL8, val)
             elsif $3 && $7
@@ -2068,7 +2068,7 @@ def next_token
               return Token.new(T_RBRA, $+)
             elsif $16
               len = $+.to_i
-              val = @str[@pos, len]
+              val = @str.byteslice(@pos, len)
               @pos += len
               return Token.new(T_LITERAL, val)
             elsif $17
@@ -2097,7 +2097,7 @@ def next_token
               return Token.new(T_QUOTED, Patterns.unescape_quoted($+))
             elsif $5
               len = $+.to_i
-              val = @str[@pos, len]
+              val = @str.byteslice(@pos, len)
               @pos += len
               return Token.new(T_LITERAL, val)
             elsif $6