[前][次][番号順一覧][スレッド一覧]

ruby-changes:47467

From: kou <ko1@a...>
Date: Sun, 13 Aug 2017 21:14:29 +0900 (JST)
Subject: [ruby-changes:47467] kou:r59584 (trunk): REXML: Fix a bug that unexpected methods can be called as a XPath function

kou	2017-08-13 21:14:24 +0900 (Sun, 13 Aug 2017)

  New Revision: 59584

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59584

  Log:
    REXML: Fix a bug that unexpected methods can be called as a XPath function
    
    [HackerOne:249295]
    
    Reported by Andrea Jegher. Thanks!!!

  Modified files:
    trunk/lib/rexml/functions.rb
    trunk/test/rexml/test_functions.rb
Index: test/rexml/test_functions.rb
===================================================================
--- test/rexml/test_functions.rb	(revision 59583)
+++ test/rexml/test_functions.rb	(revision 59584)
@@ -221,5 +221,18 @@ module REXMLTests https://github.com/ruby/ruby/blob/trunk/test/rexml/test_functions.rb#L221
       m = REXML::XPath.match(doc, "//comment()[#{predicate}]")
       assert_equal( [REXML::Comment.new("COMMENT A")], m )
     end
+
+    def test_unregistered_method
+      doc = Document.new("<root/>")
+      assert_nil(XPath::first(doc.root, "to_s()"))
+    end
+
+    def test_nonexistent_function
+      doc = Document.new("<root><nonexistent/></root>")
+      # TODO: Maybe, this is not XPath spec behavior.
+      # This behavior must be reconsidered.
+      assert_equal(doc.root.elements[1],
+                   XPath::first(doc.root, "nonexistent()"))
+    end
   end
 end
Index: lib/rexml/functions.rb
===================================================================
--- lib/rexml/functions.rb	(revision 59583)
+++ lib/rexml/functions.rb	(revision 59584)
@@ -8,10 +8,28 @@ module REXML https://github.com/ruby/ruby/blob/trunk/lib/rexml/functions.rb#L8
   # Therefore, in XML, "local-name()" is identical (and actually becomes)
   # "local_name()"
   module Functions
+    @@available_functions = {}
     @@context = nil
     @@namespace_context = {}
     @@variables = {}
 
+    INTERNAL_METHODS = [
+      :namespace_context,
+      :namespace_context=,
+      :variables,
+      :variables=,
+      :context=,
+      :get_namespace,
+      :send,
+    ]
+    class << self
+      def singleton_method_added(name)
+        unless INTERNAL_METHODS.include?(name)
+          @@available_functions[name] = true
+        end
+      end
+    end
+
     def Functions::namespace_context=(x) ; @@namespace_context=x ; end
     def Functions::variables=(x) ; @@variables=x ; end
     def Functions::namespace_context ; @@namespace_context ; end
@@ -390,9 +408,14 @@ module REXML https://github.com/ruby/ruby/blob/trunk/lib/rexml/functions.rb#L408
       node.node_type == :processing_instruction
     end
 
-    def Functions::method_missing( id )
-      puts "METHOD MISSING #{id.id2name}"
-      XPath.match( @@context[:node], id.id2name )
+    def Functions::send(name, *args)
+      if @@available_functions[name.to_sym]
+        super
+      else
+        # TODO: Maybe, this is not XPath spec behavior.
+        # This behavior must be reconsidered.
+        XPath.match(@@context[:node], name.to_s)
+      end
     end
   end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]