From b2d5944376f3d01215d63971ce0b6368d34ecef4 Mon Sep 17 00:00:00 2001 From: Ruven Date: Mon, 5 Feb 2024 22:55:41 +0100 Subject: [PATCH] Change to exception handling with Kakadu to avoid crash with mal-formed JPEG2000 streams. Fixes https://github.com/ruven/iipsrv/issues/264 --- ChangeLog | 2 ++ src/KakaduImage.cc | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f2cac7e..17aedeb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 05/02/2024: - Added JPEG2000 codec version information to logging. + - Change to exception handling with Kakadu to avoid crash with mal-formed JPEG2000 streams. Fixes + https://github.com/ruven/iipsrv/issues/264. 26/01/2024: diff --git a/src/KakaduImage.cc b/src/KakaduImage.cc index a6943b43..2b02ef7c 100644 --- a/src/KakaduImage.cc +++ b/src/KakaduImage.cc @@ -7,7 +7,7 @@ Culture of the Czech Republic. - Copyright (C) 2009-2023 IIPImage. + Copyright (C) 2009-2024 IIPImage. Author: Ruven Pillay This program is free software; you can redistribute it and/or modify @@ -375,8 +375,7 @@ void KakaduImage::loadImageInfo( int seq, int ang ) // For bilevel images, force channels to 1 as we sometimes come across such images which claim 3 channels if( bpc == 1 ) channels = 1; - // Get the max and min values for our data type - //double sminvalue[4], smaxvalue[4]; + // Get the max and min values for our data type - only handle 8 and 16 bit for now for( unsigned int i=0; i 8 && bpc <= 16 ) max.push_back( 65535.0 ); @@ -431,8 +430,8 @@ void KakaduImage::closeImage() if( codestream.exists() ) codestream.destroy(); // Close our JP2 family and JPX files - src.close(); - jpx_input.close(); + if( src.exists() ) src.close(); + if( jpx_input.exists() ) jpx_input.close(); #ifdef KAKADU_DEBUG logfile << "Kakadu :: closeImage() :: " << timer.getTime() << " microseconds" << endl; @@ -820,7 +819,12 @@ void KakaduImage::process( unsigned int res, int layers, int xoffset, int yoffse } catch (...){ // Shut down our decompressor, delete our buffers, destroy our threads and codestream before rethrowing the exception +#if defined(KDU_MAJOR_VERSION) && (KDU_MAJOR_VERSION >= 8 || ((KDU_MAJOR_VERSION >= 7) && (KDU_MINOR_VERSION >= 5))) + // Note that from Kakadu 7.5 onwards, we need to use reset() rather than finish() in case of an exception + decompressor.reset( true ); +#else decompressor.finish(); +#endif if( env.exists() ) env.destroy(); delete_buffer( stripe_buffer ); delete_buffer( buffer );