Skip to content

Commit

Permalink
Change @scanner.match to respond nil/@scanner in order to impro…
Browse files Browse the repository at this point in the history
…ve processing speed.
  • Loading branch information
naitoh committed Jan 16, 2024
1 parent 2b97e16 commit eeb45e1
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 11 deletions.
3 changes: 1 addition & 2 deletions lib/rexml/parsers/baseparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,7 @@ def pull_event
return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ]

when ENTITY_START
match = @source.match( ENTITYDECL, true ).compact
match[0] = :entitydecl
match = [:entitydecl, *@source.match( ENTITYDECL, true ).captures.compact]
ref = false
if match[1] == '%'
ref = true
Expand Down
17 changes: 8 additions & 9 deletions lib/rexml/source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,10 @@ def read

def match(pattern, cons=false)
if cons
@scanner.scan(pattern)
@scanner.scan(pattern).nil? ? nil : @scanner
else
@scanner.check(pattern)
@scanner.check(pattern).nil? ? nil : @scanner
end
@scanner.matched? ? [@scanner.matched, *@scanner.captures] : nil
end

# @return true if the Source is exhausted
Expand Down Expand Up @@ -161,24 +160,24 @@ def read

def match( pattern, cons=false )
if cons
@scanner.scan(pattern)
md = @scanner.scan(pattern)
else
@scanner.check(pattern)
md = @scanner.check(pattern)
end
while !@scanner.matched? and @source
while md.nil? and @source
begin
@scanner << readline
if cons
@scanner.scan(pattern)
md = @scanner.scan(pattern)
else
@scanner.check(pattern)
md = @scanner.check(pattern)
end
rescue
@source = nil
end
end

@scanner.matched? ? [@scanner.matched, *@scanner.captures] : nil
md.nil? ? nil : @scanner
end

def empty?
Expand Down
36 changes: 36 additions & 0 deletions test/parse/test_entity_declaration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: false
require 'test/unit'
require 'rexml/document'

module REXMLTests
class TestParseEntityDeclaration < Test::Unit::TestCase
private
def xml(internal_subset)
<<-XML
<!DOCTYPE r SYSTEM "urn:x-henrikmartensson:test" [
#{internal_subset}
]>
<r/>
XML
end

def parse(internal_subset)
REXML::Document.new(xml(internal_subset)).doctype
end

def test_empty
exception = assert_raise(REXML::ParseException) do
parse(<<-INTERNAL_SUBSET)
<!ENTITY>
INTERNAL_SUBSET
end
assert_equal(<<-DETAIL.chomp, exception.to_s)
Malformed notation declaration: name is missing
Line: 5
Position: 72
Last 80 unconsumed characters:
<!ENTITY> ]> <r/>
DETAIL
end
end
end

0 comments on commit eeb45e1

Please sign in to comment.