# Buggy code
def PyParseRangeCheck(lower_bound, upper_bound):
    """Verify that a number is within a defined range.

    This is a callback method for pyparsing setParseAction
    that verifies that a read number is within a certain range.

    To use this method it needs to be defined as a callback method
    in setParseAction with the upper and lower bound set as parameters.

    Args:
      lower_bound: An integer representing the lower bound of the range.
      upper_bound: An integer representing the upper bound of the range.

    Returns:
      A callback method that can be used by pyparsing setParseAction.
    """

    def CheckRange(unused_string, unused_location, tokens):
        """Parse the arguments."""
        try:
            check_number = tokens[0]
        except IndexError:
            check_number = -1

        if check_number < lower_bound:
            raise pyparsing.ParseException(
                "Value: {0:d} precedes lower bound: {1:d}".format(
                    check_number, lower_bound
                )
            )

        if check_number > upper_bound:
            raise pyparsing.ParseException(
                "Value: {0:d} exceeds upper bound: {1:d}".format(
                    check_number, upper_bound
                )
            )

    # Since callback methods for pyparsing need to accept certain parameters
    # and there is no way to define conditions, like upper and lower bounds
    # we need to return here a method that accepts those pyparsing parameters.
    return CheckRange


# Traceback (UnicodeDecodeError)
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/plaso/engine/worker.py", line 169, in _ParseFileEntryWithParser
parser_object.UpdateChainAndParse(self._parser_mediator)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/interface.py", line 72, in UpdateChainAndParse
self.Parse(parser_mediator, **kwargs)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/interface.py", line 256, in Parse
self.ParseFileObject(parser_mediator, file_object, **kwargs)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/text_parser.py", line 160, in ParseFileObject
_ = self.NextToken()
File "/usr/lib/python2.7/dist-packages/plaso/lib/lexer.py", line 191, in NextToken
return Lexer.NextToken(self)
File "/usr/lib/python2.7/dist-packages/plaso/lib/lexer.py", line 99, in NextToken
possible_next_state = callback(string=m.group(0), match=m)
File "/usr/lib/python2.7/dist-packages/plaso/parsers/text_parser.py", line 119, in ParseIncomplete
self.attributes['body'] += match.group(0)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)

# Fixed code
def PyParseRangeCheck(lower_bound, upper_bound):
    """Verify that a number is within a defined range.

    This is a callback method for pyparsing setParseAction
    that verifies that a read number is within a certain range.

    To use this method it needs to be defined as a callback method
    in setParseAction with the upper and lower bound set as parameters.

    Args:
      lower_bound: an integer representing the lower bound of the range.
      upper_bound: an integer representing the upper bound of the range.

    Returns:
      A callback method that can be used by pyparsing setParseAction.
    """

    def CheckRange(unused_string, unused_location, tokens):
        """Parse the arguments."""
        try:
            check_number = tokens[0]
        except IndexError:
            check_number = -1

        if check_number < lower_bound:
            raise pyparsing.ParseException(
                "Value: {0:d} precedes lower bound: {1:d}".format(
                    check_number, lower_bound
                )
            )

        if check_number > upper_bound:
            raise pyparsing.ParseException(
                "Value: {0:d} exceeds upper bound: {1:d}".format(
                    check_number, upper_bound
                )
            )

    # Since callback methods for pyparsing need to accept certain parameters
    # and there is no way to define conditions, like upper and lower bounds
    # we need to return here a method that accepts those pyparsing parameters.
    return CheckRange