Skip to content

Commit 0fb5541

Browse files
authored
backport: fix(css-selector): default XML namespace should not be applied to wildcard (#3414)
Backport of #3413 to v1.18.x
2 parents 3b28b49 + 8ef2e91 commit 0fb5541

File tree

5 files changed

+52
-37
lines changed

5 files changed

+52
-37
lines changed

Diff for: .github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ jobs:
9797
outputs:
9898
# these are usually the same, but are different once we get to ruby release candidates
9999
setup_ruby: "['3.1', '3.2', '3.3', '3.4']"
100-
setup_ruby_win: "['3.1', '3.2', '3.3', 'head']"
100+
setup_ruby_win: "['3.1', '3.2', '3.3', '3.4']"
101101
image_tag: "['3.1', '3.2', '3.3', '3.4']"
102102
runs-on: ubuntu-latest
103103
steps:

Diff for: Gemfile

+2-4
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ end
3333
# If Psych doesn't build, you can disable this group locally by running
3434
# `bundle config set --local without rdoc`
3535
# Then re-run `bundle install`.
36-
unless RUBY_PLATFORM == "java" # see #3391 and https://github.com/jruby/jruby/issues/7262
37-
group :rdoc do
38-
gem "rdoc", "6.10.0"
39-
end
36+
group :rdoc do
37+
gem "rdoc", "6.10.0" unless RUBY_PLATFORM == "java" || ENV["CI"]
4038
end

Diff for: lib/nokogiri/css/xpath_visitor.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ def visit_element_name(node)
283283
else
284284
node.value.join(":")
285285
end
286-
elsif @namespaces&.key?("xmlns") # apply the default namespace if it's declared
286+
elsif node.value.first != "*" && @namespaces&.key?("xmlns")
287+
# apply the default namespace (if one is present) to a non-wildcard selector
287288
"xmlns:#{node.value.first}"
288289
else
289290
node.value.first

Diff for: scripts/test-gem-install

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ popd
2828
# 2.3.21 because https://github.com/rubygems/rubygems/issues/5914
2929
# 2.3.22 because https://github.com/rubygems/rubygems/issues/5940
3030
gem install bundler -v "~> 2.2, != 2.3.21, != 2.3.22"
31+
bundle config set --local without rdoc
3132
bundle install --local || bundle install
3233

3334
rm -rf lib ext # ensure we don't use the local files

Diff for: test/css/test_xpath_visitor.rb

+46-31
Original file line numberDiff line numberDiff line change
@@ -143,53 +143,68 @@ def visit_pseudo_class_aaron(node)
143143
)
144144
end
145145

146-
it "# id" do
147-
assert_xpath("//*[@id='foo']", "#foo")
148-
assert_xpath("//*[@id='escape:needed,']", "#escape\\:needed\\,")
149-
assert_xpath("//*[@id='escape:needed,']", '#escape\3Aneeded\,')
150-
assert_xpath("//*[@id='escape:needed,']", '#escape\3A needed\2C')
151-
assert_xpath("//*[@id='escape:needed']", '#escape\00003Aneeded')
152-
end
153-
154-
describe "attribute" do
155-
it "basic mechanics" do
156-
assert_xpath("//h1[@a='Tender Lovemaking']", "h1[a='Tender Lovemaking']")
157-
assert_xpath("//h1[@a]", "h1[a]")
158-
assert_xpath(%q{//h1[@a='gnewline\n']}, "h1[a='\\gnew\\\nline\\\\n']")
159-
assert_xpath("//h1[@a='test']", %q{h1[a=\te\st]})
160-
end
161-
162-
it "parses leading @ (extended-syntax)" do
163-
assert_xpath("//a[@id='Boing']", "a[@id='Boing']")
164-
assert_xpath("//a[@id='Boing']", "a[@id = 'Boing']")
165-
assert_xpath("//a[@id='Boing']//div", "a[@id='Boing'] div")
146+
describe "namespaces" do
147+
let(:ns) do
148+
{
149+
"xmlns" => "http://default.example.com/",
150+
"hoge" => "http://hoge.example.com/",
151+
}
166152
end
167153

168-
it "namespacing" do
154+
it "basic mechanics" do
169155
assert_xpath("//a[@flavorjones:href]", "a[flavorjones|href]")
170156
assert_xpath("//a[@href]", "a[|href]")
171157
assert_xpath("//*[@flavorjones:href]", "*[flavorjones|href]")
158+
end
172159

173-
ns = {
174-
"xmlns" => "http://default.example.com/",
175-
"hoge" => "http://hoge.example.com/",
176-
}
177-
178-
# An intentionally-empty namespace means "don't use the default xmlns"
179-
assert_equal(["//a"], Nokogiri::CSS.xpath_for("|a", ns: ns, cache: false))
180-
181-
# The default namespace is not applied to attributes (just elements)
160+
it "default namespace is applied to elements but not attributes" do
182161
assert_equal(
183162
["//xmlns:a[@class='bar']"],
184163
Nokogiri::CSS.xpath_for("a[class='bar']", ns: ns, cache: false),
185164
)
165+
end
186166

187-
# We can explicitly apply a namespace to an attribue
167+
it "default namespace is not applied to wildcard selectors" do
168+
assert_equal(
169+
["//xmlns:a//*"],
170+
Nokogiri::CSS.xpath_for("a *", ns: ns, cache: false),
171+
)
172+
end
173+
174+
it "intentionally-empty namespace omits the default xmlns" do
175+
# An intentionally-empty namespace
176+
assert_equal(["//a"], Nokogiri::CSS.xpath_for("|a", ns: ns, cache: false))
177+
end
178+
179+
it "explicit namespaces are applied to attributes" do
188180
assert_equal(
189181
["//xmlns:a[@hoge:class='bar']"],
190182
Nokogiri::CSS.xpath_for("a[hoge|class='bar']", ns: ns, cache: false),
191183
)
192184
end
185+
end
186+
187+
describe "attribute" do
188+
it "basic mechanics" do
189+
assert_xpath("//h1[@a='Tender Lovemaking']", "h1[a='Tender Lovemaking']")
190+
assert_xpath("//h1[@a]", "h1[a]")
191+
assert_xpath(%q{//h1[@a='gnewline\n']}, "h1[a='\\gnew\\\nline\\\\n']")
192+
assert_xpath("//h1[@a='test']", %q{h1[a=\te\st]})
193+
end
194+
195+
it "#id escaping" do
196+
assert_xpath("//*[@id='foo']", "#foo")
197+
assert_xpath("//*[@id='escape:needed,']", "#escape\\:needed\\,")
198+
assert_xpath("//*[@id='escape:needed,']", '#escape\3Aneeded\,')
199+
assert_xpath("//*[@id='escape:needed,']", '#escape\3A needed\2C')
200+
assert_xpath("//*[@id='escape:needed']", '#escape\00003Aneeded')
201+
end
202+
203+
it "parses leading @ (extended-syntax)" do
204+
assert_xpath("//a[@id='Boing']", "a[@id='Boing']")
205+
assert_xpath("//a[@id='Boing']", "a[@id = 'Boing']")
206+
assert_xpath("//a[@id='Boing']//div", "a[@id='Boing'] div")
207+
end
193208

194209
it "rhs with quotes" do
195210
assert_xpath(%q{//h1[@a="'"]}, %q{h1[a="'"]})

0 commit comments

Comments
 (0)