Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/rexml/parsers/xpathparser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class XPathParser # :nodoc:
include XMLTokens
LITERAL = /^'([^']*)'|^"([^"]*)"/u

def initialize(strict: false)
@strict = strict
end

def namespaces=( namespaces )
Functions::namespace_context = namespaces
@namespaces = namespaces
Expand Down Expand Up @@ -653,6 +657,7 @@ def PrimaryExpr path, parsed
#arry << @variables[ varname ]
when /^(\w[-\w]*)(?:\()/
fname = $1
return path if @strict && fname.include?("_")
tmp = $'
return path if fname =~ NT
path = tmp
Expand Down
2 changes: 1 addition & 1 deletion lib/rexml/xpath_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class XPathParser

def initialize(strict: false)
@debug = DEBUG
@parser = REXML::Parsers::XPathParser.new
@parser = REXML::Parsers::XPathParser.new(strict: strict)
@namespaces = nil
@variables = {}
@functions = FunctionsClass.new
Expand Down
9 changes: 8 additions & 1 deletion test/functions/test_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,18 @@ def test_string_nil_without_context
{"n" => nil}))
end

def test_unregistered_method
def test_unregistered_method_with_underscore
doc = Document.new("<root/>")
assert_nil(XPath::first(doc.root, "to_s()"))
end

def test_unregistered_method_with_underscore_in_strict_mode
doc = Document.new("<root/>")
assert_raise(REXML::ParseException) do
XPath::first(doc.root, "to_s()", nil, {}, strict: true)
end
end

def test_nonexistent_function
doc = Document.new("<root><nonexistent/></root>")
# TODO: Maybe, this is not XPath spec behavior.
Expand Down
13 changes: 13 additions & 0 deletions test/parser/test_xpath.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: false

require "test/unit"
require "rexml/parseexception"
require "rexml/parsers/xpathparser"

module REXMLTests
Expand Down Expand Up @@ -66,6 +67,18 @@ def test_function
abbreviate("string-length(a/b[last()])"))
end

def test_function_with_underscore
assert_equal("local_name(*)",
abbreviate("local_name(*)"))
end

def test_function_with_underscore_in_strict_mode
parser = REXML::Parsers::XPathParser.new(strict: true)
assert_raise(REXML::ParseException) do
parser.abbreviate("local_name(*)")
end
end

def test_descendant_or_self_only
assert_equal("//",
abbreviate("/descendant-or-self::node()/"))
Expand Down