Thread safety Functions#329
Open
tompng wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Refactors REXML XPath function handling to use instance-scoped state (context/namespaces/variables) instead of module-level shared state, improving isolation and enabling safer concurrent use.
Changes:
- Introduces
FunctionsClasswith instance variables forcontext,namespace_context, andvariables, plus a new default singletonFunctions. - Updates
XPathParserto use an instance ofFunctionsClassfor boolean/number/string conversions and function dispatch. - Removes
include FunctionsfromREXML::XPathandREXML::QuickPath.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| lib/rexml/xpath_parser.rb | Switches function evaluation and coercions to an instance (@functions) rather than global Functions state. |
| lib/rexml/xpath.rb | Removes include Functions, altering how XPath functions are accessed through REXML::XPath. |
| lib/rexml/quickpath.rb | Removes include Functions, altering QuickPath’s access to XPath functions. |
| lib/rexml/functions.rb | Replaces module Functions with FunctionsClass and introduces a default singleton instance Functions. |
Comments suppressed due to low confidence (1)
lib/rexml/functions.rb:1
@@available_functionsis automatically populated from all non-internal instance methods viamethod_added, andsendwill then invoke them viasuper(bypassing visibility checks). This makes it easy to accidentally expose non-XPath helper methods as callable XPath functions when new instance methods are added in the future. A safer approach is to explicitly whitelist exported XPath functions (or mark helper methods private and exclude private methods from registration), rather than implicitly exporting everything not listed inINTERNAL_METHODS.
# frozen_string_literal: false
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+10
to
+17
| class FunctionsClass | ||
| @@available_functions = {} | ||
| @@context = nil | ||
| @@namespace_context = {} | ||
| @@variables = {} | ||
|
|
||
| def initialize | ||
| @context = nil | ||
| @namespace_context = {} | ||
| @variables = {} | ||
| end |
Comment on lines
+450
to
+453
| # Using this singleton instance may cause thread-safety issues | ||
| # especially when accessing variables, context and namespace_context. | ||
| # Consider instantiating your own FunctionsClass object. | ||
| Functions = FunctionsClass.new |
Comment on lines
5
to
10
| module REXML | ||
| # Wrapper class. Use this class to access the XPath functions. | ||
| class XPath | ||
| include Functions | ||
| # A base Hash object, supposing to be used when initializing a | ||
| # default empty namespaces set, but is currently unused. | ||
| # TODO: either set the namespaces=EMPTY_HASH, or deprecate this. |
Comment on lines
+439
to
447
| def 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) | ||
| XPath.match(@context[:node], name.to_s) | ||
| end | ||
| end |
Comment on lines
+450
to
+453
| # Using this singleton instance may cause thread-safety issues | ||
| # especially when accessing variables, context and namespace_context. | ||
| # Consider instantiating your own FunctionsClass object. | ||
| Functions = FunctionsClass.new |
REXML::Functions have a state and is not thread-safe. Change it to a class, always create a new instance in XPath#match. `REXML::Functions = REXML::FunctionsClass.new` is kept for untested REXML::Quickpath and for test code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
REXML::Functions have a state and is not thread-safe.
Change it to a class, always create a new instance in
XPath#match.REXML::Functions = REXML::FunctionsClass.newis kept for untestedREXML::Quickpathand for test code.Bug reproduction code
After about 10 seconds, it raises
"Shouldn't happen"About deleted
include FunctionsFunctions doesn't have instance methods, only have one constant for internal use.
include Functionshad no effect.