diff --git a/CHANGES b/CHANGES index de2b50af28..1da06cb40d 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,10 @@ jsoup changelog * Fixed an issue where created XML documents would have an incorrect prolog. + * Fixed an issue where you could not use an attribute selector to find values containing unbalanced braces or + parentheses. + + * Fixed an issue where namespaced tags (like ) would cause Element.cssSelector() to fail. diff --git a/src/main/java/org/jsoup/parser/TokenQueue.java b/src/main/java/org/jsoup/parser/TokenQueue.java index 034a9fa1c1..47947fa516 100644 --- a/src/main/java/org/jsoup/parser/TokenQueue.java +++ b/src/main/java/org/jsoup/parser/TokenQueue.java @@ -250,7 +250,7 @@ public String chompToIgnoreCase(String seq) { /** * Pulls a balanced string off the queue. E.g. if queue is "(one (two) three) four", (,) will return "one (two) three", - * and leave " four" on the queue. Unbalanced openers and closers can be escaped (with \). Those escapes will be left + * and leave " four" on the queue. Unbalanced openers and closers can quoted (with ' or ") or escaped (with \). Those escapes will be left * in the returned string, which is suitable for regexes (where we need to preserve the escape), but unsuitable for * contains text strings; use unescape for that. * @param open opener @@ -262,11 +262,16 @@ public String chompBalanced(char open, char close) { int end = -1; int depth = 0; char last = 0; + boolean inQuote = false; do { if (isEmpty()) break; Character c = consume(); if (last == 0 || last != ESC) { + if (c.equals('\'') || c.equals('"') && c != open) + inQuote = !inQuote; + if (inQuote) + continue; if (c.equals(open)) { depth++; if (start == -1) diff --git a/src/test/java/org/jsoup/select/SelectorTest.java b/src/test/java/org/jsoup/select/SelectorTest.java index 82921427e7..c687b79728 100644 --- a/src/test/java/org/jsoup/select/SelectorTest.java +++ b/src/test/java/org/jsoup/select/SelectorTest.java @@ -661,4 +661,11 @@ public void selectClassWithSpace() { Elements subSelect = els.select(":contains(one)"); assertEquals(2, subSelect.size()); } + + @Test public void attributeWithBrackets() { + String html = "
One
Two
"; + Document doc = Jsoup.parse(html); + assertEquals("One", doc.select("div[data='End]'").first().text()); + assertEquals("Two", doc.select("div[data='[Another)]]'").first().text()); + } }