Avoid another MemoryError

This commit is contained in:
Lonami Exo 2020-02-28 10:42:23 +01:00
parent 673a2ecd5d
commit e451abbf20
5 changed files with 30 additions and 2 deletions

View File

@ -186,6 +186,19 @@ class TLObject:
return json.dumps(d, default=default, **kwargs) return json.dumps(d, default=default, **kwargs)
def __bytes__(self): def __bytes__(self):
try:
return self._bytes()
except AttributeError:
# If a type is wrong (e.g. expected `TLObject` but `int` was
# provided) it will try to access `._bytes()`, which will fail
# with `AttributeError`. This occurs in fact because the type
# was wrong, so raise the correct error type.
raise TypeError('a TLObject was expected but found something else')
# Custom objects will call `(...)._bytes()` and not `bytes(...)` so that
# if the wrong type is used (e.g. `int`) we won't try allocating a huge
# amount of data, which would cause a `MemoryError`.
def _bytes(self):
raise NotImplementedError raise NotImplementedError
@classmethod @classmethod

View File

@ -330,7 +330,7 @@ def _write_to_dict(tlobject, builder):
def _write_to_bytes(tlobject, builder): def _write_to_bytes(tlobject, builder):
builder.writeln('def __bytes__(self):') builder.writeln('def _bytes(self):')
# Some objects require more than one flag parameter to be set # Some objects require more than one flag parameter to be set
# at the same time. In this case, add an assertion. # at the same time. In this case, add an assertion.
@ -509,7 +509,7 @@ def _write_arg_to_bytes(builder, arg, args, name=None):
else: else:
# Else it may be a custom type # Else it may be a custom type
builder.write('bytes({})', name) builder.write('{}._bytes()', name)
# If the type is not boxed (i.e. starts with lowercase) we should # If the type is not boxed (i.e. starts with lowercase) we should
# not serialize the constructor ID (so remove its first 4 bytes). # not serialize the constructor ID (so remove its first 4 bytes).

View File

@ -1,6 +1,8 @@
import io import io
import pathlib import pathlib
import pytest
from telethon import utils from telethon import utils
from telethon.tl.types import ( from telethon.tl.types import (
MessageMediaGame, Game, PhotoEmpty MessageMediaGame, Game, PhotoEmpty

View File

View File

@ -0,0 +1,13 @@
import pytest
from telethon.tl import types, functions
def test_nested_invalid_serialization():
large_long = 2**62
request = functions.account.SetPrivacyRequest(
key=types.InputPrivacyKeyChatInvite(),
rules=[types.InputPrivacyValueDisallowUsers(users=[large_long])]
)
with pytest.raises(TypeError):
bytes(request)