From 2ae8698d36d498b85f9766b5bc54f42d19d81193 Mon Sep 17 00:00:00 2001 From: jpr Date: Mon, 18 Jun 2007 11:10:17 +0000 Subject: [PATCH] Fix a bug ... when reading a bugged DICOMDIR. (When Sequence terminator is missing, gdcm::Document parsing crashed on Windows) Thx to Dr Gianni Lazzarato for reporting the bug. --- src/gdcmDocument.cxx | 33 +++++++++++++++++++++------------ src/gdcmDocument.h | 8 +++++--- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/gdcmDocument.cxx b/src/gdcmDocument.cxx index 717fd44a..77af0cc5 100644 --- a/src/gdcmDocument.cxx +++ b/src/gdcmDocument.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.cxx,v $ Language: C++ - Date: $Date: 2007/06/15 13:16:55 $ - Version: $Revision: 1.360 $ + Date: $Date: 2007/06/18 11:10:17 $ + Version: $Revision: 1.361 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -71,6 +71,7 @@ Document::Document() SetFileName(""); changeFromUN=false; + UnexpectedEOF=false; } /** @@ -919,7 +920,7 @@ bool Document::operator<(Document &document) /** * \brief Reads a given length of bytes - * (in order to avoid to many CPU time consuming fread-s) + * (in order to avoid to many CPU time-consuming fread-s) * @param l length to read */ void Document::ReadBegBuffer(size_t l) @@ -1283,11 +1284,11 @@ void Document::ParseDES(DocEntrySet *set, long offset, << " at offset 0x(" << std::hex << newDocEntry->GetOffset() << ")"); - ParseSQ( newSeqEntry, - newDocEntry->GetOffset(), - l, delim_mode_intern); + bool res = ParseSQ( newSeqEntry, + newDocEntry->GetOffset(), + l, delim_mode_intern); - gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern); + gdcmDebugMacro( "Exit from ParseSQ, delim " << delim_mode_intern << " -->return : " << res); } if ( !set->AddEntry( newSeqEntry ) ) { @@ -1319,15 +1320,18 @@ void Document::ParseDES(DocEntrySet *set, long offset, newDocEntry->Delete(); } first = false; + + if (UnexpectedEOF) // some terminator was missing + break; } // end While gdcmDebugMacro( "Exit from ParseDES, delim-mode " << delim_mode ); } /** * \brief Parses a Sequence ( SeqEntry after SeqEntry) - * @return parsed length for this level + * @return false if expected fff0,e000 not found */ -void Document::ParseSQ( SeqEntry *seqEntry, +bool Document::ParseSQ( SeqEntry *seqEntry, long offset, long l_max, bool delim_mode) { int SQItemNumber = 0; @@ -1340,9 +1344,12 @@ void Document::ParseSQ( SeqEntry *seqEntry, DocEntry *newDocEntry = ReadNextDocEntry(); if ( !newDocEntry ) - { + { + // The most frequent is when a SQ terminator is missing (?!?) gdcmWarningMacro("in ParseSQ : should never get here!"); - break; + UnexpectedEOF = true; + return false; + //break; } if ( delim_mode ) { @@ -1390,6 +1397,7 @@ void Document::ParseSQ( SeqEntry *seqEntry, break; } } + return true; } /** @@ -2256,7 +2264,7 @@ DocEntry *Document::ReadNextDocEntry() } } } - + // if UN found, let's check the dictionary, and trust it! // (maybe a private dictionary exists?) else if (vr == "UN") @@ -2276,6 +2284,7 @@ DocEntry *Document::ReadNextDocEntry() } } + DocEntry *newEntry; //if ( Global::GetVR()->IsVROfSequence(realVR) ) if (realVR == "SQ") diff --git a/src/gdcmDocument.h b/src/gdcmDocument.h index e3d0d74a..6f2fbe71 100644 --- a/src/gdcmDocument.h +++ b/src/gdcmDocument.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.h,v $ Language: C++ - Date: $Date: 2007/06/15 13:16:56 $ - Version: $Revision: 1.144 $ + Date: $Date: 2007/06/18 11:10:17 $ + Version: $Revision: 1.145 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -201,7 +201,7 @@ private: // Read void ParseDES(DocEntrySet *set, long offset, long l_max, bool delim_mode); - void ParseSQ (SeqEntry *seq, long offset, long l_max, bool delim_mode); + bool ParseSQ (SeqEntry *seq, long offset, long l_max, bool delim_mode); void LoadDocEntry (DocEntry *e, bool forceLoad = false); void FindDocEntryLength (DocEntry *e) throw ( FormatError ); @@ -264,6 +264,8 @@ private: /// \brief to indicate if last supposed to be UN DataElement is not /// (according to a private Dicom dictionary) bool changeFromUN; + /// \brief whether an unexpected EOF was encountered + bool UnexpectedEOF; }; } // end namespace gdcm -- 2.45.1