prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Log topic and data allow byte array longer than 32 bytes.
  ### What's your issue about?
  When packing data/topic for log, if the the actual argument is a byte array variable, there is no check for the actual length of the variable.
  e.g.,
  ```
  MyLog: __log__({arg1: indexed(bytes<=2000)})
  
  @public
  def foo():
      a: bytes<=100
      log.MyLog(a)
  ```
  This program should be rejected by is not.
  
  ### How can it be fixed?
  
  Add check in event_sig, pack_arg_by_32 and pack_logging_topic.
  
  #### Cute Animal Picture
  ![image](https://user-images.githubusercontent.com/5641590/33631206-753fab08-d9cf-11e7-89b4-f2d71f844453.png)
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `viper/signatures/event_signature.py`
  Content:
  ```
  1 from viper.types import get_size_of_type, canonicalize_type, parse_type, \
  2     ByteArrayType
  3 from viper.utils import sha3, is_varname_valid, bytes_to_int
  4 import ast
  5 from viper.function_signature import VariableRecord
  6 from viper.exceptions import InvalidTypeException, VariableDeclarationException
  7 
  8 
  9 # Event signature object
  10 class EventSignature():
  11     def __init__(self, name, args, indexed_list, event_id, sig):
  12         self.name = name
  13         self.args = args
  14         self.indexed_list = indexed_list
  15         self.sig = sig
  16         self.event_id = event_id
  17 
  18     # Get a signature from an event declaration
  19     @classmethod
  20     def from_declaration(cls, code):
  21         name = code.target.id
  22         pos = 0
  23         # Determine the arguments, expects something of the form def foo(arg1: num, arg2: num ...
  24         args = []
  25         indexed_list = []
  26         topics_count = 1
  27         if code.annotation.args:
  28             keys = code.annotation.args[0].keys
  29             values = code.annotation.args[0].values
  30             for i in range(len(keys)):
  31                 typ = values[i]
  32                 arg = keys[i].id
  33                 if isinstance(typ, ast.Call):
  34                     # Check to see if argument is a topic
  35                     if typ.func.id == 'indexed':
  36                         typ = values[i].args[0]
  37                         indexed_list.append(True)
  38                         topics_count += 1
  39                     else:
  40                         raise VariableDeclarationException("Only indexed keyword is allowed", arg)
  41                 else:
  42                     if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:
  43                         raise VariableDeclarationException("Can only log a maximum of 32 bytes at a time.")
  44                     indexed_list.append(False)
  45                 if topics_count > 4:
  46                     raise VariableDeclarationException("Maximum of 3 topics {} given".format(topics_count - 1), arg)
  47                 if not isinstance(arg, str):
  48                     raise VariableDeclarationException("Argument name invalid", arg)
  49                 if not typ:
  50                     raise InvalidTypeException("Argument must have type", arg)
  51                 if not is_varname_valid(arg):
  52                     raise VariableDeclarationException("Argument name invalid or reserved: " + arg, arg)
  53                 if arg in (x.name for x in args):
  54                     raise VariableDeclarationException("Duplicate function argument name: " + arg, arg)
  55                 parsed_type = parse_type(typ, None)
  56                 args.append(VariableRecord(arg, pos, parsed_type, False))
  57                 if isinstance(parsed_type, ByteArrayType):
  58                     pos += 32
  59                 else:
  60                     pos += get_size_of_type(parsed_type) * 32
  61         sig = name + '(' + ','.join([canonicalize_type(arg.typ, True) for arg in args]) + ')'
  62         event_id = bytes_to_int(sha3(bytes(sig, 'utf-8')))
  63         return cls(name, args, indexed_list, event_id, sig)
  64 
  65     def to_abi_dict(self):
  66         return {
  67             "name": self.name,
  68             "inputs": [{"type": canonicalize_type(arg.typ, True), "name": arg.name, "indexed": self.indexed_list[pos]} for pos, arg in enumerate(self.args)] if self.args else [],
  69             "anonymous": False,
  70             "type": "event"
  71         }
  72
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/viper/signatures/event_signature.py b/viper/signatures/event_signature.py
  --- a/viper/signatures/event_signature.py
  +++ b/viper/signatures/event_signature.py
  @@ -39,9 +39,9 @@
                       else:
                           raise VariableDeclarationException("Only indexed keyword is allowed", arg)
                   else:
  -                    if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:
  -                        raise VariableDeclarationException("Can only log a maximum of 32 bytes at a time.")
                       indexed_list.append(False)
  +                if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:
  +                    raise VariableDeclarationException("Can only log a maximum of 32 bytes at a time.")
                   if topics_count > 4:
                       raise VariableDeclarationException("Maximum of 3 topics {} given".format(topics_count - 1), arg)
                   if not isinstance(arg, str):
  
verification_info: {"golden_diff": "diff --git a/viper/signatures/event_signature.py b/viper/signatures/event_signature.py\n--- a/viper/signatures/event_signature.py\n+++ b/viper/signatures/event_signature.py\n@@ -39,9 +39,9 @@\n                     else:\n                         raise VariableDeclarationException(\"Only indexed keyword is allowed\", arg)\n                 else:\n-                    if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:\n-                        raise VariableDeclarationException(\"Can only log a maximum of 32 bytes at a time.\")\n                     indexed_list.append(False)\n+                if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:\n+                    raise VariableDeclarationException(\"Can only log a maximum of 32 bytes at a time.\")\n                 if topics_count > 4:\n                     raise VariableDeclarationException(\"Maximum of 3 topics {} given\".format(topics_count - 1), arg)\n                 if not isinstance(arg, str):\n", "issue": "Log topic and data allow byte array longer than 32 bytes.\n### What's your issue about?\r\nWhen packing data/topic for log, if the the actual argument is a byte array variable, there is no check for the actual length of the variable.\r\ne.g.,\r\n```\r\nMyLog: __log__({arg1: indexed(bytes<=2000)})\r\n\r\n@public\r\ndef foo():\r\n    a: bytes<=100\r\n    log.MyLog(a)\r\n```\r\nThis program should be rejected by is not.\r\n\r\n### How can it be fixed?\r\n\r\nAdd check in event_sig, pack_arg_by_32 and pack_logging_topic.\r\n\r\n#### Cute Animal Picture\r\n![image](https://user-images.githubusercontent.com/5641590/33631206-753fab08-d9cf-11e7-89b4-f2d71f844453.png)\r\n\r\n\n", "before_files": [{"content": "from viper.types import get_size_of_type, canonicalize_type, parse_type, \\\n    ByteArrayType\nfrom viper.utils import sha3, is_varname_valid, bytes_to_int\nimport ast\nfrom viper.function_signature import VariableRecord\nfrom viper.exceptions import InvalidTypeException, VariableDeclarationException\n\n\n# Event signature object\nclass EventSignature():\n    def __init__(self, name, args, indexed_list, event_id, sig):\n        self.name = name\n        self.args = args\n        self.indexed_list = indexed_list\n        self.sig = sig\n        self.event_id = event_id\n\n    # Get a signature from an event declaration\n    @classmethod\n    def from_declaration(cls, code):\n        name = code.target.id\n        pos = 0\n        # Determine the arguments, expects something of the form def foo(arg1: num, arg2: num ...\n        args = []\n        indexed_list = []\n        topics_count = 1\n        if code.annotation.args:\n            keys = code.annotation.args[0].keys\n            values = code.annotation.args[0].values\n            for i in range(len(keys)):\n                typ = values[i]\n                arg = keys[i].id\n                if isinstance(typ, ast.Call):\n                    # Check to see if argument is a topic\n                    if typ.func.id == 'indexed':\n                        typ = values[i].args[0]\n                        indexed_list.append(True)\n                        topics_count += 1\n                    else:\n                        raise VariableDeclarationException(\"Only indexed keyword is allowed\", arg)\n                else:\n                    if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:\n                        raise VariableDeclarationException(\"Can only log a maximum of 32 bytes at a time.\")\n                    indexed_list.append(False)\n                if topics_count > 4:\n                    raise VariableDeclarationException(\"Maximum of 3 topics {} given\".format(topics_count - 1), arg)\n                if not isinstance(arg, str):\n                    raise VariableDeclarationException(\"Argument name invalid\", arg)\n                if not typ:\n                    raise InvalidTypeException(\"Argument must have type\", arg)\n                if not is_varname_valid(arg):\n                    raise VariableDeclarationException(\"Argument name invalid or reserved: \" + arg, arg)\n                if arg in (x.name for x in args):\n                    raise VariableDeclarationException(\"Duplicate function argument name: \" + arg, arg)\n                parsed_type = parse_type(typ, None)\n                args.append(VariableRecord(arg, pos, parsed_type, False))\n                if isinstance(parsed_type, ByteArrayType):\n                    pos += 32\n                else:\n                    pos += get_size_of_type(parsed_type) * 32\n        sig = name + '(' + ','.join([canonicalize_type(arg.typ, True) for arg in args]) + ')'\n        event_id = bytes_to_int(sha3(bytes(sig, 'utf-8')))\n        return cls(name, args, indexed_list, event_id, sig)\n\n    def to_abi_dict(self):\n        return {\n            \"name\": self.name,\n            \"inputs\": [{\"type\": canonicalize_type(arg.typ, True), \"name\": arg.name, \"indexed\": self.indexed_list[pos]} for pos, arg in enumerate(self.args)] if self.args else [],\n            \"anonymous\": False,\n            \"type\": \"event\"\n        }\n", "path": "viper/signatures/event_signature.py"}], "after_files": [{"content": "from viper.types import get_size_of_type, canonicalize_type, parse_type, \\\n    ByteArrayType\nfrom viper.utils import sha3, is_varname_valid, bytes_to_int\nimport ast\nfrom viper.function_signature import VariableRecord\nfrom viper.exceptions import InvalidTypeException, VariableDeclarationException\n\n\n# Event signature object\nclass EventSignature():\n    def __init__(self, name, args, indexed_list, event_id, sig):\n        self.name = name\n        self.args = args\n        self.indexed_list = indexed_list\n        self.sig = sig\n        self.event_id = event_id\n\n    # Get a signature from an event declaration\n    @classmethod\n    def from_declaration(cls, code):\n        name = code.target.id\n        pos = 0\n        # Determine the arguments, expects something of the form def foo(arg1: num, arg2: num ...\n        args = []\n        indexed_list = []\n        topics_count = 1\n        if code.annotation.args:\n            keys = code.annotation.args[0].keys\n            values = code.annotation.args[0].values\n            for i in range(len(keys)):\n                typ = values[i]\n                arg = keys[i].id\n                if isinstance(typ, ast.Call):\n                    # Check to see if argument is a topic\n                    if typ.func.id == 'indexed':\n                        typ = values[i].args[0]\n                        indexed_list.append(True)\n                        topics_count += 1\n                    else:\n                        raise VariableDeclarationException(\"Only indexed keyword is allowed\", arg)\n                else:\n                    indexed_list.append(False)\n                if hasattr(typ, 'left') and typ.left.id == 'bytes' and typ.comparators[0].n > 32:\n                    raise VariableDeclarationException(\"Can only log a maximum of 32 bytes at a time.\")\n                if topics_count > 4:\n                    raise VariableDeclarationException(\"Maximum of 3 topics {} given\".format(topics_count - 1), arg)\n                if not isinstance(arg, str):\n                    raise VariableDeclarationException(\"Argument name invalid\", arg)\n                if not typ:\n                    raise InvalidTypeException(\"Argument must have type\", arg)\n                if not is_varname_valid(arg):\n                    raise VariableDeclarationException(\"Argument name invalid or reserved: \" + arg, arg)\n                if arg in (x.name for x in args):\n                    raise VariableDeclarationException(\"Duplicate function argument name: \" + arg, arg)\n                parsed_type = parse_type(typ, None)\n                args.append(VariableRecord(arg, pos, parsed_type, False))\n                if isinstance(parsed_type, ByteArrayType):\n                    pos += 32\n                else:\n                    pos += get_size_of_type(parsed_type) * 32\n        sig = name + '(' + ','.join([canonicalize_type(arg.typ, True) for arg in args]) + ')'\n        event_id = bytes_to_int(sha3(bytes(sig, 'utf-8')))\n        return cls(name, args, indexed_list, event_id, sig)\n\n    def to_abi_dict(self):\n        return {\n            \"name\": self.name,\n            \"inputs\": [{\"type\": canonicalize_type(arg.typ, True), \"name\": arg.name, \"indexed\": self.indexed_list[pos]} for pos, arg in enumerate(self.args)] if self.args else [],\n            \"anonymous\": False,\n            \"type\": \"event\"\n        }\n", "path": "viper/signatures/event_signature.py"}]}