Skip to content

Commit a0537c7

Browse files
committed
Handle escaped characters in consumeSubQuery
Fixes #2146
1 parent 970403c commit a0537c7

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
e.g.: `h1:has(+h2)`). [2137](https://github.com/jhy/jsoup/issues/2137)
4141
* The `:empty` selector incorrectly matched elements that started with a blank text node and were followed by
4242
non-empty nodes, due to an incorrect short-circuit. [2130](https://github.com/jhy/jsoup/issues/2130)
43+
* `Element.cssSelector()` would fail with "Did not find balanced marker" when building a selector for elements that had a `(` or `[` in their class names. And selectors with those characters escaped would not match as expected. [2146](https://github.com/jhy/jsoup/issues/2146)
4344
* Fuzz: a Stack Overflow exception could occur when resolving a crafted `<base href>` URL, in the normalizing regex.
4445
[2165](https://github.com/jhy/jsoup/issues/2165)
4546

src/main/java/org/jsoup/select/QueryParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,10 @@ private String consumeSubQuery() {
158158
sq.append("(").append(tq.chompBalanced('(', ')')).append(")");
159159
else if (tq.matches("["))
160160
sq.append("[").append(tq.chompBalanced('[', ']')).append("]");
161-
else
161+
else if (tq.matches("\\")) { // bounce over escapes
162+
sq.append(tq.consume());
163+
if (!tq.isEmpty()) sq.append(tq.consume());
164+
} else
162165
sq.append(tq.consume());
163166
}
164167
return StringUtil.releaseBuilder(sq);

src/test/java/org/jsoup/nodes/ElementTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,6 +2612,30 @@ void prettySerializationRoundTrips(Document.OutputSettings settings) {
26122612
assertEquals(element, elements.first());
26132613
}
26142614

2615+
@Test void cssSelectorWithBracket() {
2616+
// https://github.com/jhy/jsoup/issues/2146
2617+
Document doc = Jsoup.parse("<div class='a[foo]'>One</div><div class='b[bar]'>Two</div>");
2618+
Element div = doc.expectFirst("div");
2619+
String selector = div.cssSelector();
2620+
assertEquals("html > body > div.a\\[foo\\]", selector); // would fail with "Did not find balanced marker", consumeSubquery was not handling escapes
2621+
2622+
Elements selected = doc.select(selector);
2623+
assertEquals(1, selected.size());
2624+
assertEquals(selected.first(), div);
2625+
}
2626+
2627+
@Test void cssSelectorUnbalanced() {
2628+
// https://github.com/jhy/jsoup/issues/2146
2629+
Document doc = Jsoup.parse("<div class='a(foo'>One</div><div class='a-bar'>Two</div>");
2630+
Element div = doc.expectFirst("div");
2631+
String selector = div.cssSelector();
2632+
assertEquals("html > body > div.a\\(foo", selector);
2633+
2634+
Elements selected = doc.select(selector);
2635+
assertEquals(1, selected.size());
2636+
assertEquals(selected.first(), div);
2637+
}
2638+
26152639
@Test void orphanSiblings() {
26162640
Element el = new Element("div");
26172641
assertEquals(0, el.siblingElements().size());

0 commit comments

Comments
 (0)