diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/StringUtils.java b/extractor/src/main/java/org/schabi/newpipe/extractor/utils/StringUtils.java index 3002a8d6d..9a6091a4d 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/utils/StringUtils.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/utils/StringUtils.java @@ -23,14 +23,13 @@ public final class StringUtils { } startIndex += start.length(); - int endIndex = startIndex; - while (string.charAt(endIndex) != '{') { - ++endIndex; - } + int endIndex = findNextParenthesis(string, startIndex, true); ++endIndex; int openParenthesis = 1; while (openParenthesis > 0) { + endIndex = findNextParenthesis(string, endIndex, false); + switch (string.charAt(endIndex)) { case '{': ++openParenthesis; @@ -46,4 +45,47 @@ public final class StringUtils { return string.substring(startIndex, endIndex); } + + private static int findNextParenthesis(@Nonnull final String string, + final int offset, + final boolean onlyOpen) { + boolean lastEscaped = false; + char quote = ' '; + + for (int i = offset; i < string.length(); i++) { + boolean thisEscaped = false; + final char c = string.charAt(i); + + switch (c) { + case '{': + if (quote == ' ') { + return i; + } + break; + case '}': + if (!onlyOpen && quote == ' ') { + return i; + } + break; + case '\\': + if (!lastEscaped) { + thisEscaped = true; + } + break; + case '\'': + case '"': + if (!lastEscaped) { + if (quote == ' ') { + quote = c; + } else if (quote == c) { + quote = ' '; + } + } + } + + lastEscaped = thisEscaped; + } + + return -1; + } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/utils/StringUtilsTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/utils/StringUtilsTest.java index 926a6b67b..35a680e7e 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/utils/StringUtilsTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/utils/StringUtilsTest.java @@ -58,4 +58,14 @@ public class StringUtilsTest { assertEquals(expected, substring); } + + @Test + void find_closing_with_quotes() { + final String expected = "{return \",}\\\"/\"}"; + final String string = "function(d){return \",}\\\"/\"}"; + + final String substring = matchToClosingParenthesis(string, "function(d)"); + + assertEquals(expected, substring); + } } \ No newline at end of file