From 9cef9f5951eabaf010fc0b8d08b2d6e0c7dcf526 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 21 May 2017 13:28:24 +0300 Subject: Fix a crash wish unencodable encoding in the encoder. JSONEncoder.encode() crashed in Python 3 when encoded bytes keys if the encoding was not encodable to utf-8 (contained surrogates). --- simplejson/_speedups.c | 7 ++++++- simplejson/tests/test_speedups.py | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c index d61f270..a9a05e3 100644 --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -642,10 +642,13 @@ encoder_stringify_key(PyEncoderObject *s, PyObject *key) } else if (PyString_Check(key)) { #if PY_MAJOR_VERSION >= 3 + const char *encoding = JSON_ASCII_AS_STRING(s->encoding); + if (encoding == NULL) + return NULL; return PyUnicode_Decode( PyString_AS_STRING(key), PyString_GET_SIZE(key), - JSON_ASCII_AS_STRING(s->encoding), + encoding, NULL); #else /* PY_MAJOR_VERSION >= 3 */ Py_INCREF(key); @@ -2599,6 +2602,8 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) s->encoding = JSON_ParseEncoding(encoding); if (s->encoding == NULL) goto bail; + if (JSON_ASCII_AS_STRING(s->encoding) == NULL) + goto bail; Py_INCREF(indent); s->indent = indent; Py_INCREF(key_separator); diff --git a/simplejson/tests/test_speedups.py b/simplejson/tests/test_speedups.py index 89a30d9..b59eeca 100644 --- a/simplejson/tests/test_speedups.py +++ b/simplejson/tests/test_speedups.py @@ -1,10 +1,12 @@ +from __future__ import with_statement + import sys import unittest from unittest import TestCase import simplejson from simplejson import encoder, decoder, scanner -from simplejson.compat import PY3, long_type +from simplejson.compat import PY3, long_type, b def has_speedups(): @@ -80,3 +82,9 @@ class TestEncode(TestCase): def test(): encoder.JSONEncoder(int_as_string_bitcount=long_count).encode(0) self.assertRaises((TypeError, OverflowError), test) + + if PY3: + @skip_if_speedups_missing + def test_bad_encoding(self): + with self.assertRaises(UnicodeEncodeError): + encoder.JSONEncoder(encoding='\udcff').encode({b('key'): 123}) -- cgit v1.2.1