[med-svn] [Git][med-team/dcmtk][debian/bookworm] 8 commits: 0012-CVE-2022-4981.patch: new: fix CVE-2022-4981.

Étienne Mollier (@emollier) gitlab at salsa.debian.org
Sat Jun 13 22:02:54 BST 2026



Étienne Mollier pushed to branch debian/bookworm at Debian Med / dcmtk


Commits:
e4a751e1 by Étienne Mollier at 2026-06-12T20:24:23+02:00
0012-CVE-2022-4981.patch: new: fix CVE-2022-4981.

- - - - -
f78b200e by Étienne Mollier at 2026-06-12T20:29:25+02:00
0013-CVE-2025-2357.patch: new: fix CVE-2025-2357.

Closes: #1100724

- - - - -
145708c8 by Étienne Mollier at 2026-06-12T20:33:56+02:00
*CVE-2025-9732*.patch: new.

These two patches fix CVE-2025-9732.

Closes: #1113993

- - - - -
b6ed269d by Étienne Mollier at 2026-06-12T20:36:51+02:00
0016-CVE-2025-14607.patch: new: fix CVE-2025-14607.

Closes: #1122926

- - - - -
de913db2 by Étienne Mollier at 2026-06-12T20:38:30+02:00
0017-CVE-2025-14841.patch: new: fix CVE-2025-14841.

Closes: #1123584

- - - - -
6aa0897a by Étienne Mollier at 2026-06-12T23:15:36+02:00
0018-CVE-2026-5663.patch: new: fix CVE-2026-5663.

This patch required some rework from upstream due to little changes in
the logic and the coding style.

Closes: #1133001

- - - - -
526cfe00 by Étienne Mollier at 2026-06-12T23:15:41+02:00
0019-CVE-2026-10194.patch: new: fix CVE-2026-10194.

Closes: #1139181

- - - - -
b247b97c by Étienne Mollier at 2026-06-12T23:15:41+02:00
d/changelog: ready for upload to bookworm.

- - - - -


10 changed files:

- debian/changelog
- + debian/patches/0012-CVE-2022-4981.patch
- + debian/patches/0013-CVE-2025-2357.patch
- + debian/patches/0014-CVE-2025-9732.patch
- + debian/patches/0015-CVE-2025-9732b.patch
- + debian/patches/0016-CVE-2025-14607.patch
- + debian/patches/0017-CVE-2025-14841.patch
- + debian/patches/0018-CVE-2026-5663.patch
- + debian/patches/0019-CVE-2026-10194.patch
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,19 @@
+dcmtk (3.6.7-9~deb12u4) bookworm; urgency=medium
+
+  * Team upload.
+  * 0012-CVE-2022-4981.patch: new: fix CVE-2022-4981.
+  * 0013-CVE-2025-2357.patch: new: fix CVE-2025-2357. (Closes: #1100724)
+  * *CVE-2025-9732*.patch: new.
+    These two patches fix CVE-2025-9732. (Closes: #1113993)
+  * 0016-CVE-2025-14607.patch: new: fix CVE-2025-14607. (Closes: #1122926)
+  * 0017-CVE-2025-14841.patch: new: fix CVE-2025-14841. (Closes: #1123584)
+  * 0018-CVE-2026-5663.patch: new: fix CVE-2026-5663.
+    This patch required some rework from upstream due to little changes in
+    the logic and the coding style. (Closes: #1133001)
+  * 0019-CVE-2026-10194.patch: new: fix CVE-2026-10194. (Closes: #1139181)
+
+ -- Étienne Mollier <emollier at debian.org>  Fri, 12 Jun 2026 20:59:14 +0200
+
 dcmtk (3.6.7-9~deb12u3) bookworm; urgency=medium
 
   * Team upload.


=====================================
debian/patches/0012-CVE-2022-4981.patch
=====================================
@@ -0,0 +1,90 @@
+commit 957fb31e5d96f51ecf5cb3422c7dc2227f8e0423
+Author: Marco Eichelberg <dicom at offis.de>
+Date:   Tue May 24 11:22:35 2022 +0200
+
+    Fixed dcmqrscp crash caused by malformed config file.
+    
+    Fixed various issues in the dcmqrscp configuration file parser
+    that could cause application crashes when reading a malformed configuration
+    file, due to insufficient checks of the input data.
+    
+    This closes DCMTK issue #1026.
+    
+    Thanks to Zahra Mirzamomen <zahra.mirzamomen at monash.edu> and
+    Marcel Böhme <marcel.boehme at mpi-sp.org> for the bug report and sample files.
+
+diff --git a/dcmqrdb/libsrc/dcmqrcnf.cc b/dcmqrdb/libsrc/dcmqrcnf.cc
+index 686c9df2a..36a295fa2 100644
+--- a/dcmqrdb/libsrc/dcmqrcnf.cc
++++ b/dcmqrdb/libsrc/dcmqrcnf.cc
+@@ -1,6 +1,6 @@
+ /*
+  *
+- *  Copyright (C) 1993-2021, OFFIS e.V.
++ *  Copyright (C) 1993-2022, OFFIS e.V.
+  *  All rights reserved.  See COPYRIGHT file for details.
+  *
+  *  This software and supporting documentation were developed by
+@@ -447,7 +447,7 @@ int DcmQueryRetrieveConfig::readHostTable(FILE *cnffp, int *lineno)
+ {
+    int  error = 0,        /* error flag */
+         end = 0,          /* end flag */
+-        noOfPeers;        /* number of peers for entry */
++        noOfPeers=0;      /* number of peers for entry */
+    char rcline[512],      /* line in configuration file */
+         mnemonic[512],    /* mnemonic in line */
+         value[512],       /* parameter value */
+@@ -676,26 +676,34 @@ DcmQueryRetrieveConfigPeer *DcmQueryRetrieveConfig::readPeerList(char **valuehan
+    while((helpvalue = parsevalues(valuehandle)) != NULL) {
+       found = 0;
+       if (strchr(helpvalue, ',') == NULL) {   /* symbolic name */
+-         if (!CNF_HETable.noOfHostEntries) {
+-            panic("No symbolic names defined");
+-            *peers = 0;
+-            free(helpvalue);
+-            return((DcmQueryRetrieveConfigPeer *) 0);
+-         }
+-         for(i = 0; i < CNF_HETable.noOfHostEntries; i++) {
+-            if (!strcmp(CNF_HETable.HostEntries[i].SymbolicName, helpvalue)) {
+-               found = 1;
+-               break;
+-            }
+-         }
+-         if (!found) {
+-            panic("Symbolic name \"%s\" not defined", helpvalue);
+-            *peers = 0;
+-            free(helpvalue);
+-            return((DcmQueryRetrieveConfigPeer *) 0);
+-         }
++        if (!CNF_HETable.noOfHostEntries) {
++           panic("No symbolic names defined");
++           *peers = 0;
++           free(helpvalue);
++           return((DcmQueryRetrieveConfigPeer *) 0);
++        }
++        for(i = 0; i < CNF_HETable.noOfHostEntries; i++) {
++           if ((CNF_HETable.HostEntries[i].SymbolicName != NULL) && (0 == strcmp(CNF_HETable.HostEntries[i].SymbolicName, helpvalue))) {
++              found = 1;
++              break;
++           }
++        }
++        if (!found) {
++           panic("Symbolic name \"%s\" not defined", helpvalue);
++           *peers = 0;
++           free(helpvalue);
++           return((DcmQueryRetrieveConfigPeer *) 0);
++        }
++
++        if (CNF_HETable.HostEntries[i].noOfPeers <= 0) {
++           panic("No peers for symbolic name \"%s\" defined", helpvalue);
++           *peers = 0;
++           free(helpvalue);
++           return((DcmQueryRetrieveConfigPeer *) 0);
++        }
++
++        noOfPeers += CNF_HETable.HostEntries[i].noOfPeers;
+ 
+-         noOfPeers += CNF_HETable.HostEntries[i].noOfPeers;
+         if ((helppeer = (DcmQueryRetrieveConfigPeer *)malloc(noOfPeers * sizeof(DcmQueryRetrieveConfigPeer))) == NULL)
+             panic("Memory allocation 5 (%d)", noOfPeers);
+         if (noOfPeers - CNF_HETable.HostEntries[i].noOfPeers) {


=====================================
debian/patches/0013-CVE-2025-2357.patch
=====================================
@@ -0,0 +1,510 @@
+commit 3239a791542e1ea433d23aaa9e0a05a532ffabff
+Author: Marco Eichelberg <eichelberg at offis.de>
+Date:   Mon Mar 3 12:33:18 2025 +0100
+
+    Fixed segfault in JPEG-LS decoder.
+    
+    Fixed a bug in the JPEG-LS decoder that led to a segmentation fault if invalid
+    input data was processed, due to insufficient validation of input data.
+    
+    Thanks to Ding zhengzheng <xiaozheng.ding399 at gmail.com> for the report
+    and the sample file (PoC).
+    
+    This closes DCMTK issue #1155.
+
+diff --git a/dcmjpls/libcharls/scan.h b/dcmjpls/libcharls/scan.h
+index b4dea20d8..f13098104 100644
+--- a/dcmjpls/libcharls/scan.h
++++ b/dcmjpls/libcharls/scan.h
+@@ -1,6 +1,6 @@
+-// 
+-// (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use. 
+-// 
++//
++// (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use.
++//
+ 
+ #ifndef CHARLS_SCAN
+ #define CHARLS_SCAN
+@@ -11,7 +11,7 @@
+ 
+ #include "lokuptbl.h"
+ 
+-// This file contains the code for handling a "scan". Usually an image is encoded as a single scan. 
++// This file contains the code for handling a "scan". Usually an image is encoded as a single scan.
+ 
+ #include DCMTK_DIAGNOSTIC_IGNORE_CONST_EXPRESSION_WARNING
+ 
+@@ -21,10 +21,10 @@ extern OFVector<signed char> rgquant10Ll;
+ extern OFVector<signed char> rgquant12Ll;
+ extern OFVector<signed char> rgquant16Ll;
+ //
+-// Apply 
++// Apply
+ //
+ inlinehint LONG ApplySign(LONG i, LONG sign)
+-{ return (sign ^ i) - sign; }									
++{ return (sign ^ i) - sign; }
+ 
+ 
+ 
+@@ -58,20 +58,20 @@ inlinehint LONG GetPredictedValue(LONG Ra, LONG Rb, LONG Rc)
+ 
+ inlinehint LONG GetPredictedValue(LONG Ra, LONG Rb, LONG Rc)
+ {
+-	// sign trick reduces the number of if statements (branches) 
++	// sign trick reduces the number of if statements (branches)
+ 	LONG sgn = BitWiseSign(Rb - Ra);
+ 
+-	// is Ra between Rc and Rb? 
++	// is Ra between Rc and Rb?
+ 	if ((sgn ^ (Rc - Ra)) < 0)
+ 	{
+ 		return Rb;
+-	} 
++	}
+ 	else if ((sgn ^ (Rb - Rc)) < 0)
+ 	{
+ 		return Ra;
+ 	}
+ 
+-	// default case, valid if Rc element of [Ra,Rb] 
++	// default case, valid if Rc element of [Ra,Rb]
+ 	return Ra + Rb - Rc;
+ }
+ 
+@@ -110,7 +110,7 @@ public:
+ 
+ public:
+ 
+-	  JlsCodec(const TRAITS& inTraits, const JlsParameters& info) : STRATEGY(info), 
++	  JlsCodec(const TRAITS& inTraits, const JlsParameters& info) : STRATEGY(info),
+ 	  traits(inTraits),
+ 		  _rect(),
+ 		  _width(0),
+@@ -120,13 +120,13 @@ public:
+ 		  _RUNindex(0),
+ 		  _pquant(0),
+ 		  _bCompare(0)
+-		  
++
+ 	  {
+ 		  if (Info().ilv == ILV_NONE)
+ 		  {
+ 			  Info().components = 1;
+ 		  }
+-	  }	
++	  }
+ 
+ 
+ 	  void SetPresets(const JlsCustomParameters& presets)
+@@ -135,9 +135,9 @@ public:
+ 
+ 		  InitParams(presets.T1 != 0 ? presets.T1 : presetDefault.T1,
+ 			  presets.T2 != 0 ? presets.T2 : presetDefault.T2,
+-			  presets.T3 != 0 ? presets.T3 : presetDefault.T3, 
++			  presets.T3 != 0 ? presets.T3 : presetDefault.T3,
+ 			  presets.RESET != 0 ? presets.RESET : presetDefault.RESET);
+-	  }	
++	  }
+ 
+ 
+ 	  bool IsInterleaved()
+@@ -155,13 +155,13 @@ public:
+ 
+ 	  signed char QuantizeGratientOrg(LONG Di);
+ 	  inlinehint LONG QuantizeGratient(LONG Di)
+-	  { 
++	  {
+ 		  ASSERT(QuantizeGratientOrg(Di) == *(_pquant + Di));
+-		  return *(_pquant + Di); 
++		  return *(_pquant + Di);
+ 	  }
+ 
+ 	  void InitQuantizationLUT();
+-	
++
+ 	  LONG DecodeValue(LONG k, LONG limit, LONG qbpp);
+ 	  inlinehint void EncodeMappedValue(LONG k, LONG mappedError, LONG limit);
+ 
+@@ -216,27 +216,27 @@ public:
+ 	  {
+ 		LONG sign		= BitWiseSign(Qs);
+ 		JlsContext& ctx	= _contexts[ApplySign(Qs, sign)];
+-		LONG k			= ctx.GetGolomb();	
+-		LONG Px			= traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));    
++		LONG k			= ctx.GetGolomb();
++		LONG Px			= traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));
+ 
+ 		LONG ErrVal;
+ 		const Code& code		= decodingTables[k].Get(STRATEGY::PeekByte());
+ 		if (code.GetLength() != 0)
+ 		{
+ 			STRATEGY::Skip(code.GetLength());
+-			ErrVal = code.GetValue(); 
++			ErrVal = code.GetValue();
+ 			ASSERT(ABS(ErrVal) < 65535);
+ 		}
+ 		else
+ 		{
+-			ErrVal = UnMapErrVal(DecodeValue(k, traits.LIMIT, traits.qbpp)); 
++			ErrVal = UnMapErrVal(DecodeValue(k, traits.LIMIT, traits.qbpp));
+ 			if (ABS(ErrVal) > 65535)
+ 				throw JlsException(InvalidCompressedData);
+-		}	
++		}
+ 		ErrVal = ErrVal ^ ((traits.NEAR == 0) ? ctx.GetErrorCorrection(k) : 0);
+-		ctx.UpdateVariables(ErrVal, traits.NEAR, traits.RESET);	
++		ctx.UpdateVariables(ErrVal, traits.NEAR, traits.RESET);
+ 		ErrVal = ApplySign(ErrVal, sign);
+-		return traits.ComputeReconstructedSample(Px, ErrVal); 
++		return traits.ComputeReconstructedSample(Px, ErrVal);
+ 	  }
+ 
+ 
+@@ -245,7 +245,7 @@ public:
+ 		LONG sign		= BitWiseSign(Qs);
+ 		JlsContext& ctx	= _contexts[ApplySign(Qs, sign)];
+ 		LONG k			= ctx.GetGolomb();
+-		LONG Px			= traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));	
++		LONG Px			= traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));
+ 
+ 		LONG ErrVal		= traits.ComputeErrVal(ApplySign(x - Px, sign));
+ 
+@@ -270,16 +270,16 @@ public:
+ 	size_t  DecodeScan(void* rawData, const JlsRect& size, BYTE **buf, size_t *buf_size, size_t offset, bool bCompare);
+ 
+ protected:
+-	// codec parameters 
++	// codec parameters
+ 	TRAITS traits;
+ 	JlsRect _rect;
+ 	int _width;
+-	LONG T1;	
++	LONG T1;
+ 	LONG T2;
+-	LONG T3; 
++	LONG T3;
+ 
+ 	// compression context
+-	JlsContext _contexts[365];	
++	JlsContext _contexts[365];
+ 	CContextRunMode _contextRunmode[2];
+ 	LONG _RUNindex;
+ 	PIXEL* _previousLine; // previous line ptr
+@@ -309,7 +309,7 @@ CTable InitTable(LONG k)
+ 	CTable table;
+ 	short nerr;
+ 	for (nerr = 0; ; nerr++)
+-	{		
++	{
+ 		// Q is not used when k != 0
+ 		LONG merrval = GetMappedErrVal(nerr);//, k, -1);
+ 		OFPair<LONG, LONG> paircode = CreateEncodedValue(k, merrval);
+@@ -321,7 +321,7 @@ CTable InitTable(LONG k)
+ 	}
+ 
+ 	for (nerr = -1; ; nerr--)
+-	{		
++	{
+ 		// Q is not used when k != 0
+ 		LONG merrval = GetMappedErrVal(nerr);//, k, -1);
+ 		OFPair<LONG, LONG> paircode = CreateEncodedValue(k, merrval);
+@@ -364,7 +364,7 @@ inlinehint void JlsCodec<TRAITS,STRATEGY>::EncodeMappedValue(LONG k, LONG mapped
+ 		if (highbits + 1 > 31)
+ 		{
+ 			STRATEGY::AppendToBitStream(0, highbits / 2);
+-			highbits = highbits - highbits / 2;													
++			highbits = highbits - highbits / 2;
+ 		}
+ 		STRATEGY::AppendToBitStream(1, highbits + 1);
+ 		STRATEGY::AppendToBitStream((mappedError & ((1 << k) - 1)), k);
+@@ -374,11 +374,11 @@ inlinehint void JlsCodec<TRAITS,STRATEGY>::EncodeMappedValue(LONG k, LONG mapped
+ 	if (limit - traits.qbpp > 31)
+ 	{
+ 		STRATEGY::AppendToBitStream(0, 31);
+-		STRATEGY::AppendToBitStream(1, limit - traits.qbpp - 31);			
++		STRATEGY::AppendToBitStream(1, limit - traits.qbpp - 31);
+ 	}
+ 	else
+ 	{
+-		STRATEGY::AppendToBitStream(1, limit - traits.qbpp);			
++		STRATEGY::AppendToBitStream(1, limit - traits.qbpp);
+ 	}
+ 	STRATEGY::AppendToBitStream((mappedError - 1) & ((1 << traits.qbpp) - 1), traits.qbpp);
+ }
+@@ -389,33 +389,33 @@ inlinehint void JlsCodec<TRAITS,STRATEGY>::EncodeMappedValue(LONG k, LONG mapped
+ template<class TRAITS, class STRATEGY>
+ void JlsCodec<TRAITS,STRATEGY>::InitQuantizationLUT()
+ {
+-	// for lossless mode with default parameters, we have precomputed te luts for bitcounts 8,10,12 and 16 
++	// for lossless mode with default parameters, we have precomputed te luts for bitcounts 8,10,12 and 16
+ 	if (traits.NEAR == 0 && traits.MAXVAL == (1 << traits.bpp) - 1)
+ 	{
+ 		JlsCustomParameters presets = ComputeDefault(traits.MAXVAL, traits.NEAR);
+ 		if (presets.T1 == T1 && presets.T2 == T2 && presets.T3 == T3)
+ 		{
+-			if (traits.bpp == 8) 
++			if (traits.bpp == 8)
+ 			{
+-				_pquant = &rgquant8Ll[rgquant8Ll.size() / 2 ]; 
++				_pquant = &rgquant8Ll[rgquant8Ll.size() / 2 ];
+ 				return;
+ 			}
+-			if (traits.bpp == 10) 
++			if (traits.bpp == 10)
+ 			{
+-				_pquant = &rgquant10Ll[rgquant10Ll.size() / 2 ]; 
++				_pquant = &rgquant10Ll[rgquant10Ll.size() / 2 ];
+ 				return;
+-			}			
+-			if (traits.bpp == 12) 
++			}
++			if (traits.bpp == 12)
+ 			{
+-				_pquant = &rgquant12Ll[rgquant12Ll.size() / 2 ]; 
++				_pquant = &rgquant12Ll[rgquant12Ll.size() / 2 ];
+ 				return;
+-			}			
+-			if (traits.bpp == 16) 
++			}
++			if (traits.bpp == 16)
+ 			{
+-				_pquant = &rgquant16Ll[rgquant16Ll.size() / 2 ]; 
++				_pquant = &rgquant16Ll[rgquant16Ll.size() / 2 ];
+ 				return;
+-			}			
+-		}	
++			}
++		}
+ 	}
+ 
+ 	LONG RANGE = 1 << traits.bpp;
+@@ -453,7 +453,7 @@ template<class TRAITS, class STRATEGY>
+ LONG JlsCodec<TRAITS,STRATEGY>::DecodeRIError(CContextRunMode& ctx)
+ {
+ 	LONG k = ctx.GetGolomb();
+-	LONG EMErrval = DecodeValue(k, traits.LIMIT - J[_RUNindex]-1, traits.qbpp);	
++	LONG EMErrval = DecodeValue(k, traits.LIMIT - J[_RUNindex]-1, traits.qbpp);
+ 	LONG Errval = ctx.ComputeErrVal(EMErrval + ctx._nRItype, k);
+ 	ctx.UpdateVariables(Errval, EMErrval);
+ 	return Errval;
+@@ -466,7 +466,7 @@ void JlsCodec<TRAITS,STRATEGY>::EncodeRIError(CContextRunMode& ctx, LONG Errval)
+ {
+ 	LONG k			= ctx.GetGolomb();
+ 	bool map		= ctx.ComputeMap(Errval, k);
+-	LONG EMErrval	= 2 * ABS(Errval) - ctx._nRItype - map;	
++	LONG EMErrval	= 2 * ABS(Errval) - ctx._nRItype - map;
+ 
+ 	ASSERT(Errval == ctx.ComputeErrVal(EMErrval + ctx._nRItype, k));
+ 	EncodeMappedValue(k, EMErrval, traits.LIMIT-J[_RUNindex]-1);
+@@ -476,7 +476,7 @@ void JlsCodec<TRAITS,STRATEGY>::EncodeRIError(CContextRunMode& ctx, LONG Errval)
+ 
+ template<class TRAITS, class STRATEGY>
+ Triplet<OFTypename TRAITS::SAMPLE> JlsCodec<TRAITS,STRATEGY>::DecodeRIPixel(Triplet<SAMPLE> Ra, Triplet<SAMPLE> Rb)
+-{ 
++{
+ 	LONG Errval1 = DecodeRIError(_contextRunmode[0]);
+ 	LONG Errval2 = DecodeRIError(_contextRunmode[0]);
+ 	LONG Errval3 = DecodeRIError(_contextRunmode[0]);
+@@ -513,18 +513,18 @@ Triplet<OFTypename TRAITS::SAMPLE> JlsCodec<TRAITS,STRATEGY>::EncodeRIPixel(Trip
+ template<class TRAITS, class STRATEGY>
+ void JlsCodec<TRAITS,STRATEGY>::EncodeRunPixels(LONG runLength, bool endOfLine)
+ {
+-	while (runLength >= LONG(1 << J[_RUNindex])) 
++	while (runLength >= LONG(1 << J[_RUNindex]))
+ 	{
+ 		STRATEGY::AppendOnesToBitStream(1);
+ 		runLength = runLength - LONG(1 << J[_RUNindex]);
+ 		IncrementRunIndex();
+ 	}
+ 
+-	if (endOfLine) 
++	if (endOfLine)
+ 	{
+-		if (runLength != 0) 
++		if (runLength != 0)
+ 		{
+-			STRATEGY::AppendOnesToBitStream(1);	
++			STRATEGY::AppendOnesToBitStream(1);
+ 		}
+ 	}
+ 	else
+@@ -556,7 +556,7 @@ LONG JlsCodec<TRAITS,STRATEGY>::DecodeRunPixels(PIXEL Ra, PIXEL* startPos, LONG
+ 
+ 	if (index != cpixelMac)
+ 	{
+-		// incomplete run 	
++		// incomplete run
+ 		index += (J[_RUNindex] > 0) ? STRATEGY::ReadValue(J[_RUNindex]) : 0;
+ 	}
+ 
+@@ -566,7 +566,7 @@ LONG JlsCodec<TRAITS,STRATEGY>::DecodeRunPixels(PIXEL Ra, PIXEL* startPos, LONG
+ 	for (LONG i = 0; i < index; ++i)
+ 	{
+ 		startPos[i] = Ra;
+-	}	
++	}
+ 
+ 	return index;
+ }
+@@ -582,7 +582,7 @@ LONG JlsCodec<TRAITS,STRATEGY>::DoRunMode(LONG index, EncoderStrategy*)
+ 
+ 	LONG runLength = 0;
+ 
+-	while (traits.IsNear(ptypeCurX[runLength],Ra)) 
++	while (traits.IsNear(ptypeCurX[runLength],Ra))
+ 	{
+ 		ptypeCurX[runLength] = Ra;
+ 		runLength++;
+@@ -629,14 +629,24 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(SAMPLE*)
+ 	LONG index = 0;
+ 	LONG Rb = _previousLine[index-1];
+ 	LONG Rd = _previousLine[index];
++    LONG RANGE_UPPER = 1 << traits.bpp;
++    LONG RANGE_LOWER = - RANGE_UPPER;
+ 
+ 	while(index < _width)
+-	{	
++	{
+ 		LONG Ra = _currentLine[index -1];
+ 		LONG Rc = Rb;
+ 		Rb = Rd;
+ 		Rd = _previousLine[index + 1];
+ 
++        // make sure that values are not out of range
++        if (  (Rd - Rb < RANGE_LOWER) || (Rd - Rb > RANGE_UPPER)
++           || (Rb - Rc < RANGE_LOWER) || (Rb - Rc > RANGE_UPPER)
++           || (Rc - Ra < RANGE_LOWER) || (Rc - Ra > RANGE_UPPER))
++        {
++            throw JlsException(InvalidCompressedData);
++        }
++
+ 		LONG Qs = ComputeContextID(QuantizeGratient(Rd - Rb), QuantizeGratient(Rb - Rc), QuantizeGratient(Rc - Ra));
+ 
+ 		if (Qs != 0)
+@@ -648,8 +658,8 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(SAMPLE*)
+ 		{
+ 			index += DoRunMode(index, (STRATEGY*)(NULL));
+ 			Rb = _previousLine[index-1];
+-			Rd = _previousLine[index];	
+-		}				
++			Rd = _previousLine[index];
++		}
+ 	}
+ }
+ 
+@@ -661,7 +671,7 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(Triplet<SAMPLE>*)
+ {
+ 	LONG index = 0;
+ 	while(index < _width)
+-	{		
++	{
+ 		Triplet<SAMPLE> Ra = _currentLine[index -1];
+ 		Triplet<SAMPLE> Rc = _previousLine[index-1];
+ 		Triplet<SAMPLE> Rb = _previousLine[index];
+@@ -671,7 +681,7 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(Triplet<SAMPLE>*)
+ 		LONG Qs2 = ComputeContextID(QuantizeGratient(Rd.v2 - Rb.v2), QuantizeGratient(Rb.v2 - Rc.v2), QuantizeGratient(Rc.v2 - Ra.v2));
+ 		LONG Qs3 = ComputeContextID(QuantizeGratient(Rd.v3 - Rb.v3), QuantizeGratient(Rb.v3 - Rc.v3), QuantizeGratient(Rc.v3 - Ra.v3));
+ 
+-		
++
+ 		if (Qs1 == 0 && Qs2 == 0 && Qs3 == 0)
+ 		{
+ 			index += DoRunMode(index, (STRATEGY*)(NULL));
+@@ -684,19 +694,19 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(Triplet<SAMPLE>*)
+ 			Rx.v3 = DoRegular(Qs3, _currentLine[index].v3, GetPredictedValue(Ra.v3, Rb.v3, Rc.v3), (STRATEGY*)(NULL));
+ 			_currentLine[index] = Rx;
+ 			index++;
+-		}	
++		}
+ 	}
+ }
+ 
+ 
+-// DoScan: Encodes or decodes a scan. 
++// DoScan: Encodes or decodes a scan.
+ // In ILV_SAMPLE mode, multiple components are handled in DoLine
+ // In ILV_LINE mode, a call do DoLine is made for every component
+-// In ILV_NONE mode, DoScan is called for each component 
++// In ILV_NONE mode, DoScan is called for each component
+ 
+ template<class TRAITS, class STRATEGY>
+ void JlsCodec<TRAITS,STRATEGY>::DoScan(BYTE **ptr, size_t *size, size_t offset)
+-{		
++{
+ 	_width = Info().width;
+ 
+ 	STRATEGY::Init(ptr, size, offset);
+@@ -706,11 +716,11 @@ void JlsCodec<TRAITS,STRATEGY>::DoScan(BYTE **ptr, size_t *size, size_t offset)
+ 
+ 	OFVector<PIXEL> vectmp(2 * components * pixelstride);
+ 	OFVector<LONG> rgRUNindex(components);
+-	
++
+ 	for (LONG line = 0; line < Info().height; ++line)
+ 	{
+-		_previousLine			= &vectmp[1];	
+-		_currentLine			= &vectmp[1 + components * pixelstride];	
++		_previousLine			= &vectmp[1];
++		_currentLine			= &vectmp[1 + components * pixelstride];
+ 		if ((line & 1) == 1)
+ 		{
+ 			PIXEL *tmp = _previousLine;
+@@ -724,17 +734,17 @@ void JlsCodec<TRAITS,STRATEGY>::DoScan(BYTE **ptr, size_t *size, size_t offset)
+ 		for (int component = 0; component < components; ++component)
+ 		{
+ 			_RUNindex = rgRUNindex[component];
+-		
++
+ 			// initialize edge pixels used for prediction
+ 			_previousLine[_width]	= _previousLine[_width - 1];
+ 			_currentLine[-1]		= _previousLine[0];
+ 			DoLine((PIXEL*) NULL); // dummy arg for overload resolution
+-	
++
+ 			rgRUNindex[component] = _RUNindex;
+ 			_previousLine += pixelstride;
+ 			_currentLine += pixelstride;
+ 		}
+-		
++
+ 		if (_rect.Y <= line && line < _rect.Y + _rect.Height)
+ 		{
+ 			STRATEGY::OnLineEnd(_rect.Width, _currentLine + _rect.X - (components * pixelstride), pixelstride);
+@@ -754,7 +764,7 @@ ProcessLine* JlsCodec<TRAITS,STRATEGY>::CreateProcess(void* pvoidOut)
+ 		return new PostProcesSingleComponent(pvoidOut, Info(), sizeof(typename TRAITS::PIXEL));
+ 
+ 	if (Info().colorTransform == 0)
+-		return new ProcessTransformed<TransformNone<OFTypename TRAITS::SAMPLE> >(pvoidOut, Info(), TransformNone<SAMPLE>()); 
++		return new ProcessTransformed<TransformNone<OFTypename TRAITS::SAMPLE> >(pvoidOut, Info(), TransformNone<SAMPLE>());
+ 
+ 	if (Info().bitspersample == sizeof(SAMPLE)*8)
+ 	{
+@@ -765,7 +775,7 @@ ProcessLine* JlsCodec<TRAITS,STRATEGY>::CreateProcess(void* pvoidOut)
+ 			case COLORXFORM_HP3 : return new ProcessTransformed<TransformHp3<SAMPLE> >(pvoidOut, Info(), TransformHp3<SAMPLE>()); break;
+ 			default: throw JlsException(UnsupportedColorTransform);
+ 		}
+-	} 
++	}
+ 	else if (Info().bitspersample > 8)
+ 	{
+ 		int shift = 16 - Info().bitspersample;
+@@ -796,7 +806,7 @@ size_t JlsCodec<TRAITS,STRATEGY>::EncodeScan(const void* rawData, BYTE **ptr, si
+ 	}
+ 
+ 	DoScan(ptr, size, offset);
+-	
++
+ 	return	STRATEGY::GetLength();
+ 
+ }
+@@ -827,7 +837,7 @@ size_t JlsCodec<TRAITS,STRATEGY>::DecodeScan(void* rawData, const JlsRect& rect,
+ 	_rect = rect;
+ 
+ 	DoScan(ptr, size, offset + readBytes);
+-	
++
+ 	return STRATEGY::GetCurBytePos() - (*ptr + offset);
+ }
+ 


=====================================
debian/patches/0014-CVE-2025-9732.patch
=====================================
@@ -0,0 +1,398 @@
+commit 7ad81d69b19714936e18ea5fc74edaeb9f021ce7
+Author: Joerg Riesmeier <dicom at jriesmeier.com>
+Date:   Fri Aug 15 13:35:40 2025 +0200
+
+    Fixed issue with invalid "YBR_FULL" DICOM images.
+    
+    Fixed an issue when processing an invalid DICOM image with a Photometric
+    Interpretation of "YBR_FULL" and a Planar Configuration of "1" where
+    the number of pixels stored does not match the expected number of pixels
+    (much too less). Now, the pixel data of such an image is not processed
+    at all, but an empty image (black pixels) is created instead. The user
+    is warned about this by an appropriate log message.
+    
+    Thanks to Ding zhengzheng <xiaozheng.ding399 at gmail.com> for the report
+    and the sample file (PoC).
+
+--- dcmtk.orig/dcmimage/include/dcmtk/dcmimage/dicopxt.h
++++ dcmtk/dcmimage/include/dcmtk/dcmimage/dicopxt.h
+@@ -574,7 +574,11 @@
+                 {
+                     /* erase empty part of the buffer (=blacken the background) */
+                     if (InputCount < Count)
+-                        OFBitmanipTemplate<T>::zeroMem(Data[j] + InputCount, Count - InputCount);
++                    {
++                        const size_t count = (Count - InputCount);
++                        DCMIMAGE_TRACE("filing empty part of the intermediate pixel data (" << count << " pixels) of plane " << j << " with value = 0");
++                        OFBitmanipTemplate<T>::zeroMem(Data[j] + InputCount, count);
++                    }
+                 } else {
+                     DCMIMAGE_DEBUG("cannot allocate memory buffer for 'Data[" << j << "]' in DiColorPixelTemplate::Init()");
+                     result = 0;     // at least one buffer could not be allocated!
+--- dcmtk.orig/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
++++ dcmtk/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
+@@ -1,6 +1,6 @@
+ /*
+  *
+- *  Copyright (C) 1998-2016, OFFIS e.V.
++ *  Copyright (C) 1998-2025, OFFIS e.V.
+  *  All rights reserved.  See COPYRIGHT file for details.
+  *
+  *  This software and supporting documentation were developed by
+@@ -24,6 +24,7 @@
+ #define DIYBRPXT_H
+ 
+ #include "dcmtk/config/osconfig.h"
++#include "dcmtk/ofstd/ofbmanip.h"
+ 
+ #include "dcmtk/dcmimage/dicopxt.h"
+ #include "dcmtk/dcmimgle/diinpx.h"  /* gcc 3.4 needs this */
+@@ -90,179 +91,189 @@
+             // use the number of input pixels derived from the length of the 'PixelData'
+             // attribute), but not more than the size of the intermediate buffer
+             const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count;
+-            if (rgb)    /* convert to RGB model */
++            // make sure that there is sufficient input data (for planar pixel data)
++            if (!this->PlanarConfiguration || (count >= planeSize * 3 /* number of planes */))
+             {
+-                T2 *r = this->Data[0];
+-                T2 *g = this->Data[1];
+-                T2 *b = this->Data[2];
+-                const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
+-                DiPixelRepresentationTemplate<T1> rep;
+-                if (bits == 8 && !rep.isSigned())          // only for unsigned 8 bit
++                if (rgb)    /* convert to RGB model */
+                 {
+-                    Sint16 rcr_tab[256];
+-                    Sint16 gcb_tab[256];
+-                    Sint16 gcr_tab[256];
+-                    Sint16 bcb_tab[256];
+-                    const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
+-                    const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
+-                    const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
+-                    unsigned long l;
+-                    for (l = 0; l < 256; ++l)
++                    T2 *r = this->Data[0];
++                    T2 *g = this->Data[1];
++                    T2 *b = this->Data[2];
++                    const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
++                    DiPixelRepresentationTemplate<T1> rep;
++                    if (bits == 8 && !rep.isSigned())          // only for unsigned 8 bit
+                     {
+-                        rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
+-                        gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
+-                        gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
+-                        bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
+-                    }
+-                    Sint32 sr;
+-                    Sint32 sg;
+-                    Sint32 sb;
+-                    if (this->PlanarConfiguration)
+-                    {
+-/*
+-                        const T1 *y = pixel;
+-                        const T1 *cb = y + this->InputCount;
+-                        const T1 *cr = cb + this->InputCount;
+-                        for (i = count; i != 0; --i, ++y, ++cb, ++cr)
++                        Sint16 rcr_tab[256];
++                        Sint16 gcb_tab[256];
++                        Sint16 gcr_tab[256];
++                        Sint16 bcb_tab[256];
++                        const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
++                        const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
++                        const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
++                        unsigned long l;
++                        for (l = 0; l < 256; ++l)
+                         {
+-                            sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
+-                            sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
+-                            sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
+-                            *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
+-                            *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
+-                            *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
++                            rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
++                            gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
++                            gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
++                            bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
+                         }
++                        Sint32 sr;
++                        Sint32 sg;
++                        Sint32 sb;
++                        if (this->PlanarConfiguration)
++                        {
++/*
++                            const T1 *y = pixel;
++                            const T1 *cb = y + this->InputCount;
++                            const T1 *cr = cb + this->InputCount;
++                            for (i = count; i != 0; --i, ++y, ++cb, ++cr)
++                            {
++                                sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
++                                sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
++                                sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
++                                *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
++                                *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
++                                *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
++                            }
+ */
+-                        const T1 *y = pixel;
+-                        const T1 *cb = y + planeSize;
+-                        const T1 *cr = cb + planeSize;
+-                        unsigned long i = count;
+-                        while (i != 0)
++                            const T1 *y = pixel;
++                            const T1 *cb = y + planeSize;
++                            const T1 *cr = cb + planeSize;
++                            unsigned long i = count;
++                            while (i != 0)
++                            {
++                                /* convert a single frame */
++                                for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
++                                {
++                                    sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
++                                    sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
++                                    sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
++                                    *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
++                                    *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
++                                    *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
++                                }
++                                /* jump to next frame start (skip 2 planes) */
++                                y += 2 * planeSize;
++                                cb += 2 * planeSize;
++                                cr += 2 * planeSize;
++                            }
++                        }
++                        else
+                         {
+-                            /* convert a single frame */
+-                            for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
++                            const T1 *p = pixel;
++                            T1 y;
++                            T1 cb;
++                            T1 cr;
++                            unsigned long i;
++                            for (i = count; i != 0; --i)
+                             {
+-                                sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, *cr)]);
+-                                sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, *cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, *cr)]);
+-                                sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, *cb)]);
++                                y  = *(p++);
++                                cb = *(p++);
++                                cr = *(p++);
++                                sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[cr]);
++                                sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[cb]) - OFstatic_cast(Sint32, gcr_tab[cr]);
++                                sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[cb]);
+                                 *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
+                                 *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
+                                 *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
+                             }
+-                            /* jump to next frame start (skip 2 planes) */
+-                            y += 2 * planeSize;
+-                            cb += 2 * planeSize;
+-                            cr += 2 * planeSize;
+                         }
+                     }
+                     else
+                     {
+-                        const T1 *p = pixel;
+-                        T1 y;
+-                        T1 cb;
+-                        T1 cr;
+-                        unsigned long i;
+-                        for (i = count; i != 0; --i)
++                        if (this->PlanarConfiguration)
++                        {
++/*
++                            const T1 *y = pixel;
++                            const T1 *cb = y + this->InputCount;
++                            const T1 *cr = cb + this->InputCount;
++                            for (i = count; i != 0; --i)
++                                convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
++                                    removeSign(*(cr++), offset), maxvalue);
++*/
++                            unsigned long l;
++                            unsigned long i = count;
++                            const T1 *y = pixel;
++                            const T1 *cb = y + planeSize;
++                            const T1 *cr = cb + planeSize;
++                            while (i != 0)
++                            {
++                                /* convert a single frame */
++                                for (l = planeSize; (l != 0) && (i != 0); --l, --i)
++                                {
++                                    convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
++                                        removeSign(*(cr++), offset), maxvalue);
++                                }
++                                /* jump to next frame start (skip 2 planes) */
++                                y += 2 * planeSize;
++                                cb += 2 * planeSize;
++                                cr += 2 * planeSize;
++                            }
++                        }
++                        else
+                         {
+-                            y  = *(p++);
+-                            cb = *(p++);
+-                            cr = *(p++);
+-                            sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, cr)]);
+-                            sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, cr)]);
+-                            sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, cb)]);
+-                            *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
+-                            *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
+-                            *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
++                            const T1 *p = pixel;
++                            T2 y;
++                            T2 cb;
++                            T2 cr;
++                            unsigned long i;
++                            for (i = count; i != 0; --i)
++                            {
++                                y = removeSign(*(p++), offset);
++                                cb = removeSign(*(p++), offset);
++                                cr = removeSign(*(p++), offset);
++                                convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
++                            }
+                         }
+                     }
+-                }
+-                else
+-                {
++                } else {    /* retain YCbCr model */
++                    const T1 *p = pixel;
+                     if (this->PlanarConfiguration)
+                     {
+-/*
+-                        const T1 *y = pixel;
+-                        const T1 *cb = y + this->InputCount;
+-                        const T1 *cr = cb + this->InputCount;
+-                        for (i = count; i != 0; --i)
+-                            convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
+-                                removeSign(*(cr++), offset), maxvalue);
+-*/
++    /*
++                        T2 *q;
++                        // number of pixels to be skipped (only applicable if 'PixelData' contains more
++                        // pixels than expected)
++                        const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
++                        for (int j = 0; j < 3; ++j)
++                        {
++                            q = this->Data[j];
++                            for (i = count; i != 0; --i)
++                                *(q++) = removeSign(*(p++), offset);
++                            // skip to beginning of next plane
++                            p += skip;
++                        }
++    */
+                         unsigned long l;
+-                        unsigned long i = count;
+-                        const T1 *y = pixel;
+-                        const T1 *cb = y + planeSize;
+-                        const T1 *cr = cb + planeSize;
+-                        while (i != 0)
++                        unsigned long i = 0;
++                        while (i < count)
+                         {
+-                            /* convert a single frame */
+-                            for (l = planeSize; (l != 0) && (i != 0); --l, --i)
++                            /* store current pixel index */
++                            const unsigned long iStart = i;
++                            for (int j = 0; j < 3; ++j)
+                             {
+-                                convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
+-                                    removeSign(*(cr++), offset), maxvalue);
++                                /* convert a single plane */
++                                for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
++                                    this->Data[j][i] = removeSign(*(p++), offset);
+                             }
+-                            /* jump to next frame start (skip 2 planes) */
+-                            y += 2 * planeSize;
+-                            cb += 2 * planeSize;
+-                            cr += 2 * planeSize;
+                         }
+                     }
+                     else
+                     {
+-                        const T1 *p = pixel;
+-                        T2 y;
+-                        T2 cb;
+-                        T2 cr;
++                        int j;
+                         unsigned long i;
+-                        for (i = count; i != 0; --i)
+-                        {
+-                            y = removeSign(*(p++), offset);
+-                            cb = removeSign(*(p++), offset);
+-                            cr = removeSign(*(p++), offset);
+-                            convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
+-                        }
++                        for (i = 0; i < count; ++i)                             /* for all pixel ... */
++                            for (j = 0; j < 3; ++j)
++                                this->Data[j][i] = removeSign(*(p++), offset);  /* ... copy planes */
+                     }
+                 }
+-            } else {    /* retain YCbCr model */
+-                const T1 *p = pixel;
+-                if (this->PlanarConfiguration)
+-                {
+-/*
+-                    T2 *q;
+-                    // number of pixels to be skipped (only applicable if 'PixelData' contains more
+-                    // pixels than expected)
+-                    const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
+-                    for (int j = 0; j < 3; ++j)
+-                    {
+-                        q = this->Data[j];
+-                        for (i = count; i != 0; --i)
+-                            *(q++) = removeSign(*(p++), offset);
+-                        // skip to beginning of next plane
+-                        p += skip;
+-                    }
+-*/
+-                    unsigned long l;
+-                    unsigned long i = 0;
+-                    while (i < count)
+-                    {
+-                        /* store current pixel index */
+-                        const unsigned long iStart = i;
+-                        for (int j = 0; j < 3; ++j)
+-                        {
+-                            /* convert a single plane */
+-                            for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
+-                                this->Data[j][i] = removeSign(*(p++), offset);
+-                        }
+-                    }
+-                }
+-                else
+-                {
+-                    int j;
+-                    unsigned long i;
+-                    for (i = 0; i < count; ++i)                             /* for all pixel ... */
+-                        for (j = 0; j < 3; ++j)
+-                            this->Data[j][i] = removeSign(*(p++), offset);  /* ... copy planes */
+-                }
++            } else {
++                // do not process the input data, as it is too short
++                DCMIMAGE_WARN("input data is too short, filling the complete image with black pixels");
++                // erase empty part of the buffer (that has not been "blackened" yet)
++                for (int j = 0; j < 3; ++j)
++                    OFBitmanipTemplate<T2>::zeroMem(this->Data[j], count);
+             }
+         }
+     }
+--- dcmtk.orig/dcmimgle/libsrc/dcmimage.cc
++++ dcmtk/dcmimgle/libsrc/dcmimage.cc
+@@ -1,6 +1,6 @@
+ /*
+  *
+- *  Copyright (C) 1996-2021, OFFIS e.V.
++ *  Copyright (C) 1996-2025, OFFIS e.V.
+  *  All rights reserved.  See COPYRIGHT file for details.
+  *
+  *  This software and supporting documentation were developed by
+@@ -210,6 +210,7 @@
+                         *(q++) = c;
+                 }
+                 *q = '\0';                                          // end of C string
++                DCMIMGLE_DEBUG("filtered version of 'PhotometricInterpretation' = " << OFSTRING_GUARD(cstr));
+                 while ((pin->Name != NULL) && (strcmp(pin->Name, cstr) != 0))
+                     ++pin;
+                 delete[] cstr;


=====================================
debian/patches/0015-CVE-2025-9732b.patch
=====================================
@@ -0,0 +1,40 @@
+commit 3de96da6cd66b1af7224561c568bc3de50cd1398
+Author: Joerg Riesmeier <dicom at jriesmeier.com>
+Date:   Mon Aug 18 17:58:56 2025 +0200
+
+    Fixed issue with commit 7ad81d69b.
+    
+    Fixed an issue with recently committed changes that fix a problem with
+    invalid YBR_FULL images
+
+diff --git a/dcmimage/include/dcmtk/dcmimage/diybrpxt.h b/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
+index c5415c149..fdaaafc2d 100644
+--- a/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
++++ b/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
+@@ -92,7 +92,7 @@ class DiYBRPixelTemplate
+             // attribute), but not more than the size of the intermediate buffer
+             const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count;
+             // make sure that there is sufficient input data (for planar pixel data)
+-            if (!this->PlanarConfiguration || (count >= planeSize * 3 /* number of planes */))
++            if (!this->PlanarConfiguration || (count >= planeSize))
+             {
+                 if (rgb)    /* convert to RGB model */
+                 {
+@@ -231,7 +231,7 @@ class DiYBRPixelTemplate
+                     const T1 *p = pixel;
+                     if (this->PlanarConfiguration)
+                     {
+-    /*
++/*
+                         T2 *q;
+                         // number of pixels to be skipped (only applicable if 'PixelData' contains more
+                         // pixels than expected)
+@@ -244,7 +244,7 @@ class DiYBRPixelTemplate
+                             // skip to beginning of next plane
+                             p += skip;
+                         }
+-    */
++*/
+                         unsigned long l;
+                         unsigned long i = 0;
+                         while (i < count)


=====================================
debian/patches/0016-CVE-2025-14607.patch
=====================================
@@ -0,0 +1,31 @@
+commit 4c0e5c10079392c594d6a7abd95dd78ac0aa556a
+Author: Marco Eichelberg <eichelberg at offis.de>
+Date:   Tue Dec 2 09:06:30 2025 +0100
+
+    Fixed bug in handling of odd-length data elements.
+    
+    When a dataset containing an illegal odd-length attribute with a text VR
+    was read from file or received over a network connection, then accessing
+    the value of that attribute with DcmElement::getString() may return a
+    pointer to a string that was not properly null terminated. Using C string
+    functions such as strlen() or strcpy() on that string then lead to a read
+    beyond the end of a string, causing a segmentation fault.
+    
+    Thanks to Zou Dikai <zoudikai at outlook.com> for the bug report and POC.
+    
+    This closes DCMTK issue #1184.
+
+--- dcmtk.orig/dcmdata/libsrc/dcbytstr.cc
++++ dcmtk/dcmdata/libsrc/dcbytstr.cc
+@@ -658,7 +658,11 @@
+ 
+         /* terminate string after real length */
+         if (value != NULL)
++        {
+             value[lengthField] = 0;
++            value[lengthField+1] = 0;
++        }
++
+         /* enforce old (pre DCMTK 3.5.2) behaviour? */
+         if (!dcmAcceptOddAttributeLength.get())
+         {


=====================================
debian/patches/0017-CVE-2025-14841.patch
=====================================
@@ -0,0 +1,37 @@
+commit ffb1a4a37d2c876e3feeb31df4930f2aed7fa030
+Author: Marco Eichelberg <eichelberg at offis.de>
+Date:   Fri Nov 28 12:24:07 2025 +0100
+
+    Fixed two possible segfaults in dcmqrscp.
+    
+    Fixed two places where invalid messages may trigger a segmentation fault
+    due to a NULL pointer being de-referenced.
+    
+    Thanks to 邹 迪凯 <zoudikai at outlook.com> for the bug report and proof-of-concept.
+
+--- dcmtk.orig/dcmqrdb/libsrc/dcmqrdbi.cc
++++ dcmtk/dcmqrdb/libsrc/dcmqrdbi.cc
+@@ -1381,8 +1381,10 @@
+                 /* only char string type tags are supported at the moment */
+                 char *s = NULL;
+                 dcelem->getString(s);
++
+                 /* the available space is always elem.ValueLength+1 */
+-                OFStandard::strlcpy(elem.PValueField, s, elem.ValueLength+1);
++                if (s) OFStandard::strlcpy(elem.PValueField, s, elem.ValueLength+1);
++                    else elem.PValueField[0]='\0';
+             }
+             /** If element is the Query Level, store it in handle
+              */
+@@ -2066,8 +2068,10 @@
+                 /* only char string type tags are supported at the moment */
+                 char *s = NULL;
+                 dcelem->getString(s);
++
+                 /* the available space is always elem.ValueLength+1 */
+-                OFStandard::strlcpy(elem.PValueField, s, elem.ValueLength+1);
++                if (s) OFStandard::strlcpy(elem.PValueField, s, elem.ValueLength+1);
++                    else elem.PValueField[0]='\0';
+             }
+ 
+             /** If element is the Query Level, store it in handle


=====================================
debian/patches/0018-CVE-2026-5663.patch
=====================================
@@ -0,0 +1,274 @@
+commit edbb085e45788dccaf0e64d71534cfca925784b8
+Author: Marco Eichelberg <eichelberg at offis.de>
+Date:   Sat Mar 21 18:35:14 2026 +0100
+
+    Sanitize all strings passed to the exec options.
+    
+    Sanitize the text fields from incoming DICOM associations and DICOM objects
+    (such as Study Instance UID, SOP Instance UID, Patient's Name) and the
+    calling SCU's network presentation address by removing special characters
+    that may be interpreted as shell escape characters when one of the
+    execution options (e.g. --exec-on-reception) is in use.
+    
+    Thanks to Machine Spirits UG (haftungsbeschränkt) for the bug report,
+    detailed analysis and proof of concept.
+    
+    This closes DCMTK issue #1194.
+
+--- dcmtk.orig/dcmnet/apps/storescp.cc
++++ dcmtk/dcmnet/apps/storescp.cc
+@@ -1,6 +1,6 @@
+ /*
+  *
+- *  Copyright (C) 1994-2021, OFFIS e.V.
++ *  Copyright (C) 1994-2026, OFFIS e.V.
+  *  All rights reserved.  See COPYRIGHT file for details.
+  *
+  *  This software and supporting documentation were developed by
+@@ -201,6 +201,41 @@
+ #define SHORTCOL 4
+ #define LONGCOL 21
+ 
++// Allow list used by sanitizeAETitle(). Index is (byte - 32), so the
++// table covers the printable ASCII range 0x20..0x7E. Every entry either
++// repeats the input byte (kept) or is '_' (replaced). Kept characters:
++// space, '-', '.', ':', '@', '_' and ASCII letters/digits. All shell
++// metacharacters and path separators map to '_'.
++static const char sanitized_aetitle_charset[] =
++{
++  ' ', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '-', '.', '_',
++  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '_', '_', '_', '_', '_',
++  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
++  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '_', '_', '_', '_',
++  '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
++  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_', '_', '_', '_', '_'
++};
++
++
++inline void sanitizeAETitle(OFString& aetitle)
++{
++    // Preserve a surrounding pair of quotation marks (used by callers
++    // that substitute the AE title into an already quoted shell argument).
++    size_t len = aetitle.length();
++    size_t start = 0;
++    if (len >= 2 && aetitle[0] == '"' && aetitle[len - 1] == '"')
++    {
++        start = 1;
++        --len;
++    }
++    for (size_t i = start; i < len; ++i)
++    {
++        unsigned char c = OFstatic_cast(unsigned char, aetitle[i]);
++        if (c < 32 || c >= 127) aetitle[i] = '_';
++        else aetitle[i] = sanitized_aetitle_charset[c - 32];
++    }
++}
++
+ int main(int argc, char *argv[])
+ {
+   T_ASC_Network *net;
+@@ -1474,7 +1509,9 @@
+     calledAETitle.clear();
+   }
+   // store calling presentation address (i.e. remote hostname)
+-  callingPresentationAddress = OFSTRING_GUARD(assoc->params->DULparams.callingPresentationAddress);
++  callingPresentationAddress = "\"";
++  callingPresentationAddress += OFSTRING_GUARD(assoc->params->DULparams.callingPresentationAddress);
++  callingPresentationAddress += "\"";
+ 
+   /* now do the real work, i.e. receive DIMSE commands over the network connection */
+   /* which was established and handle these commands correspondingly. In case of */
+@@ -1838,6 +1875,7 @@
+             dateTime.getTime().getHour(), dateTime.getTime().getMinute(), dateTime.getTime().getIntSecond(), dateTime.getTime().getMilliSecond());
+ 
+           OFString subdirectoryName;
++          OFString s;
+           switch (opt_sortStudyMode)
+           {
+             case ESM_Timestamp:
+@@ -1852,15 +1890,27 @@
+               subdirectoryName = opt_sortStudyDirPrefix;
+               if (!subdirectoryName.empty())
+                 subdirectoryName += '_';
+-              subdirectoryName += currentStudyInstanceUID;
+-              OFStandard::sanitizeFilename(subdirectoryName);
++              s = currentStudyInstanceUID;
++              OFStandard::sanitizeFilename(s);
++              if (s != currentStudyInstanceUID)
++              {
++                OFLOG_WARN(storescpLogger, "Sanitized unusual characters in Study Instance UID, converted from \"" << currentStudyInstanceUID << "\" to \"" << s << "\".");
++              }
++              subdirectoryName += s;
+               break;
+             case ESM_PatientName:
+               // pattern: "[Patient's Name]_[YYYYMMDD]_[HHMMSSMMM]"
+               subdirectoryName = currentPatientName;
++              OFStandard::sanitizeFilename(subdirectoryName);
++              if (subdirectoryName != currentPatientName)
++              {
++                // It is quite normal that we need to sanitize characters in PatientName.
++                // Therefore, this is only a debug message and not a warning, unlike the other
++                // messages about sanitized fields, which are normally not expected.
++                OFLOG_DEBUG(storescpLogger, "Sanitized characters in Patient Name, converted from \"" << currentPatientName << "\" to \"" << subdirectoryName << "\".");
++              }
+               subdirectoryName += '_';
+               subdirectoryName += timestamp;
+-              OFStandard::sanitizeFilename(subdirectoryName);
+               break;
+             case ESM_None:
+               break;
+@@ -2068,8 +2118,13 @@
+     else
+     {
+       // Use the SOP instance UID as found in the C-STORE request message as part of the filename
+-      OFString uid = req->AffectedSOPInstanceUID;
++      OFString s(OFSTRING_GUARD(req->AffectedSOPInstanceUID));
++      OFString uid = s;
+       OFStandard::sanitizeFilename(uid);
++      if (uid != s)
++      {
++        OFLOG_WARN(storescpLogger, "Sanitized unusual characters in SOP Instance UID, converted from \"" << s << "\" to \"" << uid << "\".");
++      }
+       sprintf(imageFileName, "%s%c%s.%s%s", opt_outputDirectory.c_str(), PATH_SEPARATOR, dcmSOPClassUIDToModality(req->AffectedSOPClassUID, "UNKNOWN"),
+         uid.c_str(), opt_fileNameExtension.c_str());
+     }
+@@ -2202,28 +2257,40 @@
+      */
+ {
+   OFString cmd = opt_execOnReception;
++  OFString s;
+ 
+   // in case a file was actually written
+   if( !opt_ignore )
+   {
+     // perform substitution for placeholder #p (depending on presence of any --sort-xxx option)
++    // Note: We do not enclose this in quotes because it may be used as part of a path expression.
+     OFString dir = (opt_sortStudyMode == ESM_None) ? opt_outputDirectory : subdirectoryPathAndName;
+     cmd = replaceChars( cmd, OFString(PATH_PLACEHOLDER), dir );
+ 
+     // perform substitution for placeholder #f; note that outputFileNameArray.back()
+     // always contains the name of the file (without path) which was written last.
++    // Note: We do not enclose this in quotes because it may be used as part of a path expression.
+     OFString outputFileName = outputFileNameArray.back();
+     cmd = replaceChars( cmd, OFString(FILENAME_PLACEHOLDER), outputFileName );
+   }
+ 
+-  // perform substitution for placeholder #a
++  // perform substitution for placeholder #a.
++  // Note that this string is already enclosed in double quotes at this point
+   cmd = replaceChars( cmd, OFString(CALLING_AETITLE_PLACEHOLDER), callingAETitle );
+ 
+-  // perform substitution for placeholder #c
++  // perform substitution for placeholder #c.
++  // Note that this string is already enclosed in double quotes at this point
+   cmd = replaceChars( cmd, OFString(CALLED_AETITLE_PLACEHOLDER), calledAETitle );
+ 
+-  // perform substitution for placeholder #r
+-  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), callingPresentationAddress );
++  // perform substitution for placeholder #r.
++  // Note that this string is already enclosed in double quotes at this point
++  s = callingPresentationAddress;
++  sanitizeAETitle(s);
++  if (s != callingPresentationAddress)
++  {
++    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in calling presentation address, converted from " << callingPresentationAddress << " to " << s << ".");
++  }
++  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), s );
+ 
+   // Execute command in a new process
+   executeCommand( cmd );
+@@ -2325,18 +2392,41 @@
+      */
+ {
+   OFString cmd = opt_execOnEndOfStudy;
++  OFString s;
+ 
+   // perform substitution for placeholder #p; #p will be substituted by lastStudySubdirectoryPathAndName
++  // Note: We do not enclose this in quotes because it may be used as part of a path expression.
+   cmd = replaceChars( cmd, OFString(PATH_PLACEHOLDER), lastStudySubdirectoryPathAndName );
+ 
+-  // perform substitution for placeholder #a
+-  cmd = replaceChars( cmd, OFString(CALLING_AETITLE_PLACEHOLDER), callingAETitle );
++  // perform substitution for placeholder #a.
++  // Note that this string is already enclosed in double quotes at this point
++  s = callingAETitle;
++  sanitizeAETitle(s);
++  if (s != callingAETitle)
++  {
++    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in calling aetitle, converted from " << callingAETitle << " to " << s << ".");
++  }
++  cmd = replaceChars( cmd, OFString(CALLING_AETITLE_PLACEHOLDER), s );
+ 
+-  // perform substitution for placeholder #c
+-  cmd = replaceChars( cmd, OFString(CALLED_AETITLE_PLACEHOLDER), calledAETitle );
++  // perform substitution for placeholder #c.
++  // Note that this string is already enclosed in double quotes at this point
++  s = calledAETitle;
++  sanitizeAETitle(s);
++  if (s != calledAETitle)
++  {
++    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in called aetitle, converted from " << calledAETitle << " to " << s << ".");
++  }
++  cmd = replaceChars( cmd, OFString(CALLED_AETITLE_PLACEHOLDER), s );
+ 
+-  // perform substitution for placeholder #r
+-  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), callingPresentationAddress );
++  // perform substitution for placeholder #r.
++  // Note that this string is already enclosed in double quotes at this point
++  s = callingPresentationAddress;
++  sanitizeAETitle(s);
++  if (s != callingPresentationAddress)
++  {
++    OFLOG_WARN(storescpLogger, "Sanitized unusual characters in calling presentation address, converted from " << callingPresentationAddress << " to " << s << ".");
++  }
++  cmd = replaceChars( cmd, OFString(CALLING_PRESENTATION_ADDRESS_PLACEHOLDER), s );
+ 
+   // Execute command in a new process
+   executeCommand( cmd );
+--- dcmtk.orig/ofstd/libsrc/ofstd.cc
++++ dcmtk/ofstd/libsrc/ofstd.cc
+@@ -3246,16 +3246,26 @@
+ }
+ 
+ 
++static const char sanitized_filename_charset[] =
++{
++  ' ', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '-', '.', '_',
++  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '_', '_', '_', '_', '_',
++  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
++  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', '_', '_', '_', '_',
++  '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
++  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_', '_', '_', '_', '_'
++};
++
++
+ void OFStandard::sanitizeFilename(OFString& fname)
+ {
+   size_t len = fname.length();
++  char c;
+   for (size_t i=0; i<len; ++i)
+   {
+-#ifdef _WIN32
+-        if ((fname[i] == PATH_SEPARATOR)||(fname[i] == '/')) fname[i] = '_';
+-#else
+-        if (fname[i] == PATH_SEPARATOR) fname[i] = '_';
+-#endif
++        c = fname[i];
++        if (c != 0 && (c < 32 || c >= 127)) c = '_'; else c = sanitized_filename_charset[c-32];
++        fname[i] = c;
+   }
+ }
+ 
+@@ -3267,11 +3277,7 @@
+     char *c = fname;
+     while (*c)
+     {
+-#ifdef _WIN32
+-      if ((*c == PATH_SEPARATOR)||(*c == '/')) *c = '_';
+-#else
+-      if (*c == PATH_SEPARATOR) *c = '_';
+-#endif
++      if (*c < 32 || *c >= 127) *c = '_'; else *c = sanitized_filename_charset[*c-32];
+       ++c;
+     }
+   }


=====================================
debian/patches/0019-CVE-2026-10194.patch
=====================================
@@ -0,0 +1,66 @@
+commit 0f78a4ef6f645ea5530166e445e5436a5de58e75
+Author: Marco Eichelberg <eichelberg at offis.de>
+Date:   Mon May 4 17:48:30 2026 +0200
+
+    Fixed remote heap buffer overflow in dcmqrscp.
+    
+    Thanks to 'elp3pinill0' for the bug report, detailed
+    analysis, proof of concept and proposed fix.
+    
+    This closes DCMTK issue #1206.
+
+--- dcmtk.orig/dcmqrdb/libsrc/dcmqrdbi.cc
++++ dcmtk/dcmqrdb/libsrc/dcmqrdbi.cc
+@@ -1,6 +1,6 @@
+ /*
+  *
+- *  Copyright (C) 1993-2022, OFFIS e.V.
++ *  Copyright (C) 1993-2026, OFFIS e.V.
+  *  All rights reserved.  See COPYRIGHT file for details.
+  *
+  *  This software and supporting documentation were developed by
+@@ -2475,12 +2475,16 @@
+ 
+     DB_IdxInitLoop (&(handle_ -> idxCounter)) ;
+     while ( DB_IdxGetNext(&(handle_ -> idxCounter), &idxRec) == EC_Normal ) {
+-    if ( ! ( strncmp(idxRec. StudyInstanceUID, StudyUID, n) ) ) {
+-
+-        StudyArray[nbimages]. idxCounter = handle_ -> idxCounter ;
+-        StudyArray[nbimages]. RecordedDate = idxRec. RecordedDate ;
+-        StudyArray[nbimages++]. ImageSize = idxRec. ImageSize ;
+-    }
++        if ( ! ( strncmp(idxRec. StudyInstanceUID, StudyUID, n) ) ) {
++            StudyArray[nbimages]. idxCounter = handle_ -> idxCounter ;
++            StudyArray[nbimages]. RecordedDate = idxRec. RecordedDate ;
++            StudyArray[nbimages++]. ImageSize = idxRec. ImageSize ;
++            if (nbimages == MAX_NUMBER_OF_IMAGES) {
++                // too many images in this study, bail out
++                DCMQRDB_ERROR("maximum number of images per study (" << MAX_NUMBER_OF_IMAGES << ") exceeded");
++                return QR_EC_IndexDatabaseError;
++            }
++        }
+     }
+ 
+     /** Sort the StudyArray in order to have the oldest images first
+@@ -2567,6 +2571,8 @@
+     s = matchStudyUIDInStudyDesc (pStudyDesc, StudyUID,
+                      (int)(handle_ -> maxStudiesAllowed)) ;
+ 
++    OFCondition cond;
++
+     /** If Study already exists
+      */
+ 
+@@ -2587,10 +2593,10 @@
+ 
+         RequiredSize = imageSize -
+             ( handle_ -> maxBytesPerStudy - pStudyDesc[s]. StudySize ) ;
+-        deleteOldestImages(pStudyDesc, s, StudyUID, RequiredSize) ;
++        cond = deleteOldestImages(pStudyDesc, s, StudyUID, RequiredSize) ;
++        if (cond.bad()) return cond;
+     }
+ 
+-
+     }
+     else {
+ #ifdef DEBUG


=====================================
debian/patches/series
=====================================
@@ -21,3 +21,11 @@ c34f4e46e672ad21accf04da0dc085e43be6f5e1.patch
 0009-CVE-2025-25475.patch
 0010-CVE-2025-25474.patch
 0011-CVE-2025-25472.patch
+0012-CVE-2022-4981.patch
+0013-CVE-2025-2357.patch
+0014-CVE-2025-9732.patch
+0015-CVE-2025-9732b.patch
+0016-CVE-2025-14607.patch
+0017-CVE-2025-14841.patch
+0018-CVE-2026-5663.patch
+0019-CVE-2026-10194.patch



View it on GitLab: https://salsa.debian.org/med-team/dcmtk/-/compare/895d58dedeed1d92ea5221ee6129e9479d6efb18...b247b97c9820fb692e068653719750f5cdc46f35

-- 
View it on GitLab: https://salsa.debian.org/med-team/dcmtk/-/compare/895d58dedeed1d92ea5221ee6129e9479d6efb18...b247b97c9820fb692e068653719750f5cdc46f35
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20260613/7edd4789/attachment-0001.htm>


More information about the debian-med-commit mailing list