Skip to content

Commit

Permalink
[1.9.x] Fixed #26672 -- Fixed HStoreField to raise ValidationError in…
Browse files Browse the repository at this point in the history
…stead of crashing on non-dict JSON input.

Backport of f6517a5 from master
  • Loading branch information
ny0m authored and timgraham committed Jun 2, 2016
1 parent efe89f5 commit 95ed151
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ answer newbie questions, and generally made Django that much better:
Bojan Mihelac <bmihelac@mihelac.org>
Bouke Haarsma <bouke@haarsma.eu>
Božidar Benko <bbenko@gmail.com>
Brad Melin <melinbrad@gmail.com>
Brant Harris
Brendan Hayward <brendanhayward85@gmail.com>
Brenton Simpson <http://theillustratedlife.com>
Expand Down
12 changes: 11 additions & 1 deletion django/contrib/postgres/forms/hstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@


class HStoreField(forms.CharField):
"""A field for HStore data which accepts JSON input."""
"""
A field for HStore data which accepts dictionary JSON input.
"""
widget = forms.Textarea
default_error_messages = {
'invalid_json': _('Could not load JSON data.'),
'invalid_format': _('Input must be a JSON dictionary.'),
}

def prepare_value(self, value):
Expand All @@ -31,6 +34,13 @@ def to_python(self, value):
self.error_messages['invalid_json'],
code='invalid_json',
)

if not isinstance(value, dict):
raise ValidationError(
self.error_messages['invalid_format'],
code='invalid_format',
)

# Cast everything to strings for ease.
for key, val in value.items():
value[key] = six.text_type(val)
Expand Down
3 changes: 3 additions & 0 deletions docs/releases/1.9.7.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ Bugfixes

* Fixed ``on_commit`` callbacks execution order when callbacks make
transactions (:ticket:`26627`).

* Fixed ``HStoreField`` to raise a ``ValidationError`` instead of crashing on
non-dictionary JSON input (:ticket:`26672`).
7 changes: 7 additions & 0 deletions tests/postgres_tests/test_hstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ def test_invalid_json(self):
self.assertEqual(cm.exception.messages[0], 'Could not load JSON data.')
self.assertEqual(cm.exception.code, 'invalid_json')

def test_non_dict_json(self):
field = forms.HStoreField()
msg = 'Input must be a JSON dictionary.'
with self.assertRaisesMessage(exceptions.ValidationError, msg) as cm:
field.clean('["a", "b", 1]')
self.assertEqual(cm.exception.code, 'invalid_format')

def test_not_string_values(self):
field = forms.HStoreField()
value = field.clean('{"a": 1}')
Expand Down

0 comments on commit 95ed151

Please sign in to comment.