Skip to content

MagickCoreSignature assertion while CoalesceImages #169

@CMogilko

Description

@CMogilko

Hi,
I've got panic by SIGABRT while making ThumbnailImage() with CoalesceImages() and gif-files.

magick/profile.c:120: CloneImageProfiles: Assertion `clone_image->signature == MagickCoreSignature' failed.
SIGABRT: abort

It seems that image blob was corrupted.

My environment:
OS: fedora 28
Go: go version go1.10.3 linux/amd64
ImageMagick: ImageMagick-6.9.9.38-1.fc28.x86_64

Panic stacktrace:

test: magick/profile.c:120: CloneImageProfiles: Assertion `clone_image->signature == MagickCoreSignature' failed.
SIGABRT: abort
PC=0x7ffa02ed2eab m=33 sigcode=18446744073709551610

goroutine 0 [idle]:
runtime: unknown pc 0x7ffa02ed2eab
stack: frame={sp:0x7ff9a0bf29f0, fp:0x0} stack=[0x7ff9a03f31d0,0x7ff9a0bf2dd0)
00007ff9a0bf28f0:  000000000000000c  00007ff964000920 
00007ff9a0bf2900:  00000000000000b0  00000000000000c0 
00007ff9a0bf2910:  0000000007fffff7  40e0000000000000 
00007ff9a0bf2920:  4059000000000000  4059000000000000 
00007ff9a0bf2930:  0000000000000000  0000000000000000 
00007ff9a0bf2940:  0000000000000000  00007ffa009859b2 
00007ff9a0bf2950:  0000000d00000001  00007ff900000001 
00007ff9a0bf2960:  0000000000000000  0000000000000008 
00007ff9a0bf2970:  40b1110000000000  40a4140000000000 
00007ff9a0bf2980:  40a8180000000000  0000000000000000 
00007ff9a0bf2990:  0000000000000000  0000000000000003 
00007ff9a0bf29a0:  0000000d00000001  00007ff900000001 
00007ff9a0bf29b0:  0000000000000000  0000000000000008 
00007ff9a0bf29c0:  3032310000000000  705138f2a6326200 
00007ff9a0bf29d0:  00007ff9a0bf2a10  0000000000000072 
00007ff9a0bf29e0:  0000000000000072  00007ff9a0bf2c50 
00007ff9a0bf29f0: <0000000000000000  00007ff9652d5ec0 
00007ff9a0bf2a00:  00007ff9a0bf2ce0  00007ffa02f147b7 
00007ff9a0bf2a10:  00000000fbad8000  00007ff9652d5ec0 
00007ff9a0bf2a20:  00007ff9652d5f25  00007ff9652d5ec0 
00007ff9a0bf2a30:  00007ff9652d5ec0  00007ff9652d5f32 
00007ff9a0bf2a40:  00007ff9652d5fec  00007ff9652d5ec0 
00007ff9a0bf2a50:  00007ff9652d5fec  0000000000000000 
00007ff9a0bf2a60:  0000000000000000  0000000000000000 
00007ff9a0bf2a70:  fffffffe7fffffff  ffffffffffffffff 
00007ff9a0bf2a80:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2a90:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2aa0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ab0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ac0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ad0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ae0:  ffffffffffffffff  ffffffffffffffff 
runtime: unknown pc 0x7ffa02ed2eab
stack: frame={sp:0x7ff9a0bf29f0, fp:0x0} stack=[0x7ff9a03f31d0,0x7ff9a0bf2dd0)
00007ff9a0bf28f0:  000000000000000c  00007ff964000920 
00007ff9a0bf2900:  00000000000000b0  00000000000000c0 
00007ff9a0bf2910:  0000000007fffff7  40e0000000000000 
00007ff9a0bf2920:  4059000000000000  4059000000000000 
00007ff9a0bf2930:  0000000000000000  0000000000000000 
00007ff9a0bf2940:  0000000000000000  00007ffa009859b2 
00007ff9a0bf2950:  0000000d00000001  00007ff900000001 
00007ff9a0bf2960:  0000000000000000  0000000000000008 
00007ff9a0bf2970:  40b1110000000000  40a4140000000000 
00007ff9a0bf2980:  40a8180000000000  0000000000000000 
00007ff9a0bf2990:  0000000000000000  0000000000000003 
00007ff9a0bf29a0:  0000000d00000001  00007ff900000001 
00007ff9a0bf29b0:  0000000000000000  0000000000000008 
00007ff9a0bf29c0:  3032310000000000  705138f2a6326200 
00007ff9a0bf29d0:  00007ff9a0bf2a10  0000000000000072 
00007ff9a0bf29e0:  0000000000000072  00007ff9a0bf2c50 
00007ff9a0bf29f0: <0000000000000000  00007ff9652d5ec0 
00007ff9a0bf2a00:  00007ff9a0bf2ce0  00007ffa02f147b7 
00007ff9a0bf2a10:  00000000fbad8000  00007ff9652d5ec0 
00007ff9a0bf2a20:  00007ff9652d5f25  00007ff9652d5ec0 
00007ff9a0bf2a30:  00007ff9652d5ec0  00007ff9652d5f32 
00007ff9a0bf2a40:  00007ff9652d5fec  00007ff9652d5ec0 
00007ff9a0bf2a50:  00007ff9652d5fec  0000000000000000 
00007ff9a0bf2a60:  0000000000000000  0000000000000000 
00007ff9a0bf2a70:  fffffffe7fffffff  ffffffffffffffff 
00007ff9a0bf2a80:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2a90:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2aa0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ab0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ac0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ad0:  ffffffffffffffff  ffffffffffffffff 
00007ff9a0bf2ae0:  ffffffffffffffff  ffffffffffffffff 

goroutine 486 [syscall]:
runtime.cgocall(0x4acfd0, 0xc4203ebe88, 0x454faf)
	/usr/lib/golang/src/runtime/cgocall.go:128 +0x64 fp=0xc4203ebe58 sp=0xc4203ebe20 pc=0x418734
gopkg.in/gographics/imagick.v2/imagick._Cfunc_MagickCoalesceImages(0x7ff9652e8d50, 0x0)
	_cgo_gotypes.go:4037 +0x4a fp=0xc4203ebe88 sp=0xc4203ebe58 pc=0x4a63aa
gopkg.in/gographics/imagick.v2/imagick.(*MagickWand).CoalesceImages.func1(0x7ff9652e8d50, 0x3)
	/root/fe/gopath/src/gopkg.in/gographics/imagick.v2/imagick/magick_wand_image.go:357 +0x56 fp=0xc4203ebec0 sp=0xc4203ebe88 pc=0x4a80e6
gopkg.in/gographics/imagick.v2/imagick.(*MagickWand).CoalesceImages(0xc4200a8180, 0x3)
	/root/fe/gopath/src/gopkg.in/gographics/imagick.v2/imagick/magick_wand_image.go:357 +0x2e fp=0xc4203ebee0 sp=0xc4203ebec0 pc=0x4a76fe
main.(*ImageMagick).Resize(0x791fe0, 0xc42758a000, 0x1780ac, 0x1782ac, 0x1782ac, 0x0, 0x0, 0x0, 0x0)
	/root/fe/gopath/src/test/main.go:112 +0x2d8 fp=0xc4203ebf40 sp=0xc4203ebee0 pc=0x4aab48
main.do.func1(0xc426b24190, 0x4fbe80, 0x791fe0, 0x4f0253, 0x44)
	/root/fe/gopath/src/test/main.go:66 +0xfd fp=0xc4203ebfb8 sp=0xc4203ebf40 pc=0x4aadbd
runtime.goexit()
	/usr/lib/golang/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc4203ebfc0 sp=0xc4203ebfb8 pc=0x4669b1
created by main.do
	/root/fe/gopath/src/test/main.go:58 +0xf3

Test tool for reproducing, it may be required to run tool up to 10 times to get panic. Gif is attached to issue.

package main

import (
	"fmt"
	"gopkg.in/gographics/imagick.v2/imagick"
	"io/ioutil"
	"runtime"
	"strings"
	"sync"
)

func main() {
	do()
}

func do() {
	p, err := NewImageMagick()
	if err != nil {
		fmt.Println(err)
		return
	}

	files := []string{
		"1411808383_1369456619-ae4fe668748eb6af81bdf35a2d9a13ad.gif",
		"1411808383_1369456619-ae4fe668748eb6af81bdf35a2d9a13ad.gif",
		"1411808383_1369456619-ae4fe668748eb6af81bdf35a2d9a13ad.gif",
		"1411808383_1369456619-ae4fe668748eb6af81bdf35a2d9a13ad.gif",
		"1411808383_1369456619-ae4fe668748eb6af81bdf35a2d9a13ad.gif",
	}

	for k := 0; k < 10; k++ {
		wg := &sync.WaitGroup{}
		for j := 0; j < 10; j++ {

			for i := range files {
				wg.Add(1)
				go func(file string) {
					defer wg.Done()
					raw, err := ioutil.ReadFile(file)
					if err != nil {
						fmt.Println(err)
						return
					}

					_, err = p.Resize(raw)
					if err != nil {
						fmt.Println(err)
						return
					}

					//fmt.Printf("result: %+v\n", i)
				}(files[i])
			}
		}
		wg.Wait()
		fmt.Println("ok")
	}
}

type Processor interface {
	Resize([]byte) ([]byte, error)
}

type ImageMagick struct {
}

func (i *ImageMagick) Resize(blob []byte) ([]byte, error) {
	mw := imagick.NewMagickWand()

	err := mw.ReadImageBlob(blob)
	if err != nil {
		return nil, err
	}

	err = mw.StripImage()
	if err != nil {
		return nil, err
	}

	originalFormat := mw.GetImageFormat()
	err = mw.SetImageFormat("gif")
	if err != nil {
		return nil, err
	}

	err = mw.SetImageCompressionQuality(75)
	if err != nil {
		return nil, err
	}
	if strings.ToLower(originalFormat) == "gif" {
		mw = mw.CoalesceImages()
	}
	factor := float64(mw.GetImageHeight()) / float64(mw.GetImageWidth())

	previewHeight := RoundTo2(uint(factor * float64(140)))
	err = mw.ThumbnailImage(140, previewHeight)
	if err != nil {
		return nil, err
	}

	return mw.GetImageBlob(), nil
}

func NewImageMagick() (Processor, error) {
	imagick.Initialize()

	i := &ImageMagick{}

	runtime.SetFinalizer(i, func(_ *ImageMagick) {
		imagick.Terminate()
	})

	return i, nil
}

func RoundTo2(in uint) uint {
	if in%2 != 0 {
		return in + 1
	}
	return in
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions