diff --git a/Tests/check_webp_leaks.py b/Tests/check_webp_leaks.py deleted file mode 100644 index 0f54f382d..000000000 --- a/Tests/check_webp_leaks.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import division -from helper import unittest, PillowTestCase -import sys -from PIL import Image -from io import BytesIO - -# Limits for testing the leak -mem_limit = 16 # max increase in MB -iterations = 5000 -test_file = "Tests/images/hopper.webp" - - -@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or MacOS") -class TestWebPLeaks(PillowTestCase): - - def setUp(self): - try: - from PIL import _webp - except ImportError: - self.skipTest('WebP support not installed') - - def _get_mem_usage(self): - from resource import getpagesize, getrusage, RUSAGE_SELF - mem = getrusage(RUSAGE_SELF).ru_maxrss - return mem * getpagesize() / 1024 / 1024 - - def test_leak_load(self): - with open(test_file, 'rb') as f: - im_data = f.read() - start_mem = self._get_mem_usage() - for _ in range(iterations): - with Image.open(BytesIO(im_data)) as im: - im.load() - mem = (self._get_mem_usage() - start_mem) - self.assertLess(mem, mem_limit, msg='memory usage limit exceeded') - -if __name__ == '__main__': - unittest.main() diff --git a/Tests/test_webp_leaks.py b/Tests/test_webp_leaks.py new file mode 100644 index 000000000..82599bbbb --- /dev/null +++ b/Tests/test_webp_leaks.py @@ -0,0 +1,25 @@ +from helper import unittest, PillowLeakTestCase +from PIL import Image, features +from io import BytesIO + +test_file = "Tests/images/hopper.webp" + +@unittest.skipUnless(features.check('webp'), "WebP is not installed") +class TestWebPLeaks(PillowLeakTestCase): + + mem_limit = 3 * 1024 # kb + iterations = 100 + + def test_leak_load(self): + with open(test_file, 'rb') as f: + im_data = f.read() + + def core(): + with Image.open(BytesIO(im_data)) as im: + im.load() + + self._test_leak(core) + + +if __name__ == '__main__': + unittest.main() diff --git a/src/_webp.c b/src/_webp.c index 67a9e6b66..f82feb46a 100644 --- a/src/_webp.c +++ b/src/_webp.c @@ -410,6 +410,7 @@ PyObject* _anim_decoder_get_next(PyObject* self, PyObject* args) uint8_t* buf; int timestamp; PyObject* bytes; + PyObject* ret; WebPAnimDecoderObject* decp = (WebPAnimDecoderObject*)self; if (!WebPAnimDecoderGetNext(decp->dec, &buf, ×tamp)) { @@ -419,7 +420,11 @@ PyObject* _anim_decoder_get_next(PyObject* self, PyObject* args) bytes = PyBytes_FromStringAndSize((char *)buf, decp->info.canvas_width * 4 * decp->info.canvas_height); - return Py_BuildValue("Si", bytes, timestamp); + + ret = Py_BuildValue("Si", bytes, timestamp); + + Py_DECREF(bytes); + return ret; } PyObject* _anim_decoder_has_more_frames(PyObject* self, PyObject* args)