Skip to content

Commit 224a4cd

Browse files
committed
Add Source#skip_spaces? method
## Why? In the case of `@source.match?(/\s+/um, true)`, if there are no spaces at the beginning, I want to stop reading immediately. However, it continues to read the buffer until it finds a match, but it never finds a match. As a result, it continues reading until the end of the file. In the case of large XML files, drop_parsed_content occur frequently until the buffer is cleared, which may affect performance.
1 parent c87bda8 commit 224a4cd

3 files changed

Lines changed: 11 additions & 6 deletions

File tree

lib/rexml/parsers/baseparser.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def pull_event
280280
return [ :comment, process_comment ]
281281
elsif @source.match?("DOCTYPE", true)
282282
base_error_message = "Malformed DOCTYPE"
283-
unless @source.match?(/\s+/um, true)
283+
unless @source.skip_spaces?
284284
if @source.match?(">")
285285
message = "#{base_error_message}: name is missing"
286286
else
@@ -391,7 +391,7 @@ def pull_event
391391
return [ :attlistdecl, element, pairs, contents ]
392392
elsif @source.match?("NOTATION", true)
393393
base_error_message = "Malformed notation declaration"
394-
unless @source.match?(/\s+/um, true)
394+
unless @source.skip_spaces?
395395
if @source.match?(">")
396396
message = "#{base_error_message}: name is missing"
397397
else
@@ -735,7 +735,7 @@ def process_comment
735735

736736
def process_instruction
737737
name = parse_name("Malformed XML: Invalid processing instruction node")
738-
if @source.match?(/\s+/um, true)
738+
if @source.skip_spaces?
739739
match_data = @source.match(/(.*?)\?>/um, true)
740740
unless match_data
741741
raise ParseException.new("Malformed XML: Unclosed processing instruction", @source)

lib/rexml/source.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class Source
6565
attr_reader :encoding
6666

6767
module Private
68+
SKIP_SPACES = /\s+/um
6869
SCANNER_RESET_SIZE = 100000
6970
PRE_DEFINED_TERM_PATTERNS = {}
7071
pre_defined_terms = ["'", '"', "<", "]]>"]
@@ -150,6 +151,10 @@ def match?(pattern, cons=false)
150151
end
151152
end
152153

154+
def skip_spaces?
155+
@scanner.skip(Private::SKIP_SPACES) ? true : false
156+
end
157+
153158
def position
154159
@scanner.pos
155160
end

test/parse/test_document_type_declaration.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ def test_no_name
4949
end
5050
assert_equal(<<-DETAIL.chomp, exception.to_s)
5151
Malformed DOCTYPE: name is missing
52-
Line: 3
53-
Position: 17
52+
Line: 1
53+
Position: 10
5454
Last 80 unconsumed characters:
55-
<!DOCTYPE> <r/>
55+
<!DOCTYPE>
5656
DETAIL
5757
end
5858
end

0 commit comments

Comments
 (0)