Fix number parsing bugs
authorJakob Cornell <jakob+gpg@jcornell.net>
Sun, 6 Nov 2022 16:21:26 +0000 (10:21 -0600)
committerJakob Cornell <jakob+gpg@jcornell.net>
Sun, 6 Nov 2022 16:34:07 +0000 (10:34 -0600)
Previously we could accept counts with invalid digit grouping, and we wouldn't always strike rejected updates that
started with a digit.

strikebot/src/strikebot/updates.py

index b82a7914c22fe31794712cc5dbeaff98520d3885..48a1ee09835616477e042ff860b9c48a3f14c21c 100644 (file)
@@ -108,16 +108,16 @@ def _parse_from_lines(lines: list[str], curr_count: Optional[int], bot_user: str
                                raw_digits = raw_digits.removeprefix("0").removeprefix(sep or "")
 
                        parts = raw_digits.split(sep) if sep else [raw_digits]
+                       all_parts_valid = (
+                               sep is None
+                               or (
+                                       1 <= len(parts[0]) <= 3
+                                       and all(len(p) == 3 for p in parts[1:])
+                               )
+                       )
                        lone = len(lines) == 1 and (not post or post.isspace())
                        typo = False
                        if lone:
-                               all_parts_valid = (
-                                       sep is None
-                                       or (
-                                               1 <= len(parts[0]) <= 3
-                                               and all(len(p) == 3 for p in parts[1:])
-                                       )
-                               )
                                if match["v"] and len(parts) == 1 and len(parts[0]) <= 2:
                                        # failed paste of leading digits
                                        typo = True
@@ -143,6 +143,7 @@ def _parse_from_lines(lines: list[str], curr_count: Optional[int], bot_user: str
                                count_attempt = True
                                deletable = lone
                        else:
+                               groups_okay = True
                                if curr_count is not None and sep and sep.isspace():
                                        # Presume that the intended count consists of as many valid digit groups as necessary to match the
                                        # number of digits in the expected count, if possible.
@@ -164,6 +165,7 @@ def _parse_from_lines(lines: list[str], curr_count: Optional[int], bot_user: str
                                        lone = lone and len(use_parts) == len(parts)
                                else:
                                        # current count is unknown or no separator was used
+                                       groups_okay = all_parts_valid
                                        use_parts = parts
 
                                digits = "".join(use_parts)
@@ -173,12 +175,20 @@ def _parse_from_lines(lines: list[str], curr_count: Optional[int], bot_user: str
                                        and abs(number - curr_count) <= 25
                                        and _is_special_number(number)
                                )
-                               deletable = lone and not special
-                               if len(use_parts) == len(parts) and post and not post[0].isspace():
-                                       count_attempt = curr_count is not None and abs(number - curr_count) <= 25
-                                       number = None
+                               if groups_okay:
+                                       deletable = lone and not special
+                                       if len(use_parts) == len(parts) and post and not post[0].isspace():
+                                               count_attempt = curr_count is not None and abs(number - curr_count) <= 25
+                                               number = None
+                                       else:
+                                               count_attempt = True
                                else:
                                        count_attempt = True
+                                       deletable = False
+
+                       if first[0].isdigit() and not count_attempt:
+                               count_attempt = True
+                               deletable = False
                else:
                        # no count attempt found
                        number = None