nothings / stb

stb single-file public domain libraries for C/C++
https://twitter.com/nothings
Other
25.99k stars 7.67k forks source link

stb image / gif decoder: Segmentation fault on animated gif with "disposal previous" mode #1504

Open coolcornucopia opened 1 year ago

coolcornucopia commented 1 year ago

Describe the bug I encountered a "Segmentation fault" while calling stbi_load_gif_from_memory() with the animated gif from the GIF wikipedia french page.

tl;dr I use gifsicle to optimise and fix animated gif that are not properly decoded with stb image:

gifsicle -O3 gif_creating_seg_fault_with stb_image.gif -o gif_ok_with_stb_image.gif

To Reproduce I did a git repo to help reproducing the issue named https://github.com/coolcornucopia/stb-image-gif-apng-short-examples

Steps to reproduce the behavior:

  1. git clone https://github.com/coolcornucopia/stb-image-gif-apng-short-examples.git
  2. Follow the build instructions in the git related page, repeated below
# Get latest stb_image.h from https://github.com/nothings/stb
wget https://raw.githubusercontent.com/nothings/stb/master/stb_image.h -O src/stb_image.h -q

# Download a nice animated gif with transparency
# Credit: Wikipedia, License: Creative Commons Attribution-Share Alike 4.0 International
wget https://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia_logo_puzzle_globe_spins_horizontally_and_vertically%2C_revealing_the_contents_of_all_of_its_puzzle_pieces%2C_without_background.gif -O wikipedia.gif -q

# Build in release (use "make debug" for step by step debug)
make clean release
build/stb_image_gif_example wikipedia.gif

The issue occurs when calling the stbi_load_gif_from_memory() function with the gif previously loaded in memory.

Expected behavior No segmentation fault for this animated gif from the GIF wikipedia french page :smile:.

My two cents first analysis Using gdb, the segmentation fault occurs in stbi__gif_load_next().

I have tried more animated gif and I noticed that animated gif with "disposal background" work fine, others with "disposal previous" generate the segmentation fault. To check the disposal mode, I use the famous gifsicle

gifsicle -I gif_creating_seg_fault_with stb_image.gif | grep "disposal" # you will have "disposal previous delay 0.04s"
gifsicle -I gif_ok_with_stb_image.gif | grep "disposal" # you will have "disposal background delay 0.04s"

Many thanks for this nice library :smile: peace coolcornucopia