Checking for division by zero with bad tile dimensions. #181

This commit is contained in:
John Evans 2014-03-12 20:03:04 -04:00
commit 2ae848b6f0
2 changed files with 36 additions and 23 deletions

View file

@ -673,6 +673,18 @@ class Codestream(object):
msg = msg.format(j, subsampling[0], subsampling[1])
warnings.warn(msg)
try:
num_tiles_x = (xysiz[0] - xyosiz[0]) / (xytsiz[0] - xytosiz[0])
num_tiles_y = (xysiz[1] - xyosiz[1]) / (xytsiz[1] - xytosiz[1])
except ZeroDivisionError as err:
warnings.warn("Invalid tile dimensions.")
else:
numtiles = math.ceil(num_tiles_x) * math.ceil(num_tiles_y)
if numtiles > 65535:
msg = "Invalid number of tiles ({0}).".format(numtiles)
warnings.warn(msg)
kwargs = {'rsiz': rsiz,
'xysiz': xysiz,
'xyosiz': xyosiz,
@ -1514,14 +1526,6 @@ class SIZsegment(Segment):
lst.append(bitdepth - 1)
self.ssiz = tuple(lst)
num_tiles_x = (self.xsiz - self.xosiz) / (self.xtsiz - self.xtosiz)
num_tiles_y = (self.ysiz - self.yosiz) / (self.ytsiz - self.ytosiz)
numtiles = math.ceil(num_tiles_x) * math.ceil(num_tiles_y)
if numtiles > 65535:
msg = "Invalid number of tiles ({0}).".format(numtiles)
warnings.warn(msg)
def __repr__(self):
msg = "glymur.codestream.SIZsegment(rsiz={rsiz}, xysiz={xysiz}, "
msg += "xyosiz={xyosiz}, xytsiz={xytsiz}, xytosiz={xytosiz}, "

View file

@ -13,17 +13,12 @@ import struct
import sys
import tempfile
import unittest
import warnings
from glymur import Jp2k
import glymur
try:
DATA_ROOT = os.environ['OPJ_DATA_ROOT']
except KeyError:
DATA_ROOT = None
except:
raise
from .fixtures import opj_data_file, OPJ_DATA_ROOT
class TestCodestream(unittest.TestCase):
"""Test suite for unusual codestream cases."""
@ -34,7 +29,21 @@ class TestCodestream(unittest.TestCase):
def tearDown(self):
pass
@unittest.skipIf(DATA_ROOT is None,
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_tile_height_is_zero(self):
"""Zero tile height should not cause an exception."""
filename = opj_data_file('input/nonregression/2539.pdf.SIGFPE.706.1712.jp2')
if sys.hexversion < 0x03000000:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
Jp2k(filename)
else:
with self.assertWarns(UserWarning):
Jp2k(jfile)
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
def test_reserved_marker_segment(self):
@ -45,7 +54,7 @@ class TestCodestream(unittest.TestCase):
#
# Let's inject a reserved marker segment into a file that
# we know something about to make sure we can still parse it.
filename = os.path.join(DATA_ROOT, 'input/conformance/p0_01.j2k')
filename = os.path.join(OPJ_DATA_ROOT, 'input/conformance/p0_01.j2k')
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
with open(filename, 'rb') as ifile:
# Everything up until the first QCD marker.
@ -67,7 +76,7 @@ class TestCodestream(unittest.TestCase):
self.assertEqual(codestream.segment[2].length, 3)
self.assertEqual(codestream.segment[2].data, b'\x00')
@unittest.skipIf(DATA_ROOT is None,
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
@unittest.skipIf(sys.hexversion < 0x03020000,
"Uses features introduced in 3.2.")
@ -77,7 +86,7 @@ class TestCodestream(unittest.TestCase):
# Let's inject a marker segment whose marker does not appear to
# be valid. We still parse the file, but warn about the offending
# marker.
filename = os.path.join(DATA_ROOT, 'input/conformance/p0_01.j2k')
filename = os.path.join(OPJ_DATA_ROOT, 'input/conformance/p0_01.j2k')
with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile:
with open(filename, 'rb') as ifile:
# Everything up until the first QCD marker.
@ -100,11 +109,11 @@ class TestCodestream(unittest.TestCase):
self.assertEqual(codestream.segment[2].length, 3)
self.assertEqual(codestream.segment[2].data, b'\x00')
@unittest.skipIf(DATA_ROOT is None,
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_psot_is_zero(self):
"""Psot=0 in SOT is perfectly legal. Issue #78."""
filename = os.path.join(DATA_ROOT,
filename = os.path.join(OPJ_DATA_ROOT,
'input/nonregression/123.j2c')
j = Jp2k(filename)
codestream = j.get_codestream(header_only=False)
@ -125,11 +134,11 @@ class TestCodestream(unittest.TestCase):
self.assertEqual(codestream.segment[1].ssiz, (7, 7, 7))
@unittest.skipIf(DATA_ROOT is None,
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_siz_segment_ssiz_signed(self):
"""ssiz attribute to be removed in future release"""
filename = os.path.join(DATA_ROOT, 'input/conformance/p0_03.j2k')
filename = os.path.join(OPJ_DATA_ROOT, 'input/conformance/p0_03.j2k')
j = Jp2k(filename)
codestream = j.get_codestream()