Uploading an old GIF image, got this error:

ValueError: imagecolorsforindex(): Argument #2 ($color) is out of range in imagecolorsforindex() (line 324 of /path/to/backdrop1/core/modules/system/image.gd.inc).

The code at that line is:

      $transparent_color = imagecolorsforindex($image->resource, $transparent);

The value of $transparent turns out to be 255 for that image. Idk why that would be "out of range". Thoughts?

Comments

@herb -

Perhaps I wasn't clear. The function is there in Backdrop but the code to handle the problem of this specific case is not. Specifically, the Drupal code for the function includes the following in the if ($transparent >= 0) condition:

    if ($transparent >= 0) {
      // Find out the number of colors in the image palette. It will be 0 for
      // truecolor images.
      $palette_size = imagecolorstotal($image->resource);
      if ($palette_size == 0 || $transparent < $palette_size) {
        // Set the transparent color in the new resource, either if it is a
        // truecolor image or if the transparent color is part of the palette.
        // Since the index of the transparency color is a property of the
        // image rather than of the palette, it is possible that an image
        // could be created with this index set outside the palette size (see
        // http://stackoverflow.com/a/3898007).
        $transparent_color = imagecolorsforindex($image->resource, $transparent);
        $transparent = imagecolorallocate($res, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
        // Flood with our new transparent color.
        imagefill($res, 0, 0, $transparent);
        imagecolortransparent($res, $transparent);
      }
      else {
        imagefill($res, 0, 0, imagecolorallocate($res, 255, 255, 255));
      }
    }

The Backdrop version of the function has this code instead:

   if ($transparent >= 0) {
     // The original must have a transparent color, allocate to the new image.
     $transparent_color = imagecolorsforindex($image->resource, $transparent);
     $transparent = imagecolorallocate($res, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
     // Flood with our new transparent color.
     imagefill($res, 0, 0, $transparent);
     imagecolortransparent($res, $transparent);
   }

There's no checking of the palette size to see whether the value returned for $transparent is valid. The included link to stackoverflow in the D7 code comments describes the problem in more detail.

I really don't know why PHP doesn't handle this more elegantly but apparently it still doesn't. I'm running PHP 8.2.25.