summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2017-09-08 10:56:49 +0200
committerEven Rouault <even.rouault@spatialys.com>2017-09-08 10:56:49 +0200
commit28094e1ebfa420f9a0bdc7a11b8d4ee5f154db35 (patch)
tree4991651fed019b6c14c63b8bc45077beecebfe20 /src/lib
parent33167ddc13fd20313ccfcdc64141000407b68b8f (diff)
opj_tcd_mct_decode(): avoid heap buffer overflow when components have not the same number of resolutions. Also fixes an issue with subtile decoding. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3331. Credit to OSS Fuzz
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/openjp2/tcd.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c
index 68caf5b0..631a4840 100644
--- a/src/lib/openjp2/tcd.c
+++ b/src/lib/openjp2/tcd.c
@@ -1520,6 +1520,15 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd,
tilec->win_y1 = opj_uint_min(
(OPJ_UINT32)tilec->y1,
opj_uint_ceildiv(p_tcd->win_y1, image_comp->dy));
+ if (tilec->win_x1 < tilec->win_x0 ||
+ tilec->win_y1 < tilec->win_y0) {
+ /* We should not normally go there. The circumstance is when */
+ /* the tile coordinates do not intersect the area of interest */
+ /* Upper level logic should not even try to decode that tile */
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Invalid tilec->win_xxx values\n");
+ return OPJ_FALSE;
+ }
for (resno = 0; resno < tilec->numresolutions; ++resno) {
opj_tcd_resolution_t *res = tilec->resolutions + resno;
@@ -1974,6 +1983,16 @@ static OPJ_BOOL opj_tcd_mct_decode(opj_tcd_t *p_tcd, opj_event_mgr_t *p_manager)
l_samples = (OPJ_UINT32)((res_comp0->x1 - res_comp0->x0) *
(res_comp0->y1 - res_comp0->y0));
if (l_tile->numcomps >= 3) {
+ if (l_tile_comp->minimum_num_resolutions !=
+ l_tile->comps[1].minimum_num_resolutions ||
+ l_tile_comp->minimum_num_resolutions !=
+ l_tile->comps[2].minimum_num_resolutions) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Tiles don't all have the same dimension. Skip the MCT step.\n");
+ return OPJ_FALSE;
+ }
+ }
+ if (l_tile->numcomps >= 3) {
opj_tcd_resolution_t* res_comp1 = l_tile->comps[1].resolutions +
l_tile_comp->minimum_num_resolutions - 1;
opj_tcd_resolution_t* res_comp2 = l_tile->comps[2].resolutions +