Skip to content

Commit

Permalink
Fix ref counting on non-string dict keys
Browse files Browse the repository at this point in the history
For bytes, there was an extraneous INCREF; PyIter_Next returns a new reference. For other non-strings, the original itemName before converting to a string was never dereferenced.

Fixes #419
  • Loading branch information
JustAnotherArchivist authored and bwoodsend committed Apr 7, 2022
1 parent 2d1f088 commit 62dec8d
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 6 deletions.
6 changes: 2 additions & 4 deletions python/objToJSON.c
Expand Up @@ -254,15 +254,13 @@ static int Dict_iterNext(JSOBJ obj, JSONTypeContext *tc)
return 1;
}

itemNameTmp = GET_TC(tc)->itemName;
GET_TC(tc)->itemName = PyObject_Str(GET_TC(tc)->itemName);
Py_DECREF(itemNameTmp);
itemNameTmp = GET_TC(tc)->itemName;
GET_TC(tc)->itemName = PyUnicode_AsUTF8String (GET_TC(tc)->itemName);
Py_DECREF(itemNameTmp);
}
else
{
Py_INCREF(GET_TC(tc)->itemName);
}
PRINTMARK();
return 1;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/test_ujson.py
Expand Up @@ -239,11 +239,11 @@ def test_encode_dict_values_ref_counting():
@pytest.mark.skipif(
hasattr(sys, "pypy_version_info"), reason="PyPy uses incompatible GC"
)
def test_encode_dict_key_ref_counting():
@pytest.mark.parametrize("key", ["key", b"key", 1, True, None])
def test_encode_dict_key_ref_counting(key):
import gc

gc.collect()
key = "key"
data = {key: "abc"}
ref_count = sys.getrefcount(key)
ujson.dumps(data)
Expand Down

0 comments on commit 62dec8d

Please sign in to comment.