From bb4af03de421e894272b891298faa0446764a6e2 Mon Sep 17 00:00:00 2001 From: Mike Stark Date: Thu, 10 Dec 2015 10:44:19 -0500 Subject: [PATCH] [dice] Handle negative numbers and uppercase letters. First, add case-insensitivity to the "d" and "v" letters in the input regex by capturing [dD] and [vV] in regexes. Next, make sure we can handle negative numbers properly by capturing a possible "-" in front of any numbers. If dice_num or dice_type ends up negative, abort _roll_dice early (dice_type already had a negative check that wasn't being hit because "-" wasn't captured). --- sopel/modules/dice.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/sopel/modules/dice.py b/sopel/modules/dice.py index 026a52448b..ab4f62ff8f 100644 --- a/sopel/modules/dice.py +++ b/sopel/modules/dice.py @@ -124,10 +124,10 @@ def get_number_of_faces(self): def _roll_dice(bot, dice_expression): result = re.search( r""" - (?P\d*) + (?P-?\d*) d - (?P\d+) - (v(?P\d+))? + (?P-?\d+) + (v(?P-?\d+))? $""", dice_expression, re.IGNORECASE | re.VERBOSE) @@ -140,6 +140,11 @@ def _roll_dice(bot, dice_expression): bot.reply("I don't have any dice with %d sides. =(" % dice_type) return None # Signal there was a problem + # Can't roll a negative number of dice. + if dice_num < 0: + bot.reply("I'd rather not roll a negative amount of dice. =(") + return None # Signal there was a problem + # Upper limit for dice should be at most a million. Creating a dict with # more than a million elements already takes a noticeable amount of time # on a fast computer and ~55kB of memory. @@ -176,7 +181,7 @@ def roll(bot, trigger): """ # This regexp is only allowed to have one captured group, because having # more would alter the output of re.findall. - dice_regexp = r"\d*d\d+(?:v\d+)?" + dice_regexp = r"-?\d*[dD]-?\d+(?:[vV]-?\d+)?" # Get a list of all dice expressions, evaluate them and then replace the # expressions in the original string with the results. Replacing is done @@ -184,7 +189,7 @@ def roll(bot, trigger): if not trigger.group(2): return bot.reply("No dice to roll.") arg_str = trigger.group(2) - dice_expressions = re.findall(dice_regexp, arg_str, re.IGNORECASE) + dice_expressions = re.findall(dice_regexp, arg_str) arg_str = arg_str.replace("%", "%%") arg_str = re.sub(dice_regexp, "%s", arg_str)