From 12339d3b5bcfa0399b4d7468a53ec5fe662a4fc6 Mon Sep 17 00:00:00 2001 From: Justin Israel Date: Sun, 16 Jul 2023 19:29:07 +1200 Subject: [PATCH] Fix windows fdopen error (refs #229) --- .github/workflows/ci.yml | 2 +- imagick/magick_wand_image.go | 10 ++++++++-- imagick/magick_wand_test.go | 29 +++++++++++++++++++++++++++++ imagick/memory.go | 3 +++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f102392..41c07f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ on: jobs: test: - name: Test ImageMagick6 + name: Test ImageMagick6 linux runs-on: ubuntu-latest environment: imagemagick6 env: diff --git a/imagick/magick_wand_image.go b/imagick/magick_wand_image.go index 38ba2f1..f3c77da 100644 --- a/imagick/magick_wand_image.go +++ b/imagick/magick_wand_image.go @@ -3380,11 +3380,17 @@ func (mw *MagickWand) WriteImagesFile(out *os.File) error { // cfdopen returns a C-level FILE*. mode should be as described in fdopen(3). // Caller is responsible for closing the file when successfully returned, // via C.fclose() -func cfdopen(file *os.File, mode string) (*C.FILE, error) { +func cfdopen(file *os.File, mode string) (cfile *C.FILE, err error) { + cname := C.CString(file.Name()) cmode := C.CString(mode) + defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cmode)) - cfile, err := C.fdopen(C.dup(C.int(file.Fd())), cmode) + if file.Name() != "" { + cfile, err = C.fopen(cname, cmode) + } else { + cfile, err = C.fdopen(C.dup(C.int(file.Fd())), cmode) + } if err != nil { return nil, err } diff --git a/imagick/magick_wand_test.go b/imagick/magick_wand_test.go index 94e030f..b5477a0 100644 --- a/imagick/magick_wand_test.go +++ b/imagick/magick_wand_test.go @@ -6,6 +6,8 @@ package imagick import ( "fmt" + "io/ioutil" + "os" "reflect" "runtime" "sync/atomic" @@ -127,6 +129,33 @@ func TestDeleteImageArtifact(t *testing.T) { } } +func TestReadImageFile(t *testing.T) { + Initialize() + defer Terminate() + + mw := NewMagickWand() + if err := mw.ReadImage(`logo:`); err != nil { + t.Fatal(err) + } + + tmp, err := ioutil.TempFile("", "imagick_test-*.jpg") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmp.Name()) + + if err := mw.WriteImage(tmp.Name()); err != nil { + t.Fatal(err) + } + mw.Destroy() + + mw = NewMagickWand() + defer mw.Destroy() + if err := mw.ReadImageFile(tmp); err != nil { + t.Fatal(err) + } +} + func TestReadImageBlob(t *testing.T) { Initialize() defer func(t *testing.T) { diff --git a/imagick/memory.go b/imagick/memory.go index d92079a..3bd4ba1 100644 --- a/imagick/memory.go +++ b/imagick/memory.go @@ -23,6 +23,9 @@ func relinquishMemory(ptr unsafe.Pointer) { // relinquishes memory resources, null terminated array of strings func relinquishMemoryCStringArray(p **C.char) { + if p == nil { + return + } defer relinquishMemory(unsafe.Pointer(p)) for *p != nil { relinquishMemory(unsafe.Pointer(*p))