فهرست منبع

Fixed #26672 -- Fixed HStoreField to raise ValidationError instead of crashing on non-dict JSON input.

Brad Melin 8 سال پیش
والد
کامیت
f6517a5335
4فایلهای تغییر یافته به همراه22 افزوده شده و 1 حذف شده
  1. 1 0
      AUTHORS
  2. 11 1
      django/contrib/postgres/forms/hstore.py
  3. 3 0
      docs/releases/1.9.7.txt
  4. 7 0
      tests/postgres_tests/test_hstore.py

+ 1 - 0
AUTHORS

@@ -108,6 +108,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>

+ 11 - 1
django/contrib/postgres/forms/hstore.py

@@ -9,10 +9,13 @@ __all__ = ['HStoreField']
 
 
 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):
@@ -31,6 +34,13 @@ class HStoreField(forms.CharField):
                     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)

+ 3 - 0
docs/releases/1.9.7.txt

@@ -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 - 0
tests/postgres_tests/test_hstore.py

@@ -208,6 +208,13 @@ class TestFormField(PostgreSQLTestCase):
         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}')