From 9090241e614d3c5b302b713041164e27929f8898 Mon Sep 17 00:00:00 2001 From: kou Date: Thu, 19 Apr 2018 21:34:40 +0000 Subject: rexml: Fix a XPath bug that white spaces aren't ignored lib/rexml/parsers/xpathparser.rb: Ignore white spaces in relative location path. test/rexml/xpath/test_base.rb: Add more test patterns and use more debug friendly assertion style. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63204 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/rexml/parsers/xpathparser.rb | 51 +++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'lib/rexml') diff --git a/lib/rexml/parsers/xpathparser.rb b/lib/rexml/parsers/xpathparser.rb index 9577b6dcbe..304dc51698 100644 --- a/lib/rexml/parsers/xpathparser.rb +++ b/lib/rexml/parsers/xpathparser.rb @@ -185,7 +185,7 @@ module REXML # | '/' RelativeLocationPath? # | '//' RelativeLocationPath def LocationPath path, parsed - path = path.strip + path = path.lstrip if path[0] == ?/ parsed << :document if path[1] == ?/ @@ -209,7 +209,12 @@ module REXML # | RelativeLocationPath '//' Step AXIS = /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/ def RelativeLocationPath path, parsed - while path.size > 0 + loop do + original_path = path + path = path.lstrip + + return original_path if path.empty? + # (axis or @ or ) nodetest predicate > # OR > / Step # (. or ..) > @@ -239,28 +244,25 @@ module REXML n = [] path = NodeTest( path, n) - if path[0] == ?[ - path = Predicate( path, n ) - end + path = Predicate( path, n ) parsed.concat(n) end - if path.size > 0 - if path[0] == ?/ - if path[1] == ?/ - parsed << :descendant_or_self - parsed << :node - path = path[2..-1] - else - path = path[1..-1] - end - else - return path - end + original_path = path + path = path.lstrip + return original_path if path.empty? + + return original_path if path[0] != ?/ + + if path[1] == ?/ + parsed << :descendant_or_self + parsed << :node + path = path[2..-1] + else + path = path[1..-1] end end - return path end # Returns a 1-1 map of the nodeset @@ -277,6 +279,8 @@ module REXML NODE_TYPE = /^(comment|text|node)\(\s*\)/m PI = /^processing-instruction\(/ def NodeTest path, parsed + original_path = path + path = path.lstrip case path when /^\*/ path = $' @@ -310,13 +314,17 @@ module REXML parsed << :qname parsed << prefix parsed << name + else + path = original_path end return path end # Filters the supplied nodeset on the predicate(s) def Predicate path, parsed - return nil unless path[0] == ?[ + original_path = path + path = path.lstrip + return original_path unless path[0] == ?[ predicates = [] while path[0] == ?[ path, expr = get_group(path) @@ -509,8 +517,7 @@ module REXML #| LocationPath #| FilterExpr ('/' | '//') RelativeLocationPath def PathExpr path, parsed - path =~ /^\s*/ - path = $' + path = path.lstrip n = [] rest = FilterExpr( path, n ) if rest != path @@ -530,7 +537,7 @@ module REXML def FilterExpr path, parsed n = [] path = PrimaryExpr( path, n ) - path = Predicate(path, n) if path and path[0] == ?[ + path = Predicate(path, n) parsed.concat(n) path end -- cgit v1.2.3