From 0e48ae679abc0937b4aad583b1b29ee0b3e3eb15 Mon Sep 17 00:00:00 2001 From: Numerlor <25886452+Numerlor@users.noreply.github.com> Date: Wed, 9 Dec 2020 13:40:01 +0100 Subject: Improve handling of strings Previously the code assumed ' and " can be used interchangeably, and strings that were inside of brackets were ignored for depth but their contents weren't causing strings like "ab[cd" to increase the depth --- bot/exts/info/doc/_parsing.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/bot/exts/info/doc/_parsing.py b/bot/exts/info/doc/_parsing.py index 418405ca9..e6103dde2 100644 --- a/bot/exts/info/doc/_parsing.py +++ b/bot/exts/info/doc/_parsing.py @@ -56,6 +56,15 @@ _BRACKET_PAIRS = { } +def _is_closing_quote(search_string: str, index: int) -> bool: + """Check whether the quote at `index` inside `search_string` can be a closing quote.""" + if search_string[index - 1] != "\\": + return True + elif search_string[index - 2] == "\\": + return True + return False + + def _split_parameters(parameters_string: str) -> List[str]: """ Split parameters of a signature into individual parameter strings on commas. @@ -67,9 +76,11 @@ def _split_parameters(parameters_string: str) -> List[str]: depth = 0 expected_end = None current_search = None + quote_character = None - for index, character in enumerate(parameters_string): - if character in _BRACKET_PAIRS: + enumerated_string = enumerate(parameters_string) + for index, character in enumerated_string: + if quote_character is None and character in _BRACKET_PAIRS: if current_search is None: current_search = character expected_end = _BRACKET_PAIRS[character] @@ -77,12 +88,22 @@ def _split_parameters(parameters_string: str) -> List[str]: depth += 1 elif character in {"'", '"'}: - if depth == 0: + if current_search is not None: + # We're currently searching for a bracket, skip all characters that belong to the string + # to avoid false positives of closing brackets + quote_character = character + for index, character in enumerated_string: + if character == quote_character and _is_closing_quote(parameters_string, index): + break + + elif depth == 0: depth += 1 - elif parameters_string[index-1] != "\\": - depth -= 1 - elif parameters_string[index-2] == "\\": - depth -= 1 + quote_character = character + elif character == quote_character: + if _is_closing_quote(parameters_string, index): + depth -= 1 + if depth == 0: + quote_character = None elif character == expected_end: depth -= 1 -- cgit v1.2.3