From d146162e9a61574499d10428bc0065754cd26601 Mon Sep 17 00:00:00 2001
From: NAITOH Jun <naitoh@gmail.com>
Date: Mon, 4 Mar 2024 05:24:53 +0900
Subject: [PATCH] Remove `Source#string=` method (#117)

We want to just change scan pointer.

https://github.com/ruby/rexml/pull/114#discussion_r1501773803
> I want to just change scan pointer (`StringScanner#pos=`) instead of
changing `@scanner.string`.

CVE: CVE-2024-39908

Upstream-Status: Backport [https://github.com/ruby/rexml/commit/d146162e9a61574499d10428bc0065754cd26601]

Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
---
 .../lib/rexml/parsers/baseparser.rb           | 19 +++++++++++--------
 .bundle/gems/rexml-3.2.5/lib/rexml/source.rb  |  8 ++++++--
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb
index 8ea8b43..81415a8 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb
@@ -231,8 +231,9 @@ module REXML
         #STDERR.puts @source.encoding
         #STDERR.puts "BUFFER = #{@source.buffer.inspect}"
         if @document_status == nil
+          start_position = @source.position
           if @source.match("<?", true)
-            return process_instruction
+            return process_instruction(start_position)
           elsif @source.match("<!", true)
             if @source.match("--", true)
               return [ :comment, @source.match(/(.*?)-->/um, true)[1] ]
@@ -244,7 +245,7 @@ module REXML
                 else
                   message = "#{base_error_message}: invalid name"
                 end
-                @source.string = "<!DOCTYPE" + @source.buffer
+                @source.position = start_position
                 raise REXML::ParseException.new(message, @source)
               end
               name = parse_name(base_error_message)
@@ -285,6 +286,7 @@ module REXML
         end
         if @document_status == :in_doctype
           @source.match(/\s*/um, true) # skip spaces
+          start_position = @source.position
           if @source.match("<!", true)
             if @source.match("ELEMENT", true)
               md = @source.match(/(.*?)>/um, true)
@@ -344,7 +346,7 @@ module REXML
                 else
                   message = "#{base_error_message}: invalid name"
                 end
-                @source.string = " <!NOTATION" + @source.buffer
+                @source.position = start_position
                 raise REXML::ParseException.new(message, @source)
               end
               name = parse_name(base_error_message)
@@ -374,6 +376,7 @@ module REXML
           @source.match(/\s*/um, true)
         end
         begin
+          start_position = @source.position
           if @source.match("<", true)
             if @source.match("/", true)
               @namespaces_restore_stack.pop
@@ -386,7 +389,7 @@ module REXML
               if md.nil? or last_tag != md[1]
                 message = "Missing end tag for '#{last_tag}'"
                 message += " (got '#{md[1]}')" if md
-                @source.string = "</" + @source.buffer if md.nil?
+                @source.position = start_position if md.nil?
                 raise REXML::ParseException.new(message, @source)
               end
               return [ :end_element, last_tag ]
@@ -410,12 +413,12 @@ module REXML
               raise REXML::ParseException.new( "Declarations can only occur "+
                 "in the doctype declaration.", @source)
             elsif @source.match("?", true)
-              return process_instruction
+              return process_instruction(start_position)
             else
               # Get the next tag
               md = @source.match(TAG_PATTERN, true)
               unless md
-                @source.string = "<" + @source.buffer
+                @source.position = start_position
                 raise REXML::ParseException.new("malformed XML: missing tag start", @source)
               end
               tag = md[1]
@@ -641,11 +644,11 @@ module REXML
         end
       end
 
-      def process_instruction
+      def process_instruction(start_position)
         match_data = @source.match(INSTRUCTION_END, true)
         unless match_data
           message = "Invalid processing instruction node"
-          @source.string = "<?" + @source.buffer
+          @source.position = start_position
           raise REXML::ParseException.new(message, @source)
         end
         if @document_status.nil? and match_data[1] == "xml"
diff --git a/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb b/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
index 7132147..b20cc4f 100644
--- a/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
+++ b/.bundle/gems/rexml-3.2.5/lib/rexml/source.rb
@@ -80,8 +80,12 @@ module REXML
       end
     end
 
-    def string=(string)
-      @scanner.string = string
+    def position
+      @scanner.pos
+    end
+
+    def position=(pos)
+      @scanner.pos = pos
     end
 
     # @return true if the Source is exhausted
-- 
2.40.0

