Change XPath available function check from denylist to allowlist - #369
Open
tompng wants to merge 1 commit into
Open
Change XPath available function check from denylist to allowlist#369tompng wants to merge 1 commit into
tompng wants to merge 1 commit into
Conversation
Define an allowlist of available xpath functions instead of listing up all internal methods which isn't xpath function. `REXML::FunctionsClass` now strictly checks function names: `local-name` is allowed but `local_name` is rejected. The compatibility layer that accepts `local_name` is in the call site.
There was a problem hiding this comment.
🟢 Approval recommended
The changes are localized, internally consistent (parser + functions + tests), and the updated tests directly cover the new allowlist and compatibility behavior.
Pull request overview
This PR tightens XPath function dispatch in REXML by switching REXML::FunctionsClass from a denylist-based “anything except internal helpers” check to a strict allowlist of recognized XPath functions, while keeping backward-compatible underscore aliases at the call site.
Changes:
- Introduces
REXML::FunctionsClass::AVAILABLE_FUNCTIONS(aSet) and routes function invocation through a newFunctionsClass#callallowlist gate. - Updates
XPathParserto invoke XPath functions via#call(with a compatibility normalization layer and fallback behavior). - Adjusts/extends tests to validate the allowlist, strictness for underscored names via
#call, and compatibility via#send.
File summaries
| File | Description |
|---|---|
| test/functions/test_base.rb | Updates tests to assert the allowlist contents and stricter function-name handling while preserving compatibility paths. |
| lib/rexml/xpath_parser.rb | Switches function evaluation from send to FunctionsClass#call, providing underscore-to-hyphen compatibility and fallback behavior. |
| lib/rexml/functions.rb | Adds AVAILABLE_FUNCTIONS allowlist and implements #call as the strict dispatch mechanism, with #send retained as a compatibility wrapper. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
Define an allowlist of available xpath functions Instead of listing up all internal methods which isn't xpath function.
REXML::FunctionsClassnow strictly checks function names:local-nameis allowed butlocal_nameis rejected.The compatibility layer that accepts
local_nameis in the call site.Why allowlist?
Currently, REXML dropped/changed the way to add custom XPath functions in #329 that I opened.
I don't know if REXML officially supported this, it may be just a monkey patch, but perhaps it's an accidental breaking change.
If we're going to drop it forever, I think static allowlist in this PR is the simplest way.
If REXML needs to re-support custom XPath function with the old style:
def (REXML::Functions).custom_func() = 42, something needs to be done before releasing the next version. But I don't think it's easy to do it in a thread-safe way especially when the custom function touches@context.About fallback: nil
def call(name, args:, fallback: nil)can't distinguish nil fallback from unspecified fallback but it's OK.Fallback should be either bool, number, string, or NodeSet.
nilis not allowed as a value of an expression of XPath.