From d6c16aa01536165bf82747819ebcecb1bc248d45 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Wed, 24 Sep 2014 15:37:28 -0700 Subject: [PATCH] Tests for jpeg memory leaks --- Tests/check_jpeg_leaks.py | 212 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 Tests/check_jpeg_leaks.py diff --git a/Tests/check_jpeg_leaks.py b/Tests/check_jpeg_leaks.py new file mode 100644 index 000000000..adf7652cf --- /dev/null +++ b/Tests/check_jpeg_leaks.py @@ -0,0 +1,212 @@ +from helper import unittest, PillowTestCase, hopper +from PIL import Image +from io import BytesIO +import sys + +iterations = 5000 + + +""" +When run on a system without the jpeg leak fixes, the valgrind runs look like this. + +NOSE_PROCESSES=0 NOSE_TIMEOUT=600 valgrind --tool=massif \ + python test-installed.py -s -v Tests/check_jpeg_leaks.py + +""" + + +@unittest.skipIf(sys.platform.startswith('win32'), "requires Unix or MacOS") +class TestJpegLeaks(PillowTestCase): + + """ +pre patch: + + MB +31.62^ : + | @:@:@:@#:: + | @:@:@@:@:@:@:@:@#:: + | ::::::::@:@:@@:@:@:@:@:@#:: + | :::::@::::::: ::::@:@:@@:@:@:@:@:@#:: + | @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | ::::::@::::@:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | ::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | :::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | ::::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | : ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | @: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | @@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | :@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | :@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + | :@:@@: ::::::::: : :@: : @:::::::::::::@: : ::: ::::@:@:@@:@:@:@:@:@#:: + 0 +----------------------------------------------------------------------->Gi + 0 8.535 + + +post-patch: + + MB +21.03^ :::@@:::@::::@@:::::::@@::::::::@::::::::::::@:::@:::::::@:::: + | #:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | #:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :::#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | : :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | : :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | @: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | @@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + | :@:@@: :#:::@ :::@::::@ : :: : @ :::::: :@:: ::: :::: @:: @:::::::@:::: + 0 +----------------------------------------------------------------------->Gi + 0 8.421 + +""" + + + def test_qtables_leak(self): + im = hopper('RGB') + + standard_l_qtable = [int(s) for s in """ + 16 11 10 16 24 40 51 61 + 12 12 14 19 26 58 60 55 + 14 13 16 24 40 57 69 56 + 14 17 22 29 51 87 80 62 + 18 22 37 56 68 109 103 77 + 24 35 55 64 81 104 113 92 + 49 64 78 87 103 121 120 101 + 72 92 95 98 112 100 103 99 + """.split(None)] + + standard_chrominance_qtable = [int(s) for s in """ + 17 18 24 47 99 99 99 99 + 18 21 26 66 99 99 99 99 + 24 26 56 99 99 99 99 99 + 47 66 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + 99 99 99 99 99 99 99 99 + """.split(None)] + + qtables = [standard_l_qtable, + standard_chrominance_qtable] + + + for count in range(iterations): + test_output = BytesIO() + im.save(test_output, "JPEG", qtables=qtables) + + """ +pre patch: + + MB +177.1^ # + | @@@# + | :@@@@@@# + | ::::@@@@@@# + | ::::::::@@@@@@# + | @@::::: ::::@@@@@@# + | @@@@ ::::: ::::@@@@@@# + | @@@@@@@ ::::: ::::@@@@@@# + | @@::@@@@@@@ ::::: ::::@@@@@@# + | @@@@ : @@@@@@@ ::::: ::::@@@@@@# + | @@@@@@ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @@@@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @::@@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | ::::@: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | :@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | ::@@::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @@::: @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @::@ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | :::@: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + | @@@:: @: @ : : @ ::@@: : @: @@ @@ @@ @ @@ : @@@@@@@ ::::: ::::@@@@@@# + 0 +----------------------------------------------------------------------->Gi + 0 11.37 + + +post patch: + + MB +21.06^ ::::::::::::::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | ##::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | # ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @@@@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + | @ @@@# ::: ::::: : ::::::::::@::::@::::@::::@::::@::::@:::::::::@:::::: + 0 +----------------------------------------------------------------------->Gi + 0 11.33 + +""" + + def test_exif_leak(self): + im = hopper('RGB') + exif = b'12345678'*4096 + + for count in range(iterations): + test_output = BytesIO() + im.save(test_output, "JPEG", exif=exif) + + + """ +base case: + MB +20.99^ ::::: :::::::::::::::::::::::::::::::::::::::::::@::: + | ##: : ::::::@::::::: :::: :::: : : : : : : :::::::::::: :::@::: + | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@# : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@@ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@@@@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + | :@ @@ @ # : : :: :: @:: :::: :::: :::: : : : : : : :::::::::::: :::@::: + 0 +----------------------------------------------------------------------->Gi + 0 7.882 +""" + + def test_base_save(self): + im = hopper('RGB') + + for count in range(iterations): + test_output = BytesIO() + im.save(test_output, "JPEG") + + +if __name__ == '__main__': + unittest.main()