From 2c3930572a2ef1c288bc1ec0ebac68642b936bf4 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Tue, 29 Jan 2019 19:55:25 +0000 Subject: [PATCH 1/5] Fix crash with nil XPath variables Prior to d91e124ab9843d2eaf62071bf029301254c36e2b, an XPath variable could be set to nil, in which case it would be silently converted to an empty string. This is clearly still the intended behaviour of this method, as can be seen from the `when nil` further down. But, with the introduction of context support, this case was broken, because trying to do @@context[:node] would raise a NoMethodError if there was no context. --- lib/rexml/functions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rexml/functions.rb b/lib/rexml/functions.rb index 219f9c8d..ea4a2aed 100644 --- a/lib/rexml/functions.rb +++ b/lib/rexml/functions.rb @@ -136,7 +136,7 @@ def Functions::get_namespace( node_set = nil ) # An object of a type other than the four basic types is converted to a # string in a way that is dependent on that type. def Functions::string( object=nil ) - object = @@context[:node] if object.nil? + object = @@context[:node] if object.nil? && !@@context.nil? if object.respond_to?(:node_type) case object.node_type when :attribute From f3423fcf56bb9fbc356b18f59f39a4faee28cf70 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Tue, 29 Jan 2019 19:59:41 +0000 Subject: [PATCH 2/5] Remove redundant string substitution for nil This is already covered by #to_s, for which nil returns "". --- lib/rexml/functions.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/rexml/functions.rb b/lib/rexml/functions.rb index ea4a2aed..9ad73243 100644 --- a/lib/rexml/functions.rb +++ b/lib/rexml/functions.rb @@ -165,8 +165,6 @@ def Functions::string( object=nil ) object.to_s end end - when nil - "" else object.to_s end From 97047ac317b20f3065f6a6f50685b1ae53f673b1 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Wed, 30 Jan 2019 17:18:33 +0000 Subject: [PATCH 3/5] Add test for string function with nil context --- test/rexml/test_functions.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/rexml/test_functions.rb b/test/rexml/test_functions.rb index a77be38c..50438eea 100644 --- a/test/rexml/test_functions.rb +++ b/test/rexml/test_functions.rb @@ -222,6 +222,22 @@ def test_normalize_space assert_equal( [REXML::Comment.new("COMMENT A")], m ) end + def test_string_nil_without_context + # Reset to default value + REXML::Functions.class_variable_set(:@@context, nil) + + doc = REXML::Document.new(<<-XML) + + + + + + XML + + m = REXML::XPath.match(doc, "//foo[@bar=$n]", nil, { "n" => nil }) + assert_equal( 1, m.size ) + end + def test_unregistered_method doc = Document.new("") assert_nil(XPath::first(doc.root, "to_s()")) From 2842ce9929aa38d902fa649103bfa89b74b8068d Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Fri, 1 Feb 2019 10:48:28 +0000 Subject: [PATCH 4/5] Differentiate between nil object and no object --- lib/rexml/functions.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/rexml/functions.rb b/lib/rexml/functions.rb index 9ad73243..9c226d2c 100644 --- a/lib/rexml/functions.rb +++ b/lib/rexml/functions.rb @@ -135,8 +135,7 @@ def Functions::get_namespace( node_set = nil ) # # An object of a type other than the four basic types is converted to a # string in a way that is dependent on that type. - def Functions::string( object=nil ) - object = @@context[:node] if object.nil? && !@@context.nil? + def Functions::string( object=@@context[:node] ) if object.respond_to?(:node_type) case object.node_type when :attribute From 84fc709c0de24e8d25e621ef86e7a9c57cb8f0f2 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Fri, 1 Feb 2019 10:51:01 +0000 Subject: [PATCH 5/5] Clear Functions.context before each functions test --- test/rexml/test_functions.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/rexml/test_functions.rb b/test/rexml/test_functions.rb index 50438eea..c1716ebe 100644 --- a/test/rexml/test_functions.rb +++ b/test/rexml/test_functions.rb @@ -6,6 +6,12 @@ module REXMLTests class FunctionsTester < Test::Unit::TestCase include REXML + + def setup + super + REXML::Functions.context = nil + end + def test_functions # trivial text() test # confuse-a-function @@ -223,9 +229,6 @@ def test_normalize_space end def test_string_nil_without_context - # Reset to default value - REXML::Functions.class_variable_set(:@@context, nil) - doc = REXML::Document.new(<<-XML)