From 34d444e56372e0231a99504397408aeb77d73fd2 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Mon, 19 Nov 2012 23:35:05 +0100 Subject: [PATCH] models: Don't allow model deserialization to override methods --- mopidy/models.py | 2 +- tests/models_test.py | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/mopidy/models.py b/mopidy/models.py index b8f8b8b2..901d637b 100644 --- a/mopidy/models.py +++ b/mopidy/models.py @@ -14,7 +14,7 @@ class ImmutableObject(object): def __init__(self, *args, **kwargs): for key, value in kwargs.items(): - if not hasattr(self, key): + if not hasattr(self, key) or callable(getattr(self, key)): raise TypeError( '__init__() got an unexpected keyword argument "%s"' % key) diff --git a/tests/models_test.py b/tests/models_test.py index 21ad7ead..ed17cef3 100644 --- a/tests/models_test.py +++ b/tests/models_test.py @@ -89,12 +89,33 @@ class ArtistTest(unittest.TestCase): {'__type__': 'Artist', 'uri': 'uri', 'name': 'name'}, Artist(uri='uri', name='name').serialize()) - def test_to_json_and_Back(self): + def test_to_json_and_back(self): artist1 = Artist(uri='uri', name='name') serialized = json.dumps(artist1, cls=ModelJSONEncoder) artist2 = json.loads(serialized, object_hook=model_json_decoder) self.assertEqual(artist1, artist2) + def test_to_json_and_back_with_unknown_field(self): + artist = Artist(uri='uri', name='name').serialize() + artist['foo'] = 'foo' + serialized = json.dumps(artist) + test = lambda: json.loads(serialized, object_hook=model_json_decoder) + self.assertRaises(TypeError, test) + + def test_to_json_and_back_with_field_matching_method(self): + artist = Artist(uri='uri', name='name').serialize() + artist['copy'] = 'foo' + serialized = json.dumps(artist) + test = lambda: json.loads(serialized, object_hook=model_json_decoder) + self.assertRaises(TypeError, test) + + def test_to_json_and_back_with_field_matching_internal_field(self): + artist = Artist(uri='uri', name='name').serialize() + artist['__mro__'] = 'foo' + serialized = json.dumps(artist) + test = lambda: json.loads(serialized, object_hook=model_json_decoder) + self.assertRaises(TypeError, test) + def test_eq_name(self): artist1 = Artist(name='name') artist2 = Artist(name='name')