f3d-app / f3d

Fast and minimalist 3D viewer.
https://f3d.app
BSD 3-Clause "New" or "Revised" License
2.93k stars 216 forks source link

Segfault on opening gltf without textures #1479

Closed spevnev closed 4 months ago

spevnev commented 5 months ago

Describe the bug gltf files contain list of images/textures and when it is opened without these images in the path f3d segfaults. It probably happens with other file formats, but I haven't tested them. Here's the stack trace:

0   libvtkIOGeometry-9.3.9.3.dylib vtkGLTFDocumentLoader::LoadImageData() + 688
1   libvtkIOGeometry-9.3.9.3.dylib vtkGLTFDocumentLoader::LoadModelData(std::vector<char> const&) + 512
2   libvtkIOImport-9.3.9.3.dylib   vtkGLTFImporter::ImportBegin() + 588
3   libvtkIOImport-9.3.9.3.dylib   vtkImporter::Read() + 140
4   libf3d.2.4.dylib               vtkImporter::Update() + 4 (vtkImporter.h:80) [inlined]
5   libf3d.2.4.dylib               f3d::detail::loader_impl::loadScene(std::string const&) + 1008 (loader_impl.cxx:318)
6   f3d                            F3DStarter::LoadFile(int, bool) + 3300 (F3DStarter.cxx:810)

To Reproduce Steps to reproduce the behavior:

  1. Rename/move/delete textures required by gltf in order so that the path specified in the file no longer exists
  2. Open the file using f3d example.gltf

Expected behavior Either generic error message like "Error opening gltf file" or better yet "Error loading texture TEXTURE_PATH required by GLTF_PATH: file doesn't exist"

System Information:

F3D Information Paste the content of f3d --version:

F3D 2.4.0

F3D - A fast and minimalist 3D viewer
Version: 2.4.0-77-gd8960d10.
Build date: 2024-06-21 19:35:51.
Build system: Darwin 64-bits.
Compiler: AppleClang 15.0.0.15000309.
External rendering module: OFF.
Raytracing module: OFF.
VTK version: 9.3.0.

Additional context It happens in libvtk which (if I understand correctly) is a dependency, so to fix we need to read these texture paths (are they already read/available somewhere?) from the gltf file and check that they exist before calling libvtk functions.

mwestphal commented 5 months ago

Could you share example.gltf ?

spevnev commented 5 months ago

It isn't any specific file. For instance, take gearbox_animation from f3d-data. In its gltf file you can see

  "images": [
    {
      "uri": "textures/Material_26_metallicRoughness.png"
    },
    {
      "uri": "textures/Material_26_normal.png"
    },
    {
      "uri": "textures/Material_26_baseColor.png"
    },
    ...
  ]

And if you remove any of these, or the entire folder, i.e. make uri no longer as files do not exist, it causes segfault. It probably doesn't check files before loading them.

I've attachied zips of 2 examples (couldn't upload as single file due to 25MB upload limit): originals: for reference (both are taken from f3d-data) original_gearbox.zip original_bristleback.zip file_missing: deleted one texture file -> segfault file_missing_gearbox.zip file_missing_bristleback.zip folder_missing: deleted all textures -> segfault folder_missing_gearbox.zip folder_missing_bristleback.zip

mwestphal commented 5 months ago
Thread 1 "f3d" received signal SIGSEGV, Segmentation fault.
0x00007ffff2ea3fcc in vtkGLTFDocumentLoader::LoadImageData (this=0x55555658e910) at /home/glow/dev/vtk/vtk1/src/IO/Geometry/vtkGLTFDocumentLoader.cxx:848
848           if (stream->Read(buffer.data(), buffer.size()) != buffer.size())
(gdb) bt
#0  0x00007ffff2ea3fcc in vtkGLTFDocumentLoader::LoadImageData (this=0x55555658e910) at /home/glow/dev/vtk/vtk1/src/IO/Geometry/vtkGLTFDocumentLoader.cxx:848
#1  0x00007ffff2ea55f8 in vtkGLTFDocumentLoader::LoadModelData (this=0x55555658e910, glbBuffer=std::vector of length 0, capacity 0)
    at /home/glow/dev/vtk/vtk1/src/IO/Geometry/vtkGLTFDocumentLoader.cxx:976
#2  0x00007ffff375dd95 in vtkGLTFImporter::ImportBegin (this=0x555555cdf160) at /home/glow/dev/vtk/vtk1/src/IO/Import/vtkGLTFImporter.cxx:398
#3  0x00007ffff3775926 in vtkImporter::Read (this=0x555555cdf160) at /home/glow/dev/vtk/vtk1/src/IO/Import/vtkImporter.cxx:73
#4  0x00007ffff6070e78 in vtkImporter::Update (this=0x555555cdf160) at /home/glow/dev/vtk/vtk1/src/IO/Import/vtkImporter.h:92
#5  0x00007ffff60702bd in f3d::detail::loader_impl::loadScene (this=0x555555cce7b0, filePath="/home/glow/data/tmp/gearbox/scene.gltf")
    at /home/glow/dev/f3d/f3d/src/library/src/loader_impl.cxx:318
#6  0x000055555566d979 in F3DStarter::LoadFile (this=0x7fffffffe5b8, index=0, relativeIndex=false) at /home/glow/dev/f3d/f3d/src/application/F3DStarter.cxx:810
#7  0x000055555566c399 in F3DStarter::Start (this=0x7fffffffe5b8, argc=2, argv=0x7fffffffe718) at /home/glow/dev/f3d/f3d/src/application/F3DStarter.cxx:576
#8  0x000055555567ac1e in main (argc=2, argv=0x7fffffffe718) at /home/glow/dev/f3d/f3d/src/application/main.cxx:13
(gdb) 
mwestphal commented 5 months ago

Partial fix: https://gitlab.kitware.com/vtk/vtk/-/merge_requests/11256

mwestphal commented 5 months ago

Complete fix will require to work on the importer API: https://github.com/f3d-app/f3d/issues/653

mwestphal commented 5 months ago

Fixed in VTK thanks for https://gitlab.kitware.com/vtk/vtk/-/merge_requests/11267

Need a bit more work to integrate in F3D

mwestphal commented 4 months ago

fixed by https://github.com/f3d-app/f3d/pull/1512