On Sun, Feb 02, 2025 at 11:32:12AM +0100, Étienne Mollier wrote: >... > CVE-2024-28130 is notably /not/ fixed for now as I'm not that > comfortable with the codebase and changes were a bit involved. > I note that there has been a port of the fix for Debian LTS > bullseye, so I believe this should be manageable. There is > still room to amend the debdiff before upload, if someone comes > up with a fix, or to upload a later package version to fix that > last item. >... > [ Other info ] > As mentioned in the Reason paragraph, with only these changes, > CVE-2024-28130 would still affect dcmtk in bookworm. Also, > fixes exist for bullseye, so I guess something can be achieved > for bookworm too. The issue was tracked in #1070207 and history > suggests that given how involved the patch is, it has been > non-trivial to get the fixes applied to dcmtk in unstable before > availability of the newer upstream release; there was notably an > accidental ABI breakage. >...
I've attached a version for bookworm. The non-ABI-breaking variant is not pretty since instead of stack.top()->isElement() it is now doing dynamic_cast<DcmElement*>(stack.top()) != nullptr in many places. I am not claiming that my track record with DCMTK regressions is good, but the original segfault from the CVE is fixed, the ABI regression is fixed, and noone has complained in stretch/buster/bullseye about this change. I also remember from initially developing it that the upstream testsuite has some coverage of the changes. cu Adrian
>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(-) diff --git a/dcmdata/libsrc/dcddirif.cc b/dcmdata/libsrc/dcddirif.cc index 1f436926d..0f0e96975 100644 --- a/dcmdata/libsrc/dcddirif.cc +++ b/dcmdata/libsrc/dcddirif.cc @@ -433,7 +433,7 @@ static OFBool compareItems(DcmItem *item1, 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 DicomDirInterface::warnAboutInconsistentAttributes(DcmDirectoryRecord *re 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)) diff --git a/dcmdata/libsrc/dcdirrec.cc b/dcmdata/libsrc/dcdirrec.cc index e4ea26de5..08cb5392d 100644 --- a/dcmdata/libsrc/dcdirrec.cc +++ b/dcmdata/libsrc/dcdirrec.cc @@ -1004,7 +1004,7 @@ OFCondition DcmDirectoryRecord::fillElementsAndReadSOP(const char *referencedFil 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 @@ OFCondition DcmDirectoryRecord::fillElementsAndReadSOP(const char *referencedFil 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 @@ OFCondition DcmDirectoryRecord::fillElementsAndReadSOP(const char *referencedFil 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); diff --git a/dcmdata/libsrc/dcfilefo.cc b/dcmdata/libsrc/dcfilefo.cc index 52ed38127..a0150b2cf 100644 --- a/dcmdata/libsrc/dcfilefo.cc +++ b/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 @@ OFCondition DcmFileFormat::checkMetaHeaderValue(DcmMetaInfo *metainfo, { 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 @@ OFCondition DcmFileFormat::checkMetaHeaderValue(DcmMetaInfo *metainfo, 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 @@ OFCondition DcmFileFormat::checkMetaHeaderValue(DcmMetaInfo *metainfo, { 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 @@ OFCondition DcmFileFormat::checkMetaHeaderValue(DcmMetaInfo *metainfo, 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 @@ E_TransferSyntax DcmFileFormat::lookForXfer(DcmMetaInfo *metainfo) /* 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) diff --git a/dcmdata/libsrc/dcitem.cc b/dcmdata/libsrc/dcitem.cc index 8ddf1ae70..eb5bd4168 100644 --- a/dcmdata/libsrc/dcitem.cc +++ b/dcmdata/libsrc/dcitem.cc @@ -2322,7 +2322,7 @@ OFBool DcmItem::tagExistsWithValue(const DcmTagKey &key, 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 @@ OFCondition DcmItem::findAndGetElement(const DcmTagKey &tagKey, 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 @@ OFCondition DcmItem::findAndGetSequence(const DcmTagKey &seqTagKey, 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 @@ OFCondition DcmItem::findAndGetSequenceItem(const DcmTagKey &seqTagKey, 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 DcmItem::findOrCreateSequenceItem(const DcmTag& seqTag, 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 @@ OFCondition DcmItem::findAndDeleteSequenceItem(const DcmTagKey &seqTagKey, 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 @@ OFCondition DcmItem::insertSequenceItem(const DcmTag &seqTag, 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()); diff --git a/dcmimgle/libsrc/didocu.cc b/dcmimgle/libsrc/didocu.cc index 00b73b569..c11b40565 100644 --- a/dcmimgle/libsrc/didocu.cc +++ b/dcmimgle/libsrc/didocu.cc @@ -218,7 +218,7 @@ DcmElement *DiDocument::search(const DcmTagKey &tag, 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()); } diff --git a/dcmiod/libsrc/iodutil.cc b/dcmiod/libsrc/iodutil.cc index 49830a611..cfe2b6e3a 100644 --- a/dcmiod/libsrc/iodutil.cc +++ b/dcmiod/libsrc/iodutil.cc @@ -43,7 +43,7 @@ OFCondition DcmIODUtil::getAndCheckElementFromDataset( 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 @@ OFCondition DcmIODUtil::getAndCheckElementFromDataset(DcmItem& dataset, 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()); diff --git a/dcmjpeg/libsrc/djcodece.cc b/dcmjpeg/libsrc/djcodece.cc index 45c447639..8c6cc70ef 100644 --- a/dcmjpeg/libsrc/djcodece.cc +++ b/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 @@ OFCondition DJCodecEncoder::correctVOIWindows( 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()); } diff --git a/dcmnet/apps/storescu.cc b/dcmnet/apps/storescu.cc index 59696ab5c..a144f40c5 100644 --- a/dcmnet/apps/storescu.cc +++ b/dcmnet/apps/storescu.cc @@ -1138,6 +1138,12 @@ updateStringAttributeValue(DcmItem *dataset, const DcmTagKey &key, OFString &val 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()); diff --git a/dcmnet/libsrc/dimcmd.cc b/dcmnet/libsrc/dimcmd.cc index 31dad0c38..57c1333f7 100644 --- a/dcmnet/libsrc/dimcmd.cc +++ b/dcmnet/libsrc/dimcmd.cc @@ -191,14 +191,16 @@ addString(DcmDataset *obj, DcmTagKey t, char *s, OFBool keepPadding) 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) { @@ -263,17 +265,19 @@ addUS(DcmDataset *obj, DcmTagKey t, Uint16 us) 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 @@ -314,17 +318,19 @@ addUL(DcmDataset *obj, DcmTagKey t, Uint32 ul) 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 @@ -375,15 +381,17 @@ addAttributeList(DcmDataset *obj, DcmTagKey t, Uint16 *lst, int listCount) 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) { @@ -395,7 +403,7 @@ getAttributeList(DcmDataset *obj, DcmTagKey t, Uint16 **lst, int *listCount) } } - return (ec == EC_Normal)?(EC_Normal):(DIMSE_PARSEFAILED); + return (ec.good())?(EC_Normal):(DIMSE_PARSEFAILED); } /* diff --git a/dcmnet/libsrc/diutil.cc b/dcmnet/libsrc/diutil.cc index b294afe56..e84af3dfe 100644 --- a/dcmnet/libsrc/diutil.cc +++ b/dcmnet/libsrc/diutil.cc @@ -159,23 +159,21 @@ DU_stripLeadingAndTrailingSpaces(char *s) 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 @@ DU_putStringDOElement(DcmItem *obj, DcmTagKey t, const char *s) ec = obj->insert(e, OFTrue); } - return (ec == EC_Normal); + return (ec.good()); } OFBool @@ -201,15 +199,15 @@ DU_getShortDOElement(DcmItem *obj, DcmTagKey t, Uint16 *us) { 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 @@ DU_putShortDOElement(DcmItem *obj, DcmTagKey t, Uint16 us) if (ec == EC_Normal) { ec = obj->insert(e, OFTrue); } - return (ec == EC_Normal); + return (ec.good()); } OFBool diff --git a/dcmnet/libsrc/dstorscu.cc b/dcmnet/libsrc/dstorscu.cc index db85304a7..4206e67c4 100644 --- a/dcmnet/libsrc/dstorscu.cc +++ b/dcmnet/libsrc/dstorscu.cc @@ -484,7 +484,7 @@ OFCondition DcmStorageSCU::addDicomFilesFromDICOMDIR(const OFFilename &filename, 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) diff --git a/dcmpstat/apps/dcmmklut.cc b/dcmpstat/apps/dcmmklut.cc index 23aa97dbe..7f63c9d43 100644 --- a/dcmpstat/apps/dcmmklut.cc +++ b/dcmpstat/apps/dcmmklut.cc @@ -971,7 +971,7 @@ int main(int argc, char *argv[]) { // 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 @@ int main(int argc, char *argv[]) { // 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) diff --git a/dcmpstat/apps/dcmpschk.cc b/dcmpstat/apps/dcmpschk.cc index e7716c6f6..e95d84cbb 100644 --- a/dcmpstat/apps/dcmpschk.cc +++ b/dcmpstat/apps/dcmpschk.cc @@ -652,7 +652,11 @@ static OFString printAttribute( 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 diff --git a/dcmpstat/libsrc/dviface.cc b/dcmpstat/libsrc/dviface.cc index 940c5c201..284844b49 100644 --- a/dcmpstat/libsrc/dviface.cc +++ b/dcmpstat/libsrc/dviface.cc @@ -1425,14 +1425,14 @@ OFBool DVInterface::createPStateCache() 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 @@ OFCondition DVInterface::saveFileFormatToDB(DcmFileFormat &fileformat) 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 @@ OFCondition DVInterface::addToPrintHardcopyFromDB(const char *studyUID, const ch 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()); diff --git a/dcmpstat/libsrc/dvpsabl.cc b/dcmpstat/libsrc/dvpsabl.cc index 62cc1d51b..bbda18183 100644 --- a/dcmpstat/libsrc/dvpsabl.cc +++ b/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 @@ OFCondition DVPSAnnotationContent_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpscu.cc b/dcmpstat/libsrc/dvpscu.cc index be3c81fe0..25ad2a1cb 100644 --- a/dcmpstat/libsrc/dvpscu.cc +++ b/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 @@ OFCondition DVPSCurve::read(DcmItem &dset, Uint8 group) /* 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 @@ OFCondition DVPSCurve::read(DcmItem &dset, Uint8 group) 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()); } diff --git a/dcmpstat/libsrc/dvpsdal.cc b/dcmpstat/libsrc/dvpsdal.cc index 519aa977f..969c18299 100644 --- a/dcmpstat/libsrc/dvpsdal.cc +++ b/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 @@ OFCondition DVPSDisplayedArea_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpsfs.cc b/dcmpstat/libsrc/dvpsfs.cc index 5a5173c15..ba311b258 100644 --- a/dcmpstat/libsrc/dvpsfs.cc +++ b/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 @@ OFBool DVPSFilmSession::printSCPCreate( { 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 @@ OFBool DVPSFilmSession::printSCPSet( 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 @@ OFBool DVPSFilmSession::printSCPSet( 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 @@ OFBool DVPSFilmSession::printSCPSet( { 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 @@ OFBool DVPSFilmSession::printSCPSet( { 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 @@ OFBool DVPSFilmSession::printSCPSet( 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 @@ OFBool DVPSFilmSession::printSCPSet( 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 @@ OFBool DVPSFilmSession::printSCPSet( 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 @@ OFBool DVPSFilmSession::printSCPSet( 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 @@ OFBool DVPSFilmSession::printSCPSet( { 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) diff --git a/dcmpstat/libsrc/dvpsgal.cc b/dcmpstat/libsrc/dvpsgal.cc index 909deac9e..89d893de8 100644 --- a/dcmpstat/libsrc/dvpsgal.cc +++ b/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 @@ OFCondition DVPSGraphicAnnotation_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpsgll.cc b/dcmpstat/libsrc/dvpsgll.cc index d82d20862..fbf5d97d7 100644 --- a/dcmpstat/libsrc/dvpsgll.cc +++ b/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 @@ OFCondition DVPSGraphicLayer_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpsgrl.cc b/dcmpstat/libsrc/dvpsgrl.cc index 14d0e713f..61dd6565c 100644 --- a/dcmpstat/libsrc/dvpsgrl.cc +++ b/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 @@ OFCondition DVPSGraphicObject_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpshlp.cc b/dcmpstat/libsrc/dvpshlp.cc index dc0576d6c..7691f0783 100644 --- a/dcmpstat/libsrc/dvpshlp.cc +++ b/dcmpstat/libsrc/dvpshlp.cc @@ -178,7 +178,7 @@ OFBool DVPSHelper::haveReferencedUIDItem(DcmSequenceOfItems& seq, const char *ui { 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()); diff --git a/dcmpstat/libsrc/dvpsib.cc b/dcmpstat/libsrc/dvpsib.cc index 096c5b3e1..8bf93b551 100644 --- a/dcmpstat/libsrc/dvpsib.cc +++ b/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 @@ OFCondition DVPSImageBoxContent::read(DcmItem &dset, DVPSPresentationLUT_PList& 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 @@ OFCondition DVPSImageBoxContent::read(DcmItem &dset, DVPSPresentationLUT_PList& // 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 @@ OFBool DVPSImageBoxContent::printSCPSet( 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 @@ OFBool DVPSImageBoxContent::printSCPSet( 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 @@ OFBool DVPSImageBoxContent::printSCPSet( { 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 @@ OFBool DVPSImageBoxContent::printSCPSet( 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 @@ OFBool DVPSImageBoxContent::printSCPSet( 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 @@ OFBool DVPSImageBoxContent::printSCPSet( 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 @@ OFBool DVPSImageBoxContent::printSCPSet( 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 @@ OFBool DVPSImageBoxContent::printSCPSet( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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 @@ OFBool DVPSImageBoxContent::printSCPEvaluateBasicGrayscaleImageSequence( 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) diff --git a/dcmpstat/libsrc/dvpsibl.cc b/dcmpstat/libsrc/dvpsibl.cc index e3768d5a0..ef069eb84 100644 --- a/dcmpstat/libsrc/dvpsibl.cc +++ b/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 @@ OFCondition DVPSImageBoxContent_PList::read(DcmItem &dset, DVPSPresentationLUT_P 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) diff --git a/dcmpstat/libsrc/dvpspll.cc b/dcmpstat/libsrc/dvpspll.cc index 1b2b7a35b..46465171c 100644 --- a/dcmpstat/libsrc/dvpspll.cc +++ b/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 @@ OFCondition DVPSPresentationLUT_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpsril.cc b/dcmpstat/libsrc/dvpsril.cc index 843a03081..19ec221ea 100644 --- a/dcmpstat/libsrc/dvpsril.cc +++ b/dcmpstat/libsrc/dvpsril.cc @@ -71,7 +71,7 @@ OFCondition DVPSReferencedImage_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpsrsl.cc b/dcmpstat/libsrc/dvpsrsl.cc index 4b0c83aa7..d2f9dcfff 100644 --- a/dcmpstat/libsrc/dvpsrsl.cc +++ b/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 @@ OFCondition DVPSReferencedSeries_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpssp.cc b/dcmpstat/libsrc/dvpssp.cc index 98b1201a7..717c81460 100644 --- a/dcmpstat/libsrc/dvpssp.cc +++ b/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 @@ OFCondition DVPSStoredPrint::read(DcmItem &dset) 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 @@ OFCondition DVPSStoredPrint::read(DcmItem &dset) // 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 @@ OFCondition DVPSStoredPrint::read(DcmItem &dset) 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 @@ OFCondition DVPSStoredPrint::read(DcmItem &dset) 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 @@ OFCondition DVPSStoredPrint::printSCUcreateBasicFilmBox(DVPSPrintMessageHandler& { // 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 @@ OFCondition DVPSStoredPrint::printSCUcreateBasicFilmBox(DVPSPrintMessageHandler& // 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 @@ OFBool DVPSStoredPrint::printSCPCreate( { 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 @@ OFBool DVPSStoredPrint::printSCPCreate( { 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( { 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 @@ OFBool DVPSStoredPrint::printSCPSet( { 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( 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 @@ OFBool DVPSStoredPrint::printSCPSet( { 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) diff --git a/dcmpstat/libsrc/dvpstxl.cc b/dcmpstat/libsrc/dvpstxl.cc index ffb6dcc10..8e35ff7ae 100644 --- a/dcmpstat/libsrc/dvpstxl.cc +++ b/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 @@ OFCondition DVPSTextObject_PList::read(DcmItem &dset) 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) diff --git a/dcmpstat/libsrc/dvpsvll.cc b/dcmpstat/libsrc/dvpsvll.cc index 3859f4ab9..17a627707 100644 --- a/dcmpstat/libsrc/dvpsvll.cc +++ b/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 @@ OFCondition DVPSVOILUT_PList::read(DcmItem &dset) 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) diff --git a/dcmrt/libsrc/drttypes.cc b/dcmrt/libsrc/drttypes.cc index 3aee4312f..456378a3a 100644 --- a/dcmrt/libsrc/drttypes.cc +++ b/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 @@ OFCondition DRTTypes::getAndCheckStringValueFromDataset(DcmItem &dataset, { 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) diff --git a/dcmsign/libsrc/dcsignat.cc b/dcmsign/libsrc/dcsignat.cc index 9e81a22d2..5fc9b85eb 100644 --- a/dcmsign/libsrc/dcsignat.cc +++ b/dcmsign/libsrc/dcsignat.cc @@ -102,7 +102,7 @@ OFCondition DcmSignature::getMACIDnumber(DcmItem &item, Uint16& macid) 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 @@ OFCondition DcmSignature::verifyCurrent() // 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 @@ OFCondition DcmSignature::verifyCurrent() 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 @@ OFCondition DcmSignature::verifyCurrent() 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 @@ OFCondition DcmSignature::getCurrentMacXferSyntaxName(OFString& str) 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 @@ OFCondition DcmSignature::getCurrentMacName(OFString& str) 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 @@ OFCondition DcmSignature::getCurrentSignatureUID(OFString& str) 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 @@ OFCondition DcmSignature::getCurrentSignatureDateTime(OFString& str) 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 @@ OFCondition DcmSignature::verifySignatureProfile(SiSecurityProfile &sprof) // 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 @@ OFCondition DcmSignature::verifySignatureProfile(SiSecurityProfile &sprof) { 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()) diff --git a/dcmsign/libsrc/sicert.cc b/dcmsign/libsrc/sicert.cc index 683f4f1a0..49953fe99 100644 --- a/dcmsign/libsrc/sicert.cc +++ b/dcmsign/libsrc/sicert.cc @@ -147,7 +147,7 @@ OFCondition SiCertificate::read(DcmItem& item) 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 @@ OFCondition SiCertificate::read(DcmItem& item) { 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; diff --git a/dcmsr/libsrc/dsrtypes.cc b/dcmsr/libsrc/dsrtypes.cc index c5b38546d..da92280ff 100644 --- a/dcmsr/libsrc/dsrtypes.cc +++ b/dcmsr/libsrc/dsrtypes.cc @@ -1176,7 +1176,7 @@ 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()) + if (result.good() && (dynamic_cast<DcmElement*>(stack.top()) != nullptr)) { /* copy object from search stack */ result = delem.copyFrom(*stack.top()); @@ -1201,7 +1201,7 @@ OFCondition DSRTypes::getAndCheckStringValueFromDataset(DcmItem &dataset, { 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 */ -- 2.30.2
>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
>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