esnme/ultrajson — pull request #93 by Komnomnomnom (2013-06-18 09:46:48+00:00)
Title: Fix invalid memory read (from valgrind) during test_decodeBrokenListLeakTest

This change prevents `offset` pointer from wandering beyond the end of the buffer.

Valgrind warning:

```
(py27_db)kieran@smallbang ~/work/git/ultrajson_kom $ PYTHONPATH=. valgrind --tool=memcheck --suppressions=/home/kieran/work/py27_db/valgrind-python.supp nosetests -v tests/tests.py:UltraJSONTests.test_decodeBrokenListLeakTest
==31140== Memcheck, a memory error detector
==31140== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==31140== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==31140== Command: /home/kieran/work/pyenv/py27_db/bin/nosetests -v tests/tests.py:UltraJSONTests.test_decodeBrokenListLeakTest
==31140==
test_decodeBrokenListLeakTest (tests.UltraJSONTests) ... ==31140== Invalid read of size 1
==31140== at 0xC2A6F0D: SkipWhitespace (ultrajsondec.c:376)
==31140== by 0xC2A7E8E: JSON_DecodeObject (ultrajsondec.c:888)
==31140== by 0xC2A44AB: JSONToObj (JSONtoObj.c:173)
==31140== by 0x55B41C: PyCFunction_Call (methodobject.c:85)
==31140== by 0x4D127F: call_function (ceval.c:4021)
==31140== by 0x4CC3B3: PyEval_EvalFrameEx (ceval.c:2666)
==31140== by 0x4D1748: fast_function (ceval.c:4107)
==31140== by 0x4D1453: call_function (ceval.c:4042)
==31140== by 0x4CC3B3: PyEval_EvalFrameEx (ceval.c:2666)
==31140== by 0x4CEA78: PyEval_EvalCodeEx (ceval.c:3253)
==31140== by 0x558AED: function_call (funcobject.c:526)
==31140== by 0x4208EE: PyObject_Call (abstract.c:2529)
==31140== Address 0x7722b5c is 0 bytes after a block of size 60 alloc'd
==31140== at 0x4C2C04B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==31140== by 0x46C7C6: PyString_FromStringAndSize (stringobject.c:88)
==31140== by 0x4F5114: r_object (marshal.c:807)
==31140== by 0x4F548D: r_object (marshal.c:884)
==31140== by 0x4F5CC1: r_object (marshal.c:1017)
==31140== by 0x4F548D: r_object (marshal.c:884)
==31140== by 0x4F5CC1: r_object (marshal.c:1017)
==31140== by 0x4F548D: r_object (marshal.c:884)
==31140== by 0x4F5CC1: r_object (marshal.c:1017)
==31140== by 0x4F6556: PyMarshal_ReadObjectFromString (marshal.c:1181)
==31140== by 0x4F6437: PyMarshal_ReadLastObjectFromFile (marshal.c:1142)
==31140== by 0x4EBC86: read_compiled_module (import.c:801)
==31140==
ok

----------------------------------------------------------------------
Ran 1 test in 0.309s

OK
[94489 refs]
==31140==
==31140== HEAP SUMMARY:
==31140== in use at exit: 5,508,494 bytes in 34,928 blocks
==31140== total heap usage: 325,126 allocs, 290,198 frees, 45,633,540 bytes allocated
==31140==
==31140== LEAK SUMMARY:
==31140== definitely lost: 0 bytes in 0 blocks
==31140== indirectly lost: 0 bytes in 0 blocks
==31140== possibly lost: 1,751,229 bytes in 8,129 blocks
==31140== still reachable: 3,757,265 bytes in 26,799 blocks
==31140== suppressed: 0 bytes in 0 blocks
==31140== Rerun with --leak-check=full to see details of leaked memory
==31140==
==31140== For counts of detected and suppressed errors, rerun with: -v
==31140== ERROR SUMMARY: 1000 errors from 1 contexts (suppressed: 2 from 2)
```

All tests pass in Python 2.7 and valgrind run is clean.