@@ -156,9 +156,49 @@ struct vtkF3DQuakeMDLImporter::vtkInternals
156156 return reinterpret_cast <const mdl_simpleframe_t *>(buffer.data () + offset);
157157 }
158158
159+ // ----------------------------------------------------------------------------
160+ static bool ReadAndCheckHeader (const std::vector<uint8_t >& buffer, vtkObject* object,
161+ size_t & offset, const mdl_header_t *& header)
162+ {
163+ // Read header
164+ try
165+ {
166+ header = vtkInternals::ReadFromVector<mdl_header_t >(buffer, offset);
167+ }
168+ catch (const F3DRangeError&)
169+ {
170+ if (object)
171+ {
172+ vtkErrorWithObjectMacro (object, " Invalid MDL file" );
173+ }
174+ return false ;
175+ }
176+
177+ // Check magic number for "IPDO" or "IDST"
178+ if (!(header->ident == 0x4F504449 || header->ident == 0x54534449 ))
179+ {
180+ if (object)
181+ {
182+ vtkErrorWithObjectMacro (object, " Incompatible MDL header" );
183+ }
184+ return false ;
185+ }
186+
187+ // Check version for v6 exactly
188+ if (header->version != 6 )
189+ {
190+ if (object)
191+ {
192+ vtkErrorWithObjectMacro (object, " Unsupported MDL version. Only version 6 is supported" );
193+ }
194+ return false ;
195+ }
196+ return true ;
197+ }
198+
159199 // ----------------------------------------------------------------------------
160200 // Safer buffer typecasting with auto offset incrementing with variable length data
161- const mdl_simpleframe_t * ReadFromVectorSimpleframe (
201+ static const mdl_simpleframe_t * ReadFromVectorSimpleframe (
162202 const std::vector<uint8_t >& buffer, size_t & offset, size_t num_verts = 0 )
163203 {
164204 static constexpr auto mdl_simpleframe_t_fixed_size =
@@ -563,34 +603,15 @@ struct vtkF3DQuakeMDLImporter::vtkInternals
563603 stream->Seek (0 , vtkResourceStream::SeekDirection::Begin);
564604
565605 // Read stream into buffer
606+ // TODO rework to avoid copying the whole buffer
566607 std::vector<uint8_t > buffer (length);
567608 stream->Read (buffer.data (), length);
568609
569- // Read header
570- // XXX: This is completely unsafe, should be rewritten using modern API
610+ // Read Header
571611 size_t offset = 0 ;
572612 const mdl_header_t * header;
573- try
574- {
575- header = vtkInternals::ReadFromVector<mdl_header_t >(buffer, offset);
576- }
577- catch (const F3DRangeError&)
578- {
579- vtkErrorWithObjectMacro (this ->Parent , " Invalid MDL file" );
580- return false ;
581- }
582-
583- // Check magic number for "IPDO" or "IDST"
584- if (!(header->ident == 0x4F504449 || header->ident == 0x54534449 ))
613+ if (!vtkInternals::ReadAndCheckHeader (buffer, this ->Parent , offset, header))
585614 {
586- vtkErrorWithObjectMacro (this ->Parent , " Incompatible MDL header" );
587- return false ;
588- }
589-
590- // Check version for v6 exactly
591- if (header->version != 6 )
592- {
593- vtkErrorWithObjectMacro (this ->Parent , " Unsupported MDL version. Only version 6 is supported" );
594615 return false ;
595616 }
596617
@@ -791,3 +812,30 @@ bool vtkF3DQuakeMDLImporter::GetTemporalInformation(
791812 }
792813 return true ;
793814}
815+
816+ // ------------------------------------------------------------------------------
817+ bool vtkF3DQuakeMDLImporter::CanReadFile (vtkResourceStream* stream)
818+ {
819+ if (!stream)
820+ {
821+ return false ;
822+ }
823+
824+ // Read header into buffer
825+ std::size_t headerSize = sizeof (vtkInternals::mdl_header_t );
826+ stream->Seek (0 , vtkResourceStream::SeekDirection::Begin);
827+ std::vector<uint8_t > buffer (headerSize);
828+ if (stream->Read (buffer.data (), headerSize) != headerSize)
829+ {
830+ return false ;
831+ }
832+
833+ // Check header buffer
834+ size_t offset = 0 ;
835+ const vtkInternals::mdl_header_t * header;
836+ if (!vtkInternals::ReadAndCheckHeader (buffer, nullptr , offset, header))
837+ {
838+ return false ;
839+ }
840+ return true ;
841+ }
0 commit comments