]> Creatis software - gdcm.git/commitdiff
Fix a bug ... when reading a bugged DICOMDIR.
authorjpr <jpr>
Mon, 18 Jun 2007 11:10:17 +0000 (11:10 +0000)
committerjpr <jpr>
Mon, 18 Jun 2007 11:10:17 +0000 (11:10 +0000)
(When Sequence terminator is missing, gdcm::Document parsing crashed on Windows)
Thx to Dr Gianni Lazzarato for reporting the bug.

src/gdcmDocument.cxx
src/gdcmDocument.h

index 717fd44a8c2d01b513a87a52bd4741c0a4470fee..77af0cc52660ac0d3414266a3b662ade6daafe28 100644 (file)
@@ -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")
index e3d0d74a937a24894642d3d832dd1da4a6024438..6f2fbe711055e4292f0a8d4e0ca5fe8850f7a61e 100644 (file)
@@ -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