classification
Title: assertion failure in json, in case _json.make_encoder() received a bad encoder() argument
Type: crash Stage: resolved
Components: Extension Modules Versions: Python 3.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Oren Milman, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2017-09-18 08:57 by Oren Milman, last changed 2017-09-27 05:41 by serhiy.storchaka. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 3643 merged Oren Milman, 2017-09-18 09:53
PR 3777 merged python-dev, 2017-09-27 04:47
Messages (3)
msg302428 - (view) Author: Oren Milman (Oren Milman) * Date: 2017-09-18 08:57
The following code causes an assertion failure:

import _json
def _bad_encoder(*args):
    return None

enc = _json.make_encoder(None, None, _bad_encoder, None,
                         'foo', 'bar', None, None, None)

enc(obj='spam', _current_indent_level=4)


This is because encoder_new() (in Modules/_json.c) assumes that the received
encoder() argument is a function that returns a string, and stores it in the
new PyEncoderObject.
When encoder_encode_string() is called (by encoder_listencode_obj()), it
returns whatever the stored encoder() returned, assuming it returned a string.
Then, encoder_listencode_obj() passes this value to _steal_accumulate(), which
passes it to _PyAccu_Accumulate(), which asserts it is a string.


Similarly, the following code also causes an assertion failure (only the obj
argument is different):

import _json
def _bad_encoder(*args):
    return None

enc = _json.make_encoder(None, None, _bad_encoder, None,
                         'foo', 'bar', None, None, None)

enc(obj={'spam': 42}, _current_indent_level=4)


In this case, encoder_listencode_dict() passes whatever encoder_encode_string()
returned, to _PyAccu_Accumulate(), which asserts it is a string.
msg302836 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-24 09:07
New changeset 2b382dd6121bb1e4b75470fb3ef8555665df3eb6 by Serhiy Storchaka (Oren Milman) in branch 'master':
bpo-31505: Fix an assertion failure in json, in case _json.make_encoder() received a bad encoder() argument. (#3643)
https://github.com/python/cpython/commit/2b382dd6121bb1e4b75470fb3ef8555665df3eb6
msg303094 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-09-27 05:21
New changeset 7c24e99c99c961e6633ac45390a211f65806c687 by Serhiy Storchaka (Miss Islington (bot)) in branch '3.6':
[3.6] bpo-31505: Fix an assertion failure in json, in case _json.make_encoder() received a bad encoder() argument. (GH-3643) (#3777)
https://github.com/python/cpython/commit/7c24e99c99c961e6633ac45390a211f65806c687
History
Date User Action Args
2017-09-27 05:41:43serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2017-09-27 05:21:49serhiy.storchakasetmessages: + msg303094
2017-09-27 04:47:46python-devsetpull_requests: + pull_request3764
2017-09-24 09:07:16serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg302836
2017-09-18 09:53:22Oren Milmansetkeywords: + patch
stage: patch review
pull_requests: + pull_request3638
2017-09-18 09:06:15Oren Milmansettitle: assertion failure in _json.make_encoder() in case of a bad encoder() argument -> assertion failure in json, in case _json.make_encoder() received a bad encoder() argument
2017-09-18 08:57:43Oren Milmancreate