From 0da68dee98d035f398c8241110e749cc2befdae5 Mon Sep 17 00:00:00 2001 From: Eric Soroos Date: Wed, 24 Jan 2018 13:22:51 +0000 Subject: [PATCH 1/3] Fix leak opening _webp files --- src/_webp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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) From 379d3ccce249d60a60eb02d31c381d2d2a4e2a3e Mon Sep 17 00:00:00 2001 From: Eric Soroos Date: Wed, 24 Jan 2018 14:02:33 +0000 Subject: [PATCH 2/3] Fixed up the webp leak check --- Tests/check_webp_leaks.py | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/Tests/check_webp_leaks.py b/Tests/check_webp_leaks.py index 0f54f382d..82599bbbb 100644 --- a/Tests/check_webp_leaks.py +++ b/Tests/check_webp_leaks.py @@ -1,38 +1,25 @@ -from __future__ import division -from helper import unittest, PillowTestCase -import sys -from PIL import Image +from helper import unittest, PillowLeakTestCase +from PIL import Image, features 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.skipUnless(features.check('webp'), "WebP is not installed") +class TestWebPLeaks(PillowLeakTestCase): -@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 + mem_limit = 3 * 1024 # kb + iterations = 100 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): + + def core(): 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') + + self._test_leak(core) + if __name__ == '__main__': unittest.main() From 1b06cbc3bb637e19fb2e4d140ff9c5a1173c06e7 Mon Sep 17 00:00:00 2001 From: Eric Soroos Date: Wed, 24 Jan 2018 14:02:58 +0000 Subject: [PATCH 3/3] run webp leak check by default --- Tests/{check_webp_leaks.py => test_webp_leaks.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Tests/{check_webp_leaks.py => test_webp_leaks.py} (100%) diff --git a/Tests/check_webp_leaks.py b/Tests/test_webp_leaks.py similarity index 100% rename from Tests/check_webp_leaks.py rename to Tests/test_webp_leaks.py