Control: tags -1 - moreinfo Greetings,
I attached the new debdiff to include the patch set provided by Adrian Bunk in #1094991 instead of mine. The main difference is that the ABI breaking methods are removed, and their invocations have been replaced by explicit checks everywhere they were called, e.g. isElement invocations from the original patch set like: stack.top()->isElement() are replaced by: dynamic_cast<DcmElement*>(stack.top()) != nullptr I have rerun most tests to make sure they are still okay; I have a tail of reverse dependency rebuilds pending completion, but no issues so far otherwise. Have a nice day, :) -- .''`. Étienne Mollier <emoll...@debian.org> : :' : pgp: 8f91 b227 c7d6 f2b1 948c 8236 793c f67e 8f0d 11da `. `' sent from /dev/pts/1, please excuse my verbosity `-
diff -Nru dcmtk-3.6.7/debian/changelog dcmtk-3.6.7/debian/changelog --- dcmtk-3.6.7/debian/changelog 2025-02-01 20:09:27.000000000 +0100 +++ dcmtk-3.6.7/debian/changelog 2025-02-13 17:48:57.000000000 +0100 @@ -1,3 +1,21 @@ +dcmtk (3.6.7-9~deb12u3) bookworm; urgency=medium + + * Team upload. + * Introduce patch series to fix CVE-2024-28130. + This change introduces the patches: + * 0001-Fixed-unchecked-typecasts-of-DcmItem-search-results.patch + * 0002-Fixed-unchecked-typecasts-and-fixed-LUT-handling.patch + * 0003-Fixed-wrong-error-handling-previous-commit.patch + mapping to upstream commits: + * dc6a2446dc03c9db90f82ce17a597f2cd53776c5 + * 601b227eecaab33a3a3a11dc256d84b1a62f63af + * 7d54f8efec995e5601d089fa17b0625c2b41af23 + with the nuance that upstream check functions are inlined, in order to + avoid an ABI breakage. + Thanks to Adrian Bunk (Closes: #1070207) + + -- Étienne Mollier <emoll...@debian.org> Thu, 13 Feb 2025 17:48:57 +0100 + dcmtk (3.6.7-9~deb12u2) bookworm; urgency=medium * Team upload. diff -Nru dcmtk-3.6.7/debian/patches/0001-Fixed-unchecked-typecasts-of-DcmItem-search-results.patch dcmtk-3.6.7/debian/patches/0001-Fixed-unchecked-typecasts-of-DcmItem-search-results.patch --- dcmtk-3.6.7/debian/patches/0001-Fixed-unchecked-typecasts-of-DcmItem-search-results.patch 1970-01-01 01:00:00.000000000 +0100 +++ dcmtk-3.6.7/debian/patches/0001-Fixed-unchecked-typecasts-of-DcmItem-search-results.patch 2025-02-13 17:43:55.000000000 +0100 @@ -0,0 +1,1473 @@ +>From b8e1d6f7a0e2fba1b0dd138c790751bf88220464 Mon Sep 17 00:00:00 2001 +From: Marco Eichelberg <di...@offis.de> +Date: Mon, 15 Apr 2024 12:12:51 +0200 +Subject: Fixed unchecked typecasts of DcmItem::search results. + +DcmItem::search() returns a stack of DcmObject pointers as search results. +These pointers in most instances need to be casted to DcmItem, DcmElement +or a subclass of these. In many cases, the type of the object was not +properly checked before the typecast. This could lead to segmentation faults +when invalid DICOM datasets were processed where elements had the wrong +value representation. +--- + dcmdata/libsrc/dcddirif.cc | 4 ++-- + dcmdata/libsrc/dcdirrec.cc | 6 +++--- + dcmdata/libsrc/dcfilefo.cc | 12 +++++------ + dcmdata/libsrc/dcitem.cc | 14 ++++++------- + dcmimgle/libsrc/didocu.cc | 2 +- + dcmiod/libsrc/iodutil.cc | 4 ++-- + dcmjpeg/libsrc/djcodece.cc | 8 ++++---- + dcmnet/apps/storescu.cc | 6 ++++++ + dcmnet/libsrc/dimcmd.cc | 38 ++++++++++++++++++++-------------- + dcmnet/libsrc/diutil.cc | 28 ++++++++++++------------- + dcmnet/libsrc/dstorscu.cc | 2 +- + dcmpstat/apps/dcmmklut.cc | 4 ++-- + dcmpstat/apps/dcmpschk.cc | 6 +++++- + dcmpstat/libsrc/dviface.cc | 10 ++++----- + dcmpstat/libsrc/dvpsabl.cc | 4 ++-- + dcmpstat/libsrc/dvpscu.cc | 18 ++++++++-------- + dcmpstat/libsrc/dvpsdal.cc | 4 ++-- + dcmpstat/libsrc/dvpsfs.cc | 22 ++++++++++---------- + dcmpstat/libsrc/dvpsgal.cc | 4 ++-- + dcmpstat/libsrc/dvpsgll.cc | 4 ++-- + dcmpstat/libsrc/dvpsgrl.cc | 4 ++-- + dcmpstat/libsrc/dvpshlp.cc | 2 +- + dcmpstat/libsrc/dvpsib.cc | 42 +++++++++++++++++++------------------- + dcmpstat/libsrc/dvpsibl.cc | 4 ++-- + dcmpstat/libsrc/dvpspll.cc | 4 ++-- + dcmpstat/libsrc/dvpsril.cc | 2 +- + dcmpstat/libsrc/dvpsrsl.cc | 4 ++-- + dcmpstat/libsrc/dvpssp.cc | 40 ++++++++++++++++++------------------ + dcmpstat/libsrc/dvpstxl.cc | 4 ++-- + dcmpstat/libsrc/dvpsvll.cc | 4 ++-- + dcmrt/libsrc/drttypes.cc | 8 +++----- + dcmsign/libsrc/dcsignat.cc | 20 +++++++++--------- + dcmsign/libsrc/sicert.cc | 4 ++-- + dcmsr/libsrc/dsrtypes.cc | 4 ++-- + 34 files changed, 180 insertions(+), 166 deletions(-) + +--- dcmtk.orig/dcmdata/libsrc/dcddirif.cc ++++ dcmtk/dcmdata/libsrc/dcddirif.cc +@@ -433,7 +433,7 @@ + OFBool first = OFTrue; + DcmStack stack1, stack2; + /* check whether attributes are equal */ +- while (item1->nextObject(stack1, first).good() && item2->nextObject(stack2, first).good()) ++ while (item1->nextObject(stack1, first).good() && item2->nextObject(stack2, first).good() && (dynamic_cast<DcmElement*>(stack1.top()) != nullptr) && (dynamic_cast<DcmElement*>(stack2.top()) != nullptr)) + { + if (!compareAttributes(OFstatic_cast(DcmElement *, stack1.top()), OFstatic_cast(DcmElement *, stack2.top()), fromSequence, i++, reason)) + break; +@@ -5511,7 +5511,7 @@ + OFBool first = OFTrue; + DcmElement *delem = NULL; + /* iterate over all record elements */ +- while (record->nextObject(stack, first).good() && (result || !abortCheck)) ++ while (record->nextObject(stack, first).good() && (result || !abortCheck) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + delem = OFstatic_cast(DcmElement *, stack.top()); + if ((delem != NULL) && (delem->getLength() > 0)) +--- dcmtk.orig/dcmdata/libsrc/dcdirrec.cc ++++ dcmtk/dcmdata/libsrc/dcdirrec.cc +@@ -1004,7 +1004,7 @@ + DCMDATA_ERROR("Internal ERROR in DcmDirectoryRecord::fillElementsAndReadSOP()"); + } + uiP = new DcmUniqueIdentifier(refSOPClassTag); // (0004,1510) +- if (refFile->search(DCM_SOPClassUID, stack).good()) ++ if (refFile->search(DCM_SOPClassUID, stack).good() && (stack.top()->ident() == EVR_UI)) + { + char *uid = NULL; + OFstatic_cast(DcmUniqueIdentifier *, stack.top())->getString(uid); +@@ -1017,7 +1017,7 @@ + insert(uiP, OFTrue); + + uiP = new DcmUniqueIdentifier(refSOPInstTag); // (0004,1511) +- if (refFile->search(DCM_SOPInstanceUID, stack).good() || refFile->search(DCM_MediaStorageSOPInstanceUID, stack).good()) ++ if ((refFile->search(DCM_SOPInstanceUID, stack).good() || refFile->search(DCM_MediaStorageSOPInstanceUID, stack).good()) && (stack.top()->ident() == EVR_UI)) + { + char *uid = NULL; + OFstatic_cast(DcmUniqueIdentifier *, stack.top())->getString(uid); +@@ -1030,7 +1030,7 @@ + insert(uiP, OFTrue); + + uiP = new DcmUniqueIdentifier(refFileXferTag); // (0004,1512) +- if (refFile->search(DCM_TransferSyntaxUID, stack).good()) ++ if (refFile->search(DCM_TransferSyntaxUID, stack).good() && (stack.top()->ident() == EVR_UI)) + { + char *uid = NULL; + OFstatic_cast(DcmUniqueIdentifier *, stack.top())->getString(uid); +--- dcmtk.orig/dcmdata/libsrc/dcfilefo.cc ++++ dcmtk/dcmdata/libsrc/dcfilefo.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1994-2022, OFFIS e.V. ++ * Copyright (C) 1994-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -363,7 +363,7 @@ + { + if ((writeMode == EWM_updateMeta) || (elem->getLength() == 0)) + { +- if (dataset->search(DCM_SOPClassUID, stack).good()) ++ if (dataset->search(DCM_SOPClassUID, stack).good() && (stack.top()->ident() == EVR_UI)) + { + char *uid = NULL; + l_error = OFstatic_cast(DcmUniqueIdentifier *, stack.top())->getString(uid); +@@ -379,7 +379,7 @@ + else if (DCM_dcmdataLogger.isEnabledFor(OFLogger::WARN_LOG_LEVEL)) + { + // check whether UID in meta-header is identical to the one in the dataset +- if (dataset->search(DCM_SOPClassUID, stack).good()) ++ if (dataset->search(DCM_SOPClassUID, stack).good() && (stack.top()->ident() == EVR_UI)) + { + OFString uidDataset, uidMetaHeader; + OFstatic_cast(DcmUniqueIdentifier *, stack.top())->getOFStringArray(uidDataset); +@@ -405,7 +405,7 @@ + { + if ((writeMode == EWM_updateMeta) || (elem->getLength() == 0)) + { +- if (dataset->search(DCM_SOPInstanceUID, stack).good()) ++ if (dataset->search(DCM_SOPInstanceUID, stack).good() && (stack.top()->ident() == EVR_UI)) + { + char* uid = NULL; + l_error = OFstatic_cast(DcmUniqueIdentifier *, stack.top())->getString(uid); +@@ -423,7 +423,7 @@ + else if (DCM_dcmdataLogger.isEnabledFor(OFLogger::WARN_LOG_LEVEL)) + { + // check whether UID in meta-header is identical to the one in the dataset +- if (dataset->search(DCM_SOPInstanceUID, stack).good()) ++ if (dataset->search(DCM_SOPInstanceUID, stack).good() && (stack.top()->ident() == EVR_UI)) + { + OFString uidDataset, uidMetaHeader; + OFstatic_cast(DcmUniqueIdentifier *, stack.top())->getOFStringArray(uidDataset); +@@ -634,7 +634,7 @@ + /* check whether meta header is present (and non-empty, i.e. contains elements) */ + if (metainfo && !metainfo->isEmpty()) + { +- if (metainfo->search(DCM_TransferSyntaxUID, stack).good()) ++ if (metainfo->search(DCM_TransferSyntaxUID, stack).good() && (stack.top()->ident() == EVR_UI)) + { + DcmUniqueIdentifier *xferUI = OFstatic_cast(DcmUniqueIdentifier *, stack.top()); + if (xferUI->getTag().getXTag() == DCM_TransferSyntaxUID) +--- dcmtk.orig/dcmdata/libsrc/dcitem.cc ++++ dcmtk/dcmdata/libsrc/dcitem.cc +@@ -2322,7 +2322,7 @@ + DcmStack stack; + OFBool result = OFFalse; + +- if (search(key, stack, ESM_fromHere, searchIntoSub).good()) ++ if (search(key, stack, ESM_fromHere, searchIntoSub).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + DcmElement *elem = OFstatic_cast(DcmElement *, stack.top()); + if (elem != NULL) +@@ -2345,7 +2345,7 @@ + DcmStack stack; + /* find the element */ + OFCondition status = search(tagKey, stack, ESM_fromHere, searchIntoSub); +- if (status.good()) ++ if (status.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + element = OFstatic_cast(DcmElement *, stack.top()); + /* should never happen but ... */ +@@ -2980,7 +2980,7 @@ + DcmStack stack; + /* find the element */ + OFCondition status = search(seqTagKey, stack, ESM_fromHere, searchIntoSub); +- if (status.good()) ++ if (status.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); + /* should never happen but ... */ +@@ -3017,7 +3017,7 @@ + DcmStack stack; + /* find sequence */ + OFCondition status = search(seqTagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (status.good()) ++ if (status.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + /* get element */ + DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); +@@ -3079,7 +3079,7 @@ + OFCondition status = search(seqTag, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); + DcmSequenceOfItems *sequence = NULL; + /* sequence found? */ +- if (status.good()) ++ if (status.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + /* get element */ + DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); +@@ -3213,7 +3213,7 @@ + DcmStack stack; + /* find sequence */ + OFCondition status = search(seqTagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (status.good()) ++ if (status.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + /* get element */ + DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); +@@ -4173,7 +4173,7 @@ + status = search(seqTag, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); + DcmSequenceOfItems *sequence = NULL; + /* sequence found? */ +- if (status.good()) ++ if (status.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + /* get element */ + DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); +--- dcmtk.orig/dcmimgle/libsrc/didocu.cc ++++ dcmtk/dcmimgle/libsrc/didocu.cc +@@ -218,7 +218,7 @@ + obj = Object; + // only search on main dataset level + if ((obj != NULL) && (obj->search(tag, stack, ESM_fromHere, OFFalse /* searchIntoSub */) == EC_Normal) && +- (stack.top()->getLength(Xfer) > 0)) ++ (stack.top()->getLength(Xfer) > 0) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + return OFstatic_cast(DcmElement *, stack.top()); + } +--- dcmtk.orig/dcmiod/libsrc/iodutil.cc ++++ dcmtk/dcmiod/libsrc/iodutil.cc +@@ -43,7 +43,7 @@ + DcmStack stack; + const DcmTagKey tagKey = delem.getTag(); + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good()) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + /* copy object from search stack */ + result = delem.copyFrom(*stack.top()); +@@ -76,7 +76,7 @@ + + DcmStack stack; + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good()) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + /* copy object from search stack */ + delem = OFstatic_cast(DcmElement*, stack.top()->clone()); +--- dcmtk.orig/dcmjpeg/libsrc/djcodece.cc ++++ dcmtk/dcmjpeg/libsrc/djcodece.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 2001-2022, OFFIS e.V. ++ * Copyright (C) 2001-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -1397,17 +1397,17 @@ + DcmElement *explanation = NULL; + + DcmStack stack; +- if ((dataset->search(DCM_WindowCenter, stack, ESM_fromHere, OFFalse)).good()) ++ if ((dataset->search(DCM_WindowCenter, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + center = OFreinterpret_cast(DcmElement*, stack.top()); + } + stack.clear(); +- if ((dataset->search(DCM_WindowWidth, stack, ESM_fromHere, OFFalse)).good()) ++ if ((dataset->search(DCM_WindowWidth, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + width = OFreinterpret_cast(DcmElement*, stack.top()); + } + stack.clear(); +- if ((dataset->search(DCM_WindowCenterWidthExplanation, stack, ESM_fromHere, OFFalse)).good()) ++ if ((dataset->search(DCM_WindowCenterWidthExplanation, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + explanation = OFreinterpret_cast(DcmElement*, stack.top()); + } +--- dcmtk.orig/dcmnet/apps/storescu.cc ++++ dcmtk/dcmnet/apps/storescu.cc +@@ -1138,6 +1138,12 @@ + return OFFalse; + } + ++ if (! (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ { ++ OFLOG_ERROR(storescuLogger, "updateStringAttributeValue: not a DcmElement: " << tag.getTagName() << " " << key); ++ return OFFalse; ++ } ++ + DcmElement *elem = OFstatic_cast(DcmElement *, stack.top()); + + DcmVR vr(elem->ident()); +--- dcmtk.orig/dcmnet/libsrc/dimcmd.cc ++++ dcmtk/dcmnet/libsrc/dimcmd.cc +@@ -191,14 +191,16 @@ + static OFCondition + getString(DcmDataset *obj, DcmTagKey t, char *s, int maxlen, OFBool *spacePadded) + { +- DcmElement *elem; ++ DcmElement *elem = NULL; + DcmStack stack; + OFCondition ec = EC_Normal; + char* aString; + + ec = obj->search(t, stack); +- elem = (DcmElement*)stack.top(); +- if (ec == EC_Normal && elem != NULL) { ++ if (ec.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ elem = (DcmElement*)stack.top(); ++ ++ if (elem != NULL) { + if (elem->getLength() == 0) { + s[0] = '\0'; + } else if (elem->getLength() > (Uint32)maxlen) { +@@ -266,17 +268,19 @@ + static OFCondition + getUS(DcmDataset *obj, DcmTagKey t, Uint16 *us) + { +- DcmElement *elem; ++ DcmElement *elem = NULL; + DcmStack stack; + OFCondition ec = EC_Normal; + + ec = obj->search(t, stack); +- elem = (DcmElement*)stack.top(); +- if (ec == EC_Normal && elem != NULL) { ++ if (ec.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ elem = (DcmElement*)stack.top(); ++ ++ if (elem != NULL) { + ec = elem->getUint16(*us, 0); + } + +- return (ec == EC_Normal)?(EC_Normal):(DIMSE_PARSEFAILED); ++ return (ec.good())?(EC_Normal):(DIMSE_PARSEFAILED); + } + + static OFCondition +@@ -317,17 +321,19 @@ + static OFCondition + getUL(DcmDataset *obj, DcmTagKey t, Uint32 *ul) + { +- DcmElement *elem; ++ DcmElement *elem = NULL; + DcmStack stack; + OFCondition ec = EC_Normal; + + ec = obj->search(t, stack); +- elem = (DcmElement*)stack.top(); +- if (ec == EC_Normal && elem != NULL) { ++ if (ec.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ elem = (DcmElement*)stack.top(); ++ ++ if (elem != NULL) { + ec = elem->getUint32(*ul, 0); + } + +- return (ec == EC_Normal)?(EC_Normal):(DIMSE_PARSEFAILED); ++ return (ec.good())?(EC_Normal):(DIMSE_PARSEFAILED); + } + + #if 0 +@@ -378,15 +384,17 @@ + static OFCondition + getAttributeList(DcmDataset *obj, DcmTagKey t, Uint16 **lst, int *listCount) + { +- DcmElement *elem; ++ DcmElement *elem = NULL; + DcmStack stack; + OFCondition ec = EC_Normal; + Uint16 *aList = NULL; + Uint32 nBytes = 0; + + ec = obj->search(t, stack); +- elem = (DcmElement*)stack.top(); +- if (ec == EC_Normal && elem != NULL) { ++ if (ec.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ elem = (DcmElement*)stack.top(); ++ ++ if (elem) { + nBytes = elem->getLength(); + *listCount = (int)(nBytes / sizeof(Uint16)); + if (*listCount > 0) { +@@ -398,7 +406,7 @@ + } + } + +- return (ec == EC_Normal)?(EC_Normal):(DIMSE_PARSEFAILED); ++ return (ec.good())?(EC_Normal):(DIMSE_PARSEFAILED); + } + + /* +--- dcmtk.orig/dcmnet/libsrc/diutil.cc ++++ dcmtk/dcmnet/libsrc/diutil.cc +@@ -159,23 +159,21 @@ + OFBool + DU_getStringDOElement(DcmItem *obj, DcmTagKey t, char *s, size_t bufsize) + { +- DcmByteString *elem; + DcmStack stack; +- OFCondition ec = EC_Normal; + char* aString; + +- ec = obj->search(t, stack); +- elem = (DcmByteString*) stack.top(); +- if (ec == EC_Normal && elem != NULL) { ++ OFCondition ec = obj->search(t, stack); ++ if (ec.good() && (stack.top() != NULL) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) { ++ DcmElement *elem = (DcmElement *) stack.top(); + if (elem->getLength() == 0) { + s[0] = '\0'; + } else { + ec = elem->getString(aString); +- if (ec == EC_Normal) ++ if (ec.good()) + OFStandard::strlcpy(s, aString, bufsize); + } + } +- return (ec == EC_Normal); ++ return (ec.good()); + } + + OFBool +@@ -193,7 +191,7 @@ + ec = obj->insert(e, OFTrue); + } + +- return (ec == EC_Normal); ++ return (ec.good()); + } + + OFBool +@@ -201,15 +199,15 @@ + { + DcmElement *elem; + DcmStack stack; +- OFCondition ec = EC_Normal; + +- ec = obj->search(t, stack); +- elem = (DcmElement*) stack.top(); +- if (ec == EC_Normal && elem != NULL) { +- ec = elem->getUint16(*us, 0); ++ OFCondition ec = obj->search(t, stack); ++ if (ec.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ { ++ elem = (DcmElement*) stack.top(); ++ if (elem) ec = elem->getUint16(*us, 0); + } + +- return (ec == EC_Normal); ++ return (ec.good()); + } + + OFBool +@@ -226,7 +224,7 @@ + if (ec == EC_Normal) { + ec = obj->insert(e, OFTrue); + } +- return (ec == EC_Normal); ++ return (ec.good()); + } + + OFBool +--- dcmtk.orig/dcmnet/libsrc/dstorscu.cc ++++ dcmtk/dcmnet/libsrc/dstorscu.cc +@@ -484,7 +484,7 @@ + OFFilename dirName; + OFStandard::getDirNameFromPath(dirName, filename, OFFalse /* assumeDirName */); + // iterate over all items (directory records) where ReferencedFileID is present +- while (dataset->search(DCM_ReferencedFileID, stack, ESM_afterStackTop, OFTrue).good()) ++ while (dataset->search(DCM_ReferencedFileID, stack, ESM_afterStackTop, OFTrue).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + // make sure that the dataset and element pointer are there + if (stack.card() > 1) +--- dcmtk.orig/dcmpstat/apps/dcmmklut.cc ++++ dcmtk/dcmpstat/apps/dcmmklut.cc +@@ -971,7 +971,7 @@ + { + // search existing sequence + DcmStack stack; +- if (EC_Normal == dataset->search(DCM_PresentationLUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dataset->search(DCM_PresentationLUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + dseq=(DcmSequenceOfItems *)stack.top(); + } + if (dseq == NULL) +@@ -992,7 +992,7 @@ + { + // search existing sequence + DcmStack stack; +- if (EC_Normal == dataset->search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dataset->search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + dseq=(DcmSequenceOfItems *)stack.top(); + } + if (dseq == NULL) +--- dcmtk.orig/dcmpstat/apps/dcmpschk.cc ++++ dcmtk/dcmpstat/apps/dcmpschk.cc +@@ -652,7 +652,11 @@ + OFOStringStream str; + + ec = dset->search(key, stack, ESM_fromHere, OFFalse); +- elem = (DcmElement*) stack.top(); ++ if (ec.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ { ++ elem = (DcmElement*) stack.top(); ++ } ++ + if (elem) + elem->print(str, DCMTypes::PF_shortenLongTagValues); + else +--- dcmtk.orig/dcmpstat/libsrc/dviface.cc ++++ dcmtk/dcmpstat/libsrc/dviface.cc +@@ -1425,14 +1425,14 @@ + if (reference != NULL) + { + DcmStack stack; +- if (dataset->search(DCM_ContentDescription, stack, ESM_fromHere, OFFalse) == EC_Normal) ++ if (dataset->search(DCM_ContentDescription, stack, ESM_fromHere, OFFalse) == EC_Normal && (stack.top()->ident() == EVR_LO)) + { + char *value = NULL; + if ((*OFstatic_cast(DcmLongString *, stack.top())).getString(value) == EC_Normal) + reference->Description = value; + } + stack.clear(); +- if (dataset->search(DCM_ContentLabel, stack, ESM_fromHere, OFFalse) == EC_Normal) ++ if (dataset->search(DCM_ContentLabel, stack, ESM_fromHere, OFFalse) == EC_Normal && (stack.top()->ident() == EVR_LO)) + { + char *value = NULL; + if ((*OFstatic_cast(DcmLongString *, stack.top())).getString(value) == EC_Normal) +@@ -2843,12 +2843,12 @@ + DcmDataset *dset = fileformat.getDataset(); + if (dset) + { +- if (EC_Normal == dset->search(DCM_SOPInstanceUID, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset->search(DCM_SOPInstanceUID, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + OFstatic_cast(DcmElement *, stack.top())->getString(instanceUID); + } + stack.clear(); +- if (EC_Normal == dset->search(DCM_SOPClassUID, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset->search(DCM_SOPClassUID, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + OFstatic_cast(DcmElement *, stack.top())->getString(classUID); + } +@@ -3761,7 +3761,7 @@ + DVPSPresentationLUT presentationLUT; + if (EC_Normal != presentationLUT.read(*dataset, OFFalse)) presentationLUT.setType(DVPSP_identity); + result = dataset->search(sopclassuid.getTag(), stack, ESM_fromHere, OFFalse); +- if (EC_Normal == result) ++ if (EC_Normal == result && (stack.top()->ident() == EVR_UI)) + { + char *sopclass = NULL; + sopclassuid = *OFstatic_cast(DcmUniqueIdentifier *, stack.top()); +--- dcmtk.orig/dcmpstat/libsrc/dvpsabl.cc ++++ dcmtk/dcmpstat/libsrc/dvpsabl.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1999-2010, OFFIS e.V. ++ * Copyright (C) 1999-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -69,7 +69,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_RETIRED_AnnotationContentSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_RETIRED_AnnotationContentSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpscu.cc ++++ dcmtk/dcmpstat/libsrc/dvpscu.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2020, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -80,14 +80,14 @@ + + /* first we look for the Curve Data */ + DcmTagKey key(0x5000 + group,0x3000); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_curveData = (DcmElement *)(stack.top()); + } else return EC_IllegalCall; + + key.setElement(0x0005); // Curve Dimensions + stack.clear(); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_curveDimensions = (DcmElement *)(stack.top()); + } else return EC_IllegalCall; +@@ -101,42 +101,42 @@ + + key.setElement(0x0010); // Number of Points + stack.clear(); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_numberOfPoints = (DcmElement *)(stack.top()); + } else return EC_IllegalCall; + + key.setElement(0x0020); // Type of Data + stack.clear(); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_typeOfData = (DcmElement *)(stack.top()); + } else return EC_IllegalCall; + + key.setElement(0x0103); // Data Value Representation + stack.clear(); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_dataVR = (DcmElement *)(stack.top()); + } else return EC_IllegalCall; + + key.setElement(0x0022); // Curve Description + stack.clear(); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_curveDescription = (DcmElement *)(stack.top()); + } + + key.setElement(0x0030); // Axis Units + stack.clear(); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_axisUnits = (DcmElement *)(stack.top()); + } + + key.setElement(0x2500); // Curve Label + stack.clear(); +- if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(key, stack, ESM_fromHere, OFFalse) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + d_curveLabel = (DcmElement *)(stack.top()); + } +--- dcmtk.orig/dcmpstat/libsrc/dvpsdal.cc ++++ dcmtk/dcmpstat/libsrc/dvpsdal.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1999-2010, OFFIS e.V. ++ * Copyright (C) 1999-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -67,7 +67,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_DisplayedAreaSelectionSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_DisplayedAreaSelectionSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpsfs.cc ++++ dcmtk/dcmpstat/libsrc/dvpsfs.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2021, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -280,7 +280,7 @@ + { + stack.clear(); + +- if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_SQ)) + { + DcmSequenceOfItems *seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +@@ -480,7 +480,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)numberOfCopies.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)numberOfCopies.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_IS)) + { + numberOfCopies = *((DcmIntegerString *)(stack.top())); + Sint32 numCopies=0; +@@ -502,7 +502,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)printPriority.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)printPriority.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + printPriority = *((DcmCodeString *)(stack.top())); + OFString aString; +@@ -523,7 +523,7 @@ + { + Uint32 numMediumTypes = cfg.getTargetPrinterNumberOfMediumTypes(cfgname); + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)mediumType.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)mediumType.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + mediumType = *((DcmCodeString *)(stack.top())); + OFString theMedium; +@@ -555,7 +555,7 @@ + { + Uint32 numFilmDestination = cfg.getTargetPrinterNumberOfFilmDestinations(cfgname); + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)filmDestination.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)filmDestination.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + filmDestination = *((DcmCodeString *)(stack.top())); + OFString theDestination; +@@ -586,7 +586,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)filmSessionLabel.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)filmSessionLabel.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_LO)) + { + filmSessionLabel = *((DcmLongString *)(stack.top())); + ADD_TO_PDATASET(DcmLongString, filmSessionLabel) +@@ -597,7 +597,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)ownerID.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)ownerID.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_SH)) + { + ownerID = *((DcmShortString *)(stack.top())); + ADD_TO_PDATASET(DcmShortString, ownerID) +@@ -611,7 +611,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)illumination.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)illumination.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + illumination = *((DcmUnsignedShort *)(stack.top())); + // we don't check illumination set by the user (for now) +@@ -623,7 +623,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)reflectedAmbientLight.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)reflectedAmbientLight.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + reflectedAmbientLight = *((DcmUnsignedShort *)(stack.top())); + // we don't check reflected ambient light set by the user (for now) +@@ -636,7 +636,7 @@ + { + stack.clear(); + +- if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_SQ)) + { + DcmSequenceOfItems *seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +--- dcmtk.orig/dcmpstat/libsrc/dvpsgal.cc ++++ dcmtk/dcmpstat/libsrc/dvpsgal.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2010, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -69,7 +69,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_GraphicAnnotationSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_GraphicAnnotationSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpsgll.cc ++++ dcmtk/dcmpstat/libsrc/dvpsgll.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2017, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -75,7 +75,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_GraphicLayerSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_GraphicLayerSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpsgrl.cc ++++ dcmtk/dcmpstat/libsrc/dvpsgrl.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2010, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -66,7 +66,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_GraphicObjectSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_GraphicObjectSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpshlp.cc ++++ dcmtk/dcmpstat/libsrc/dvpshlp.cc +@@ -178,7 +178,7 @@ + { + item = seq.getItem(i); + stack.clear(); +- if (EC_Normal == item->search(DCM_ReferencedSOPClassUID, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == item->search(DCM_ReferencedSOPClassUID, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_UI)) + { + aString.clear(); + refuid = (DcmUniqueIdentifier *)(stack.top()); +--- dcmtk.orig/dcmpstat/libsrc/dvpsib.cc ++++ dcmtk/dcmpstat/libsrc/dvpsib.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2018, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -153,7 +153,7 @@ + if (result==EC_Normal) + { + stack.clear(); +- if (EC_Normal == dset.search(DCM_ReferencedImageSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_ReferencedImageSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +@@ -181,7 +181,7 @@ + // check referenced presentation LUT sequence + // if there is any reference, it must refer to one of the presentation LUTs we are managing. + stack.clear(); +- if (EC_Normal == dset.search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +@@ -672,7 +672,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)imageBoxPosition.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)imageBoxPosition.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + imageBoxPosition = *((DcmUnsignedShort *)(stack.top())); + // the image box position is checked elsewhere +@@ -688,7 +688,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)magnificationType.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)magnificationType.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + magnificationType = *((DcmCodeString *)(stack.top())); + Uint32 numMagnifications = cfg.getTargetPrinterNumberOfMagnificationTypes(cfgname); +@@ -721,7 +721,7 @@ + { + + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)smoothingType.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)smoothingType.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + smoothingType = *((DcmCodeString *)(stack.top())); + Uint32 numSmoothings = cfg.getTargetPrinterNumberOfSmoothingTypes(cfgname); +@@ -761,7 +761,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)configurationInformation.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)configurationInformation.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_ST)) + { + configurationInformation = *((DcmShortText *)(stack.top())); + Uint32 numConfigurationInformation = cfg.getTargetPrinterNumberOfConfigurationSettings(cfgname); +@@ -800,7 +800,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)polarity.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)polarity.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + polarity = *((DcmCodeString *)(stack.top())); + OFString thePolarity; +@@ -820,7 +820,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)requestedImageSize.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)requestedImageSize.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_DS)) + { + if (! cfg.getTargetPrinterSupportsRequestedImageSize(cfgname)) + { +@@ -841,7 +841,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)requestedDecimateCropBehavior.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)requestedDecimateCropBehavior.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + if (! cfg.getTargetPrinterSupportsDecimateCrop(cfgname)) + { +@@ -871,7 +871,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search(DCM_BasicGrayscaleImageSequence, stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search(DCM_BasicGrayscaleImageSequence, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_SQ)) + { + DcmSequenceOfItems *seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +@@ -971,7 +971,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)samplesPerPixel.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)samplesPerPixel.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + samplesPerPixel = *((DcmUnsignedShort *)(stack.top())); + val = 0; +@@ -994,7 +994,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)rows.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)rows.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + rows = *((DcmUnsignedShort *)(stack.top())); + val = 0; +@@ -1017,7 +1017,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)columns.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)columns.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + columns = *((DcmUnsignedShort *)(stack.top())); + val = 0; +@@ -1042,7 +1042,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)bitsStored.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)bitsStored.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + bitsStored = *((DcmUnsignedShort *)(stack.top())); + val = 0; +@@ -1082,7 +1082,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)bitsAllocated.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)bitsAllocated.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + bitsAllocated = *((DcmUnsignedShort *)(stack.top())); + val = 0; +@@ -1105,7 +1105,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)highBit.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)highBit.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + highBit = *((DcmUnsignedShort *)(stack.top())); + val = 0; +@@ -1128,7 +1128,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)pixelRepresentation.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)pixelRepresentation.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + pixelRepresentation = *((DcmUnsignedShort *)(stack.top())); + val = 0; +@@ -1151,7 +1151,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)photometricInterpretation.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)photometricInterpretation.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + photometricInterpretation = *((DcmCodeString *)(stack.top())); + OFString theColorModel; +@@ -1175,7 +1175,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)pixelAspectRatio.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)pixelAspectRatio.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_IS)) + { + pixelAspectRatio = *((DcmIntegerString *)(stack.top())); + if (pixelAspectRatio.getVM() != 2) +@@ -1193,7 +1193,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search(DCM_PixelData, stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search(DCM_PixelData, stack, ESM_fromHere, OFFalse)) && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + pixelData = new DcmPixelData(DCM_PixelData); + if (pixelData) +--- dcmtk.orig/dcmpstat/libsrc/dvpsibl.cc ++++ dcmtk/dcmpstat/libsrc/dvpsibl.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1999-2010, OFFIS e.V. ++ * Copyright (C) 1999-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -68,7 +68,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_RETIRED_ImageBoxContentSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_RETIRED_ImageBoxContentSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpspll.cc ++++ dcmtk/dcmpstat/libsrc/dvpspll.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1999-2022, OFFIS e.V. ++ * Copyright (C) 1999-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -72,7 +72,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_RETIRED_PresentationLUTContentSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_RETIRED_PresentationLUTContentSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpsril.cc ++++ dcmtk/dcmpstat/libsrc/dvpsril.cc +@@ -71,7 +71,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_ReferencedImageSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_ReferencedImageSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpsrsl.cc ++++ dcmtk/dcmpstat/libsrc/dvpsrsl.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2010, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -69,7 +69,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_ReferencedSeriesSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_ReferencedSeriesSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpssp.cc ++++ dcmtk/dcmpstat/libsrc/dvpssp.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2021, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -328,7 +328,7 @@ + if (result==EC_Normal) + { + stack.clear(); +- if (EC_Normal == dset.search(DCM_RETIRED_FilmBoxContentSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_RETIRED_FilmBoxContentSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +@@ -362,7 +362,7 @@ + // check referenced presentation LUT sequence + // if there is any reference, it must refer to one of the presentation LUTs we are managing. + stack.clear(); +- if (EC_Normal == item->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == item->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +@@ -445,7 +445,7 @@ + if (result==EC_Normal) + { + stack.clear(); +- if (EC_Normal == dset.search(DCM_RETIRED_PrintManagementCapabilitiesSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_RETIRED_PrintManagementCapabilitiesSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + OFBool haveFilmBox = OFFalse; + OFBool haveGrayscaleImageBox = OFFalse; +@@ -511,7 +511,7 @@ + destination.clear(); + printerName.clear(); + stack.clear(); +- if (EC_Normal == dset.search(DCM_RETIRED_PrinterCharacteristicsSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_RETIRED_PrinterCharacteristicsSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq = (DcmSequenceOfItems *)stack.top(); + if (seq->card() > 0) +@@ -1536,7 +1536,7 @@ + { + // N-CREATE was successful, now evaluate Referenced Image Box SQ + stack.clear(); +- if (EC_Normal == attributeListOut->search(DCM_ReferencedImageBoxSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == attributeListOut->search(DCM_ReferencedImageBoxSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + numItems = (size_t)seq->card(); +@@ -1559,7 +1559,7 @@ + // evaluate Referenced Basic Annotation Box SQ if present + stack.clear(); + annotationContentList.clearAnnotationSOPInstanceUIDs(); +- if (EC_Normal == attributeListOut->search(DCM_ReferencedBasicAnnotationBoxSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == attributeListOut->search(DCM_ReferencedBasicAnnotationBoxSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + numItems = (size_t)seq->card(); +@@ -2419,7 +2419,7 @@ + { + stack.clear(); + +- if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_SQ)) + { + DcmSequenceOfItems *seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +@@ -2487,7 +2487,7 @@ + { + stack.clear(); + +- if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedFilmSessionSequence, stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedFilmSessionSequence, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_SQ)) + { + DcmUniqueIdentifier classUID(DCM_ReferencedSOPClassUID); + DcmUniqueIdentifier instanceUID(DCM_ReferencedSOPInstanceUID); +@@ -2706,7 +2706,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)magnificationType.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)magnificationType.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + magnificationType = *((DcmCodeString *)(stack.top())); + Uint32 numMagnifications = cfg.getTargetPrinterNumberOfMagnificationTypes(cfgname); +@@ -2739,7 +2739,7 @@ + { + + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)smoothingType.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)smoothingType.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + smoothingType = *((DcmCodeString *)(stack.top())); + Uint32 numSmoothings = cfg.getTargetPrinterNumberOfSmoothingTypes(cfgname); +@@ -2781,7 +2781,7 @@ + { + + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)borderDensity.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)borderDensity.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + borderDensity = *((DcmCodeString *)(stack.top())); + Uint32 numBorderDensities = cfg.getTargetPrinterNumberOfBorderDensities(cfgname); +@@ -2832,7 +2832,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)emptyImageDensity.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)emptyImageDensity.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + emptyImageDensity = *((DcmCodeString *)(stack.top())); + Uint32 numEmptyImageDensities = cfg.getTargetPrinterNumberOfEmptyImageDensities(cfgname); +@@ -2883,7 +2883,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)maxDensity.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)maxDensity.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + maxDensity = *((DcmUnsignedShort *)(stack.top())); + // we don't check a max density set by the user (for now) +@@ -2895,7 +2895,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)minDensity.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)minDensity.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + minDensity = *((DcmUnsignedShort *)(stack.top())); + Uint32 numMinDensities = cfg.getTargetPrinterNumberOfMinDensities(cfgname); +@@ -2917,7 +2917,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)trim.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)trim.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_CS)) + { + trim = *((DcmCodeString *)(stack.top())); + +@@ -2945,7 +2945,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)configurationInformation.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)configurationInformation.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_ST)) + { + configurationInformation = *((DcmShortText *)(stack.top())); + Uint32 numConfigurationInformation = cfg.getTargetPrinterNumberOfConfigurationSettings(cfgname); +@@ -2987,7 +2987,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)illumination.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)illumination.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + illumination = *((DcmUnsignedShort *)(stack.top())); + // we don't check illumination set by the user (for now) +@@ -2999,7 +2999,7 @@ + if (result) + { + stack.clear(); +- if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)reflectedAmbientLight.getTag(), stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search((DcmTagKey &)reflectedAmbientLight.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) + { + reflectedAmbientLight = *((DcmUnsignedShort *)(stack.top())); + // we don't check reflected ambient light set by the user (for now) +@@ -3012,7 +3012,7 @@ + { + stack.clear(); + +- if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse))) ++ if (rqDataset && (EC_Normal == rqDataset->search(DCM_ReferencedPresentationLUTSequence, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_SQ)) + { + DcmSequenceOfItems *seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) +--- dcmtk.orig/dcmpstat/libsrc/dvpstxl.cc ++++ dcmtk/dcmpstat/libsrc/dvpstxl.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2010, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -66,7 +66,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_TextObjectSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_TextObjectSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmpstat/libsrc/dvpsvll.cc ++++ dcmtk/dcmpstat/libsrc/dvpsvll.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2010, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -66,7 +66,7 @@ + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; + +- if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +--- dcmtk.orig/dcmrt/libsrc/drttypes.cc ++++ dcmtk/dcmrt/libsrc/drttypes.cc +@@ -1,14 +1,12 @@ + /* + * +- * Copyright (c) 2008-2021, OFFIS e.V. and ICSMED AG, Oldenburg, Germany +- * Copyright (C) 2013-2021, J. Riesmeier, Oldenburg, Germany ++ * Copyright (c) 2008-2024, OFFIS e.V. and ICSMED AG, Oldenburg, Germany ++ * Copyright (C) 2013-2024, J. Riesmeier, Oldenburg, Germany + * All rights reserved. See COPYRIGHT file for details. + * + * Source file for class DRTTypes + * + * Generated manually based on dsrtypes.cc +- * File created on 2008-12-05 +- * Last modified on 2016-02-12 by Riesmeier + * + */ + +@@ -212,7 +210,7 @@ + { + DcmStack stack; + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good()) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + DcmElement *element = OFstatic_cast(DcmElement *, stack.top()); + if (element != NULL) +--- dcmtk.orig/dcmsign/libsrc/dcsignat.cc ++++ dcmtk/dcmsign/libsrc/dcsignat.cc +@@ -102,7 +102,7 @@ + macid = 0xFFFF; + DcmStack stack; + OFCondition result = item.search(DCM_MACIDNumber, stack, ESM_fromHere, OFFalse); +- if (result.good() && (stack.top()->isLeaf())) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + result = ((DcmElement *)(stack.top()))->getUint16(macid); + } +@@ -732,7 +732,7 @@ + // read MAC Calculation Transfer Syntax UID + if (result.good()) + { +- if ((selectedMacParametersItem->search(DCM_MACCalculationTransferSyntaxUID, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedMacParametersItem->search(DCM_MACCalculationTransferSyntaxUID, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + char *uid = NULL; + if ((((DcmElement *)(stack.top()))->getString(uid)).good()) +@@ -748,7 +748,7 @@ + if (result.good()) + { + stack.clear(); +- if ((selectedMacParametersItem->search(DCM_MACAlgorithm, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedMacParametersItem->search(DCM_MACAlgorithm, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + OFString macidentifier; + if ((((DcmElement *)(stack.top()))->getOFString(macidentifier, 0)).good()) +@@ -781,7 +781,7 @@ + if (result.good()) + { + stack.clear(); +- if ((selectedSignatureItem->search(DCM_Signature, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedSignatureItem->search(DCM_Signature, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->ident() == EVR_OB)) + { + signature = new DcmOtherByteOtherWord(*((DcmOtherByteOtherWord *)(stack.top()))); + if (signature == NULL) result = EC_MemoryExhausted; +@@ -958,7 +958,7 @@ + DcmStack stack; + + // read MAC Calculation Transfer Syntax UID +- if ((selectedMacParametersItem->search(DCM_MACCalculationTransferSyntaxUID, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedMacParametersItem->search(DCM_MACCalculationTransferSyntaxUID, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + char *uid = NULL; + if ((((DcmElement *)(stack.top()))->getString(uid)).good() && uid) +@@ -1003,7 +1003,7 @@ + DcmStack stack; + + // read MAC Algorithm +- if ((selectedMacParametersItem->search(DCM_MACAlgorithm, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedMacParametersItem->search(DCM_MACAlgorithm, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + if ((((DcmElement *)(stack.top()))->getOFString(str, 0)).good()) result = EC_Normal; + } +@@ -1018,7 +1018,7 @@ + DcmStack stack; + + // read signature UID +- if ((selectedSignatureItem->search(DCM_DigitalSignatureUID, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedSignatureItem->search(DCM_DigitalSignatureUID, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + if ((((DcmElement *)(stack.top()))->getOFString(str, 0)).good()) result = EC_Normal; + } +@@ -1046,7 +1046,7 @@ + DcmStack stack; + + // read signature date/time +- if ((selectedSignatureItem->search(DCM_DigitalSignatureDateTime, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedSignatureItem->search(DCM_DigitalSignatureDateTime, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + if ((((DcmElement *)(stack.top()))->getOFString(str, 0)).good()) result = EC_Normal; + } +@@ -1117,7 +1117,7 @@ + // check MAC Calculation Transfer Syntax UID + if (result.good()) + { +- if ((selectedMacParametersItem->search(DCM_MACCalculationTransferSyntaxUID, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedMacParametersItem->search(DCM_MACCalculationTransferSyntaxUID, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + char *uid = NULL; + if ((((DcmElement *)(stack.top()))->getString(uid)).good()) +@@ -1140,7 +1140,7 @@ + { + E_MACType mac = EMT_RIPEMD160; + stack.clear(); +- if ((selectedMacParametersItem->search(DCM_MACAlgorithm, stack, ESM_fromHere, OFFalse)).good() && (stack.top()->isLeaf())) ++ if ((selectedMacParametersItem->search(DCM_MACAlgorithm, stack, ESM_fromHere, OFFalse)).good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + OFString macidentifier; + if ((((DcmElement *)(stack.top()))->getOFString(macidentifier, 0)).good()) +--- dcmtk.orig/dcmsign/libsrc/sicert.cc ++++ dcmtk/dcmsign/libsrc/sicert.cc +@@ -147,7 +147,7 @@ + OFString aString; + DcmStack stack; + result = item.search(DCM_CertificateType, stack, ESM_fromHere, OFFalse); +- if (result.good()) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + result = ((DcmElement *)(stack.top()))->getOFString(aString, 0); + if (result.good()) +@@ -156,7 +156,7 @@ + { + stack.clear(); + result = item.search(DCM_CertificateOfSigner, stack, ESM_fromHere, OFFalse); +- if (result.good()) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + DcmElement *cert = (DcmElement *)stack.top(); + Uint8 *data = NULL; +--- dcmtk.orig/dcmsr/libsrc/dsrtypes.cc ++++ dcmtk/dcmsr/libsrc/dsrtypes.cc +@@ -1176,7 +1176,7 @@ + DcmStack stack; + const DcmTagKey tagKey = delem.getTag(); + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good()) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + /* copy object from search stack */ + result = delem.copyFrom(*stack.top()); +@@ -1201,7 +1201,7 @@ + { + DcmStack stack; + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good()) ++ if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) + { + DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); + /* we need a reference to the original element in order to determine the SpecificCharacterSet */ diff -Nru dcmtk-3.6.7/debian/patches/0002-Fixed-unchecked-typecasts-and-fixed-LUT-handling.patch dcmtk-3.6.7/debian/patches/0002-Fixed-unchecked-typecasts-and-fixed-LUT-handling.patch --- dcmtk-3.6.7/debian/patches/0002-Fixed-unchecked-typecasts-and-fixed-LUT-handling.patch 1970-01-01 01:00:00.000000000 +0100 +++ dcmtk-3.6.7/debian/patches/0002-Fixed-unchecked-typecasts-and-fixed-LUT-handling.patch 2025-02-13 17:44:01.000000000 +0100 @@ -0,0 +1,494 @@ +>From 6cf0bc5d1cad4288d53d3a63207cd58d98300975 Mon Sep 17 00:00:00 2001 +From: Marco Eichelberg <di...@offis.de> +Date: Mon, 15 Apr 2024 12:19:33 +0200 +Subject: Fixed unchecked typecasts and fixed LUT handling. + +This commit adds further fixes for unchecked typecasts of DcmItem::search() +results (see description of previous commit). Furthermore, this commit +specifically addresses the handling of look-up tables (LUTs) in module +dcmpstat, where attribute (0028,3006) LUTData may use either US or OW +value representation, and (0028,3002) LUTDescriptor may be either US or SS. +The code should now properly handle all permitted value representations. +LUTData is now always written as OW in order to avoid the 64k size limit +for US in explicit VR encoding. + +Thanks to Martin Zeiser from the Cisco Talos team +<vulndiscov...@external.cisco.com> for the bug report (TALOS-2024-1957). + +Together with the previous commit, this closes DCMTK issue #1120. +--- + dcmpstat/libsrc/dcmpstat.cc | 40 ++++++++++++++++------- + dcmpstat/libsrc/dvpspl.cc | 34 ++++++++++++++------ + dcmpstat/libsrc/dvpssv.cc | 34 ++++++++++++++------ + dcmpstat/libsrc/dvpssvl.cc | 29 ++++++++++------- + dcmpstat/libsrc/dvpstat.cc | 63 +++++++++++++++++-------------------- + dcmpstat/libsrc/dvpsvl.cc | 19 +++++++++-- + 6 files changed, 140 insertions(+), 79 deletions(-) + +diff --git a/dcmpstat/libsrc/dcmpstat.cc b/dcmpstat/libsrc/dcmpstat.cc +index f35ca16cd..c1acad5ff 100644 +--- a/dcmpstat/libsrc/dcmpstat.cc ++++ b/dcmpstat/libsrc/dcmpstat.cc +@@ -384,12 +384,16 @@ OFCondition DcmPresentationState::read(DcmItem &dset) + { + item = seq->getItem(0); + stack.clear(); +- // LUTDescriptor can be US or SS. For now we only handle US. ++ ++ // LUTDescriptor can be US or SS + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTDescriptor.getTag(), +- stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) + { +- modalityLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); ++ // We explicitly use DcmElement::operator=(), which works for US and SS ++ DcmElement *mLUTDescriptor = &modalityLUTDescriptor; ++ mLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); + } ++ + stack.clear(); + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTExplanation.getTag(), + stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_LO)) +@@ -400,9 +404,11 @@ OFCondition DcmPresentationState::read(DcmItem &dset) + + // LUTData can be OW, US or SS. For now we only handle US. + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTData.getTag(), +- stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) + { +- modalityLUTData = *((DcmUnsignedShort *)(stack.top())); ++ // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters ++ DcmElement *mdata = &modalityLUTData; ++ mdata->operator=(*(DcmElement *)(stack.top())); + } + stack.clear(); + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTType.getTag(), +@@ -879,11 +885,13 @@ OFCondition DcmPresentationState::createFromImage( + { + item = seq->getItem(0); + stack.clear(); +- // LUTDescriptor can be US or SS. For now we only handle US. ++ // LUTDescriptor can be US or SS + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTDescriptor.getTag(), +- stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) + { +- modalityLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); ++ // We explicitly use DcmElement::operator=(), which works for US and SS ++ DcmElement *mLUTDescriptor = &modalityLUTDescriptor; ++ mLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); + } + stack.clear(); + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTExplanation.getTag(), +@@ -895,9 +903,11 @@ OFCondition DcmPresentationState::createFromImage( + + // LUTData can be OW, US or SS. For now we only handle US. + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTData.getTag(), +- stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US)) ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) + { +- modalityLUTData = *((DcmUnsignedShort *)(stack.top())); ++ // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters ++ DcmElement *mdata = &modalityLUTData; ++ mdata->operator=(*(DcmElement *)(stack.top())); + } + stack.clear(); + if ((EC_Normal == item->search((DcmTagKey &)modalityLUTType.getTag(), +@@ -1247,10 +1257,16 @@ OFCondition DcmPresentationState::write(DcmItem &dset, OFBool replaceSOPInstance + dseq = new DcmSequenceOfItems(DCM_ModalityLUTSequence); + if (dseq) + { +- delem = new DcmUnsignedShort(modalityLUTDescriptor); ++ // we clone modalityLUTDescriptor in order to retain the VR (US or SS) ++ delem = OFstatic_cast(DcmElement *, modalityLUTDescriptor.clone()); + if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; +- delem = new DcmUnsignedShort(modalityLUTData); ++ ++ // we write LUTData as OW in order to avoid the 64 kByte limit for US ++ delem = new DcmOtherByteOtherWord(DCM_LUTData); ++ delem->operator=(modalityLUTData); ++ OFstatic_cast(DcmOtherByteOtherWord *, delem)->setVR(EVR_OW); + if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; ++ + delem = new DcmLongString(modalityLUTType); + if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; + if (modalityLUTExplanation.getLength() >0) +diff --git a/dcmpstat/libsrc/dvpspl.cc b/dcmpstat/libsrc/dvpspl.cc +index ec4cccf97..f5574ab33 100644 +--- a/dcmpstat/libsrc/dvpspl.cc ++++ b/dcmpstat/libsrc/dvpspl.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1999-2018, OFFIS e.V. ++ * Copyright (C) 1999-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -24,6 +24,7 @@ + #include "dcmtk/dcmdata/dcdeftag.h" + #include "dcmtk/dcmdata/dcsequen.h" + #include "dcmtk/dcmdata/dcvrcs.h" ++#include "dcmtk/dcmdata/dcvrobow.h" + #include "dcmtk/dcmpstat/dvpspl.h" + #include "dcmtk/dcmpstat/dvpsdef.h" /* for constants and macros */ + #include "dcmtk/dcmnet/dimse.h" +@@ -79,29 +80,36 @@ OFCondition DVPSPresentationLUT::read(DcmItem &dset, OFBool withSOPInstance) + if (result==EC_Normal) + { + stack.clear(); +- if (EC_Normal == dset.search(DCM_PresentationLUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_PresentationLUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) + { + item = seq->getItem(0); + stack.clear(); +- if (EC_Normal == item->search((DcmTagKey &)presentationLUTDescriptor.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ ++ // LUTDescriptor can be US or SS ++ if ((EC_Normal == item->search((DcmTagKey &)presentationLUTDescriptor.getTag(), ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) + { +- presentationLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); ++ // We explicitly use DcmElement::operator=(), which works for US and SS ++ DcmElement *pLUTDescriptor = &presentationLUTDescriptor; ++ pLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); + } ++ + stack.clear(); + if (EC_Normal == item->search((DcmTagKey &)presentationLUTExplanation.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_LO)) + { + presentationLUTExplanation = *((DcmLongString *)(stack.top())); + } + stack.clear(); + if (EC_Normal == item->search((DcmTagKey &)presentationLUTData.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) + { +- presentationLUTData = *((DcmUnsignedShort *)(stack.top())); ++ // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters ++ DcmElement *pldata = &presentationLUTData; ++ pldata->operator=(*(DcmElement *)(stack.top())); + } + } else { + result=EC_TagNotFound; +@@ -187,10 +195,16 @@ OFCondition DVPSPresentationLUT::write(DcmItem &dset, OFBool withSOPInstance) + dseq = new DcmSequenceOfItems(DCM_PresentationLUTSequence); + if (dseq) + { +- delem = new DcmUnsignedShort(presentationLUTDescriptor); ++ // we clone presentationLUTDescriptor in order to retain the VR (US or SS) ++ delem = OFstatic_cast(DcmElement *, presentationLUTDescriptor.clone()); + if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; +- delem = new DcmUnsignedShort(presentationLUTData); ++ ++ // we write LUTData as OW in order to avoid the 64 kByte limit for US ++ delem = new DcmOtherByteOtherWord(DCM_LUTData); ++ delem->operator=(presentationLUTData); ++ OFstatic_cast(DcmOtherByteOtherWord *, delem)->setVR(EVR_OW); + if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; ++ + if (presentationLUTExplanation.getLength() >0) + { + delem = new DcmLongString(presentationLUTExplanation); +diff --git a/dcmpstat/libsrc/dvpssv.cc b/dcmpstat/libsrc/dvpssv.cc +index 8e3d49bd4..4a7fd0e30 100644 +--- a/dcmpstat/libsrc/dvpssv.cc ++++ b/dcmpstat/libsrc/dvpssv.cc +@@ -1,6 +1,6 @@ + /* + * +- * Copyright (C) 1998-2018, OFFIS e.V. ++ * Copyright (C) 1998-2024, OFFIS e.V. + * All rights reserved. See COPYRIGHT file for details. + * + * This software and supporting documentation were developed by +@@ -23,6 +23,7 @@ + #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ + #include "dcmtk/dcmdata/dcdeftag.h" + #include "dcmtk/dcmdata/dcsequen.h" ++#include "dcmtk/dcmdata/dcvrobow.h" + #include "dcmtk/dcmpstat/dvpssv.h" + #include "dcmtk/dcmpstat/dvpsri.h" /* for DVPSReferencedImage */ + #include "dcmtk/dcmpstat/dvpsrsl.h" /* DVPSReferencedSeries_PList */ +@@ -75,29 +76,36 @@ OFCondition DVPSSoftcopyVOI::read(DcmItem &dset) + if (result==EC_Normal) + { + stack.clear(); +- if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() ==1) + { + item = seq->getItem(0); + stack.clear(); +- if (EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ ++ // LUTDescriptor can be US or SS ++ if ((EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) + { +- voiLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); ++ // We explicitly use DcmElement::operator=(), which works for US and SS ++ DcmElement *vLUTDescriptor = &voiLUTDescriptor; ++ vLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); + } ++ + stack.clear(); + if (EC_Normal == item->search((DcmTagKey &)voiLUTExplanation.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_LO)) + { + voiLUTExplanation = *((DcmLongString *)(stack.top())); + } + stack.clear(); + if (EC_Normal == item->search((DcmTagKey &)voiLUTData.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) + { +- voiLUTData = *((DcmUnsignedShort *)(stack.top())); ++ // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters ++ DcmElement *vldata = &voiLUTData; ++ vldata->operator=(*(DcmElement *)(stack.top())); + } + } else { + result=EC_TagNotFound; +@@ -177,10 +185,16 @@ OFCondition DVPSSoftcopyVOI::write(DcmItem &dset) + dseq = new DcmSequenceOfItems(DCM_VOILUTSequence); + if (dseq) + { +- delem = new DcmUnsignedShort(voiLUTDescriptor); ++ // we clone voiLUTDescriptor in order to retain the VR (US or SS) ++ delem = OFstatic_cast(DcmElement *, voiLUTDescriptor.clone()); + if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; +- delem = new DcmUnsignedShort(voiLUTData); ++ ++ // we write LUTData as OW in order to avoid the 64 kByte limit for US ++ delem = new DcmOtherByteOtherWord(DCM_LUTData); ++ delem->operator=(voiLUTData); ++ OFstatic_cast(DcmOtherByteOtherWord *, delem)->setVR(EVR_OW); + if (delem) ditem->insert(delem, OFTrue /*replaceOld*/); else result=EC_MemoryExhausted; ++ + if (voiLUTExplanation.getLength() >0) + { + delem = new DcmLongString(voiLUTExplanation); +diff --git a/dcmpstat/libsrc/dvpssvl.cc b/dcmpstat/libsrc/dvpssvl.cc +index 79a239438..27a40f587 100644 +--- a/dcmpstat/libsrc/dvpssvl.cc ++++ b/dcmpstat/libsrc/dvpssvl.cc +@@ -71,8 +71,8 @@ OFCondition DVPSSoftcopyVOI_PList::read(DcmItem &dset) + DVPSSoftcopyVOI *newImage = NULL; + DcmSequenceOfItems *dseq=NULL; + DcmItem *ditem=NULL; +- +- if (EC_Normal == dset.search(DCM_SoftcopyVOILUTSequence, stack, ESM_fromHere, OFFalse)) ++ ++ if (EC_Normal == dset.search(DCM_SoftcopyVOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + dseq=(DcmSequenceOfItems *)stack.top(); + if (dseq) +@@ -248,29 +248,36 @@ OFCondition DVPSSoftcopyVOI_PList::createFromImage( + if (result==EC_Normal) + { + stack.clear(); +- if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dset.search(DCM_VOILUTSequence, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_SQ)) + { + seq=(DcmSequenceOfItems *)stack.top(); + if (seq->card() > 0) + { + item = seq->getItem(0); + stack.clear(); +- if (EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ ++ // LUTDescriptor can be US or SS ++ if ((EC_Normal == item->search((DcmTagKey &)voiLUTDescriptor.getTag(), ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) + { +- voiLUTDescriptor = *((DcmUnsignedShort *)(stack.top())); ++ // We explicitly use DcmElement::operator=(), which works for US and SS ++ DcmElement *vLUTDescriptor = &voiLUTDescriptor; ++ vLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); + } ++ + stack.clear(); +- if (EC_Normal == item->search((DcmTagKey &)voiLUTExplanation.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == item->search((DcmTagKey &)voiLUTExplanation.getTag(), ++ stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_LO)) + { + voiLUTExplanation = *((DcmLongString *)(stack.top())); + } + stack.clear(); +- if (EC_Normal == item->search((DcmTagKey &)voiLUTData.getTag(), +- stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == item->search((DcmTagKey &)voiLUTData.getTag(), ++ stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) + { +- voiLUTData = *((DcmUnsignedShort *)(stack.top())); ++ // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters ++ DcmElement *vldata = &voiLUTData; ++ vldata->operator=(*(DcmElement *)(stack.top())); + } + } else result=EC_TagNotFound; + } +diff --git a/dcmpstat/libsrc/dvpstat.cc b/dcmpstat/libsrc/dvpstat.cc +index ce2f5ad5f..d1a45aded 100644 +--- a/dcmpstat/libsrc/dvpstat.cc ++++ b/dcmpstat/libsrc/dvpstat.cc +@@ -578,14 +578,14 @@ OFCondition DVPresentationState::attachImage(DcmDataset *dataset, OFBool transfe + currentImageSelectedFrame = 1; // default: first frame + + // get Modality +- if (EC_Normal == dataset->search(DCM_Modality, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dataset->search(DCM_Modality, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_CS)) + { + currentImageModality = *((DcmCodeString *)(stack.top())); + } + stack.clear(); + + // determine default Presentation LUT Shape +- if (EC_Normal == dataset->search(DCM_PhotometricInterpretation, stack, ESM_fromHere, OFFalse)) ++ if (EC_Normal == dataset->search(DCM_PhotometricInterpretation, stack, ESM_fromHere, OFFalse) && (stack.top()->ident() == EVR_CS)) + { + DcmCodeString *photometricInterpretation = (DcmCodeString *)(stack.top()); + if (photometricInterpretation->getVM() == 1) +@@ -598,12 +598,12 @@ OFCondition DVPresentationState::attachImage(DcmDataset *dataset, OFBool transfe + stack.clear(); + + // get SOP class UID and SOP instance UID. +- if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPClassUID, stack, ESM_fromHere, OFFalse))) ++ if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPClassUID, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_UI)) + { + result = ((DcmUniqueIdentifier *)(stack.top()))->getString(currentImageSOPClassUID); + } + stack.clear(); +- if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPInstanceUID, stack, ESM_fromHere, OFFalse))) ++ if ((EC_Normal == result)&&(EC_Normal == dataset->search(DCM_SOPInstanceUID, stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_UI)) + { + result = ((DcmUniqueIdentifier *)(stack.top()))->getString(currentImageSOPInstanceUID); + } +@@ -1124,40 +1124,36 @@ OFCondition DVPresentationState::setGammaVOILUT(double gammaValue, DVPSObjectApp + numEntries16 = (Uint16)numberOfEntries; + + /* LUT Descriptor */ +- DcmElement *lutDescriptor = NULL; +- if (firstMapped < 0) ++ DcmUnsignedShort *lutDescriptor = new DcmUnsignedShort(DcmTag(DCM_LUTDescriptor, EVR_US)); ++ if (lutDescriptor == NULL) status = EC_MemoryExhausted; ++ else + { +- // LUT Descriptor is SS +- lutDescriptor = new DcmSignedShort(DcmTag(DCM_LUTDescriptor, EVR_SS)); +- if (lutDescriptor != NULL) ++ if (firstMapped < 0) + { +- status = lutDescriptor->putSint16((Sint16)numEntries16, 0); +- if (EC_Normal == status) +- status = lutDescriptor->putSint16((Sint16)firstMapped, 1); +- if (EC_Normal == status) +- status = lutDescriptor->putSint16((Sint16)numberOfBits, 2); +- } else +- status = EC_MemoryExhausted; +- } else { +- // LUT Descriptor is US +- lutDescriptor = new DcmUnsignedShort(DcmTag(DCM_LUTDescriptor, EVR_US)); +- if (lutDescriptor != NULL) +- { +- status = lutDescriptor->putUint16(numEntries16, 0); +- if (EC_Normal == status) +- status = lutDescriptor->putUint16((Uint16)firstMapped, 1); +- if (EC_Normal == status) +- status = lutDescriptor->putUint16((Uint16)numberOfBits, 2); +- } else +- status = EC_MemoryExhausted; ++ // LUT Descriptor is SS ++ DcmSignedShort ldesc(DcmTag(DCM_LUTDescriptor, EVR_SS)); ++ status = ldesc.putSint16((Sint16)numEntries16, 0); ++ if (EC_Normal == status) status = ldesc.putSint16((Sint16)firstMapped, 1); ++ if (EC_Normal == status) status = ldesc.putSint16((Sint16)numberOfBits, 2); ++ if (EC_Normal == status) ++ { ++ // copy content of SS element into DcmUnsignedShort using DcmElement::operator= ++ DcmElement *ld = lutDescriptor; ++ ld->operator=(ldesc); ++ } ++ } else { ++ // LUT Descriptor is US ++ status = lutDescriptor->putUint16(numEntries16, 0); ++ if (EC_Normal == status) status = lutDescriptor->putUint16((Uint16)firstMapped, 1); ++ if (EC_Normal == status) status = lutDescriptor->putUint16((Uint16)numberOfBits, 2); ++ } + } + + /* LUT Data */ +- DcmElement *lutData = NULL; ++ DcmUnsignedShort *lutData = NULL; + if (status == EC_Normal) + { +- // LUT Data as OW, because of max size = 64K +- lutData = new DcmOtherByteOtherWord(DcmTag(DCM_LUTData, EVR_OW)); ++ lutData = new DcmUnsignedShort(DcmTag(DCM_LUTData, EVR_US)); + if (lutData != NULL) + status = lutData->putUint16Array(data, numberOfEntries); + else +@@ -1186,15 +1182,14 @@ OFCondition DVPresentationState::setGammaVOILUT(double gammaValue, DVPSObjectApp + if (status == EC_Normal) + { + if ((lutDescriptor != NULL) && (lutData != NULL) && (lutExplanation != NULL)) +- status = setVOILUT(*(DcmUnsignedShort *)lutDescriptor, *(DcmUnsignedShort *)lutData, *lutExplanation, applicability); ++ status = setVOILUT(*lutDescriptor, *lutData, *lutExplanation, applicability); + } + + /* delete temporary dcmtk structures */ + delete lutDescriptor; + delete lutData; + delete lutExplanation; +- } else +- status = EC_MemoryExhausted; ++ } else status = EC_MemoryExhausted; + delete[] data; + } + return status; +diff --git a/dcmpstat/libsrc/dvpsvl.cc b/dcmpstat/libsrc/dvpsvl.cc +index b10b83f20..fdba0a0e0 100644 +--- a/dcmpstat/libsrc/dvpsvl.cc ++++ b/dcmpstat/libsrc/dvpsvl.cc +@@ -59,9 +59,24 @@ OFCondition DVPSVOILUT::read(DcmItem &dset) + OFCondition result = EC_Normal; + DcmStack stack; + +- READ_FROM_DATASET(DcmUnsignedShort, EVR_US, voiLUTDescriptor) ++ // LUTDescriptor can be US or SS ++ if ((EC_Normal == dset.search((DcmTagKey &)voiLUTDescriptor.getTag(), ++ stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_SS)) ++ { ++ // We explicitly use DcmElement::operator=(), which works for US and SS ++ DcmElement *vLUTDescriptor = &voiLUTDescriptor; ++ vLUTDescriptor->operator=(* OFstatic_cast(DcmElement *, stack.top())); ++ } ++ + READ_FROM_DATASET(DcmLongString, EVR_LO, voiLUTExplanation) +- READ_FROM_DATASET(DcmUnsignedShort, EVR_US, voiLUTData) ++ ++ stack.clear(); ++ if ((EC_Normal == dset.search((DcmTagKey &)voiLUTData.getTag(), stack, ESM_fromHere, OFFalse)) && (stack.top()->ident() == EVR_US || stack.top()->ident() == EVR_OW)) ++ { ++ // we deliberately call DcmElement::operator=() here, which will work for both DcmUnsignedShort and DcmOtherByteOtherWord parameters ++ DcmElement *vldata = &voiLUTData; ++ vldata->operator=(*(DcmElement *)(stack.top())); ++ } + + if (EC_Normal == result) + { +-- +2.30.2 + diff -Nru dcmtk-3.6.7/debian/patches/0003-Fixed-wrong-error-handling-previous-commit.patch dcmtk-3.6.7/debian/patches/0003-Fixed-wrong-error-handling-previous-commit.patch --- dcmtk-3.6.7/debian/patches/0003-Fixed-wrong-error-handling-previous-commit.patch 1970-01-01 01:00:00.000000000 +0100 +++ dcmtk-3.6.7/debian/patches/0003-Fixed-wrong-error-handling-previous-commit.patch 2025-02-13 17:44:11.000000000 +0100 @@ -0,0 +1,85 @@ +>From 9ecec7671ded01648354e617972d0f1f9a9576b9 Mon Sep 17 00:00:00 2001 +From: Joerg Riesmeier <di...@jriesmeier.com> +Date: Mon, 22 Apr 2024 12:11:11 +0200 +Subject: Fixed wrong error handling (previous commit). + +Fixed wrong error handling introduced with the previous commit. +--- + dcmrt/libsrc/drttypes.cc | 6 +++--- + dcmsr/libsrc/dsrtypes.cc | 32 ++++++++++++++++++++------------ + 2 files changed, 23 insertions(+), 15 deletions(-) + +diff --git a/dcmrt/libsrc/drttypes.cc b/dcmrt/libsrc/drttypes.cc +index 456378a3a..d8d2860b4 100644 +--- a/dcmrt/libsrc/drttypes.cc ++++ b/dcmrt/libsrc/drttypes.cc +@@ -210,11 +210,11 @@ OFCondition DRTTypes::getAndCheckStringValueFromDataset(DcmItem &dataset, + { + DcmStack stack; + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ if (result.good()) + { +- DcmElement *element = OFstatic_cast(DcmElement *, stack.top()); +- if (element != NULL) ++ if (dynamic_cast<DcmElement*>(stack.top()) != nullptr) + { ++ DcmElement *element = OFstatic_cast(DcmElement *, stack.top()); + if (checkElementValue(*element, vm, type, result, moduleName)) + result = element->getOFString(stringValue, 0); + else +diff --git a/dcmsr/libsrc/dsrtypes.cc b/dcmsr/libsrc/dsrtypes.cc +index da92280ff..9b4e50ff8 100644 +--- a/dcmsr/libsrc/dsrtypes.cc ++++ b/dcmsr/libsrc/dsrtypes.cc +@@ -1176,13 +1176,17 @@ OFCondition DSRTypes::getAndCheckElementFromDataset(DcmItem &dataset, + DcmStack stack; + const DcmTagKey tagKey = delem.getTag(); + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ if (result.good()) + { +- /* copy object from search stack */ +- result = delem.copyFrom(*stack.top()); +- /* we need a reference to the original element in order to determine the SpecificCharacterSet */ +- if (!checkElementValue(OFstatic_cast(DcmElement *, stack.top()), tagKey, vm, type, result, moduleName, acceptViolation)) +- result = SR_EC_InvalidValue; ++ if (dynamic_cast<DcmElement*>(stack.top()) != nullptr) ++ { ++ /* copy object from search stack */ ++ result = delem.copyFrom(*stack.top()); ++ /* we need a reference to the original element in order to determine the SpecificCharacterSet */ ++ if (!checkElementValue(OFstatic_cast(DcmElement *, stack.top()), tagKey, vm, type, result, moduleName, acceptViolation)) ++ result = SR_EC_InvalidValue; ++ } else ++ result = EC_CorruptedData; + } + /* the element could not be found in the dataset */ + else if (!checkElementValue(delem, vm, type, result, moduleName, acceptViolation)) +@@ -1201,13 +1205,17 @@ OFCondition DSRTypes::getAndCheckStringValueFromDataset(DcmItem &dataset, + { + DcmStack stack; + OFCondition result = dataset.search(tagKey, stack, ESM_fromHere, OFFalse /*searchIntoSub*/); +- if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) ++ if (result.good()) + { +- DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); +- /* we need a reference to the original element in order to determine the SpecificCharacterSet */ +- if (!checkElementValue(delem, tagKey, vm, type, result, moduleName, acceptViolation)) +- result = SR_EC_InvalidValue; +- delem->getOFString(stringValue, 0); ++ if (dynamic_cast<DcmElement*>(stack.top()) != nullptr) ++ { ++ DcmElement *delem = OFstatic_cast(DcmElement *, stack.top()); ++ /* we need a reference to the original element in order to determine the SpecificCharacterSet */ ++ if (!checkElementValue(delem, tagKey, vm, type, result, moduleName, acceptViolation)) ++ result = SR_EC_InvalidValue; ++ delem->getOFString(stringValue, 0); ++ } else ++ result = EC_CorruptedData; + } else { + if ((type == "1") || (type == "2")) + { +-- +2.30.2 + diff -Nru dcmtk-3.6.7/debian/patches/series dcmtk-3.6.7/debian/patches/series --- dcmtk-3.6.7/debian/patches/series 2025-02-01 20:09:27.000000000 +0100 +++ dcmtk-3.6.7/debian/patches/series 2025-02-13 17:44:11.000000000 +0100 @@ -15,3 +15,6 @@ 0009-CVE-2024-27628.patch 0010-CVE-2024-34508-34509.patch 0011-CVE-2024-34508-34509_bis.patch +0001-Fixed-unchecked-typecasts-of-DcmItem-search-results.patch +0002-Fixed-unchecked-typecasts-and-fixed-LUT-handling.patch +0003-Fixed-wrong-error-handling-previous-commit.patch
signature.asc
Description: PGP signature