diff --git a/src/sentry/db/models/fields/encrypted.py b/src/sentry/db/models/fields/encrypted.py index ca605cef6ca2fe..256ddfd0d4aa3a 100644 --- a/src/sentry/db/models/fields/encrypted.py +++ b/src/sentry/db/models/fields/encrypted.py @@ -10,7 +10,7 @@ import six from django.db.models import CharField, TextField -from picklefield.fields import PickledObjectField +from picklefield.fields import PickledObjectField, dbsafe_decode, PickledObject, _ObjectWrapper from sentry.db.models.fields.jsonfield import JSONField from sentry.db.models.utils import Creator from sentry.utils.encryption import decrypt, encrypt @@ -56,7 +56,24 @@ def get_db_prep_value(self, value, *args, **kwargs): def to_python(self, value): if value is not None and isinstance(value, six.string_types): value = decrypt(value) - return super(EncryptedPickledObjectField, self).to_python(value) + + # The following below is a copypaste of PickledObjectField.to_python of + # v1.0.0 with one change: We re-raise any baseexceptions such as + # signals. 1.0.0 has a bare `except:` which causes issues. + + if value is not None: + try: + value = dbsafe_decode(value, self.compress) + except Exception: + # If the value is a definite pickle; and an error is raised in + # de-pickling it should be allowed to propogate. + if isinstance(value, PickledObject): + raise + else: + if isinstance(value, _ObjectWrapper): + return value._obj + + return value class EncryptedTextField(TextField):