From 0b64024541ce6b3e62d44488743b7ce8fe0126b2 Mon Sep 17 00:00:00 2001 From: Justin Israel Date: Sun, 29 Mar 2020 13:20:09 +1300 Subject: [PATCH 1/4] Create test to reproduce fdopen crash in windows --- imagick/magick_wand_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/imagick/magick_wand_test.go b/imagick/magick_wand_test.go index 23f242b..21505f7 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" @@ -161,6 +163,33 @@ func TestImageChannelMask(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) { From 5017f52e31ccdd80d211b83ff8cd23560f101f3e Mon Sep 17 00:00:00 2001 From: Justin Israel Date: Sun, 16 Jul 2023 17:28:53 +1200 Subject: [PATCH 2/4] Fix windows crash: prefer fopen instead of fdopen (refs #229) --- imagick/magick_wand_image.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/imagick/magick_wand_image.go b/imagick/magick_wand_image.go index d857443..de11abe 100644 --- a/imagick/magick_wand_image.go +++ b/imagick/magick_wand_image.go @@ -2899,11 +2899,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 } From 0491c7e3ecfbd7aea45897f81075ed187215b9b5 Mon Sep 17 00:00:00 2001 From: Justin Israel Date: Sun, 16 Jul 2023 17:35:58 +1200 Subject: [PATCH 3/4] Add windows CI pipeline --- .github/workflows/ci.yml | 74 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 29 ---------------- imagick/memory.go | 3 ++ 3 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e4b21df --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,74 @@ +name: Test + +on: + push: + tags: + - "*" + branches-ignore: + - 'exp_*' + pull_request: + branches-ignore: + - 'exp_*' + +jobs: + test: + name: Test ImageMagick7 + runs-on: ubuntu-latest + environment: imagemagick7 + env: + DOCKER_IMAGE: gographics/imagick.v3:im-${{ vars.IMAGEMAGICK7_VERSION }} + # We want to run on external PRs, but not on our own internal PRs as they'll be run + # by the push to the branch. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Test + run: | + docker run --rm \ + -v $PWD:/go/projects/imagick \ + -v $PWD/.cache/go-build:/root/.cache/go-build \ + -v $PWD/.cache/go/pkg:/go/pkg \ + "$DOCKER_IMAGE" + + test_windows: + name: Test go-${{ matrix.go }} on ${{ matrix.os }} + strategy: + matrix: + go: [1.20.6] + os: [windows-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Setup go + uses: actions/setup-go@v4.0.1 + with: + go-version: ${{ matrix.go }} + + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + install: >- + base-devel + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-pkg-config + mingw-w64-x86_64-imagemagick + + - name: Install deps + shell: msys2 {0} + run: | + /c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go.exe env + pkg-config --cflags --libs MagickWand + MAGICK_CONFIGURE_PATH=/d/a/_temp/msys/msys64/mingw64/etc/ImageMagick-7 convert -list configure + + - name: Test + shell: msys2 {0} + run: > + MAGICK_CONFIGURE_PATH=/d/a/_temp/msys/msys64/mingw64/etc/ImageMagick-7 + /c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go.exe test -v ./imagick diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b9957fc..0000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -sudo: required - -language: generic - -services: - - docker - -env: - global: - - DOCKER_IMAGE=gographics/imagick.v3:im-$IMAGEMAGICK7_VERSION - - CACHE_DIR=$HOME/.cache - - GOCACHE=$CACHE_DIR/go-build - - GOPATH=$CACHE_DIR/go - -cache: - directories: - - $GOCACHE - - $GOPATH/pkg - -before_script: - - docker pull "$DOCKER_IMAGE" - -script: - - > - docker run -it --rm \ - -v $PWD:/go/projects/imagick \ - -v ${GOCACHE}:/root/.cache/go-build \ - -v ${GOPATH}/pkg:/go/pkg \ - "$DOCKER_IMAGE" diff --git a/imagick/memory.go b/imagick/memory.go index fc9f014..e7fa52d 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)) From b953ce4ed3a989b12e9eb857883bcfda3559d1c7 Mon Sep 17 00:00:00 2001 From: Justin Israel Date: Sun, 16 Jul 2023 18:08:33 +1200 Subject: [PATCH 4/4] ci update to remove matrix --- .github/workflows/ci.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4b21df..82d1477 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ on: jobs: test: - name: Test ImageMagick7 + name: Test ImageMagick7 linux runs-on: ubuntu-latest environment: imagemagick7 env: @@ -33,12 +33,8 @@ jobs: "$DOCKER_IMAGE" test_windows: - name: Test go-${{ matrix.go }} on ${{ matrix.os }} - strategy: - matrix: - go: [1.20.6] - os: [windows-latest] - runs-on: ${{ matrix.os }} + name: Test ImageMagick7 windows + runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v1 @@ -48,7 +44,7 @@ jobs: - name: Setup go uses: actions/setup-go@v4.0.1 with: - go-version: ${{ matrix.go }} + go-version: 1.20.6 - name: Setup MSYS2 uses: msys2/setup-msys2@v2 @@ -63,7 +59,7 @@ jobs: - name: Install deps shell: msys2 {0} run: | - /c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go.exe env + /c/hostedtoolcache/windows/go/1.20.6/x64/bin/go.exe env pkg-config --cflags --libs MagickWand MAGICK_CONFIGURE_PATH=/d/a/_temp/msys/msys64/mingw64/etc/ImageMagick-7 convert -list configure @@ -71,4 +67,4 @@ jobs: shell: msys2 {0} run: > MAGICK_CONFIGURE_PATH=/d/a/_temp/msys/msys64/mingw64/etc/ImageMagick-7 - /c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go.exe test -v ./imagick + /c/hostedtoolcache/windows/go/1.20.6/x64/bin/go.exe test -v ./imagick