Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: Experiencing silent crash when attempting to convert a JPEG to a GIF #4125

Open
5 tasks done
travispaul opened this issue Jun 5, 2024 · 15 comments
Open
5 tasks done

Comments

@travispaul
Copy link

Possible bug

Is this a possible bug in a feature of sharp, unrelated to installation?

  • Running npm install sharp completes without error.
  • Running node -e "require('sharp')" completes without error.

If you cannot confirm both of these, please open an installation issue instead.

Are you using the latest version of sharp?

  • I am using the latest version of sharp as reported by npm view sharp dist-tags.latest.

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of sharp that is not the latest, please open an issue against that package instead.

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

  System:
    OS: Windows 11 10.0.22631
    CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13900
    Memory: 38.11 GB / 63.70 GB
  Binaries:
    Node: 18.20.2 - X:\bin\nodejs\node.EXE
    npm: 10.5.0 - X:\bin\nodejs\npm.CMD
  npmPackages:
    sharp: ^0.33.4 => 0.33.4

Does this problem relate to file caching?

The default behaviour of libvips is to cache input files, which can lead to EBUSY or EPERM errors on Windows.
Use sharp.cache(false) to switch this feature off.

  • Adding sharp.cache(false) does not fix this problem.

Does this problem relate to images appearing to have been rotated by 90 degrees?

Images that contain EXIF Orientation metadata are not auto-oriented. By default, EXIF metadata is removed.

  • To auto-orient pixel values use the parameter-less rotate() operation.

  • To retain EXIF Orientation use keepExif().

  • Using rotate() or keepExif() does not fix this problem.

What are the steps to reproduce?

Using the reproducer, attempt to convert the attached JPEG image, into a GIF.

What is the expected behaviour?

The JPEG input image is converted into a GIF image or an error is returned in the catch() handler.

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

Running the following script as: node ./index.js 1.jpg
Where 1.jpg is the attached image will cause node to crash and return with an exit code of 5
The file converted.gif will be created but contains 0 bytes.
Neither the then() or catch() handlers are invoked.

const sharp = require('sharp')
const filename = process.argv[2]
console.log(`Loading file: '${filename}'`)
sharp(filename)
  .toFormat('gif')
  .toFile(`converted.gif`)
  .then(info => {
    console.log('got info:', info)
  })
  .catch(error => {
    console.error('got error:', error)
  })

Please provide sample image(s) that help explain this problem

1

@lovell
Copy link
Owner

lovell commented Jun 5, 2024

I'm unable to reproduce this locally.

an exit code of 5

On Windows this exit code often indicates some kind of file permission problem e.g. input file owned by admin user but process run as non-admin.

@travispaul
Copy link
Author

Interesting, I wasn't having the same issue with PNG or TIFF formats, but is consistent with GIF. I'll try another PC and see what happens, thanks for the quick response.

@travispaul
Copy link
Author

travispaul commented Jun 5, 2024

I see the same behavior on a Windows 10 machine:

  System:
    OS: Windows 10 10.0.19045
    CPU: (8) x64 Intel(R) Core(TM) i7-7700T CPU @ 2.90GHz
    Memory: 25.32 GB / 31.89 GB
  Binaries:
    Node: 18.20.2 - C:\Program Files\nodejs\node.EXE
    npm: 10.5.0 - C:\Program Files\nodejs\npm.CMD
  npmPackages:
    sharp: ^0.33.4 => 0.33.4

I tried running the reproducer in an Administrator Command prompt to see if the behavior was any different but saw the same results. The files are all created by and owned by the same user. Any tips for debugging further?

@travispaul
Copy link
Author

travispaul commented Jun 5, 2024

Worth noting, just tried with a newer node (v20.14.0) and receive a Segmentation Fault message printed to stderr (I see no message with v18) and an exit code of 139

@lovell
Copy link
Owner

lovell commented Jun 6, 2024

Thanks for the extra info, I'll try on another machine later.

Are you able to get a backtrace of the crash? The PDB symbol files for libvips v8.15.2 and its dependencies (as provided by sharp v0.33.4) are available at https://s3.eu-west-1.amazonaws.com/libvips-packaging/pdb/8.15.2/vips-pdb-w64-web-8.15.2-static.zip

I wasn't having the same issue with PNG

My current thinking is that this relates to palette generation/mapping, as used for GIF output. Are you able to create a palette-based PNG via .png({ palette: true })?

@travispaul
Copy link
Author

travispaul commented Jun 10, 2024

@lovell I am able to invoke .png({ palette: true }) on the image without error, and PNG is created. I've included a stacktrace below using Node.js v20.14.0. Let me know if you'd like me to gather any additional info.

0:013> g
(6740.31b8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for \\?\X:\src\misc\sharptest\node_modules\@img\sharp-win32-x64\lib\libvips-42.dll
ucrtbase!memcpy+0x2bb:
00007ffc`feb214bb c4a17e7f8c0960ffffff vmovdqu ymmword ptr [rcx+r9-0A0h],ymm1 ds:0000025f`e6fb8fe1=00

0:013> k
 # Child-SP          RetAddr               Call Site
00 000000a3`493fdd78 00007ffc`47234466     ucrtbase!memcpy+0x2bb
01 (Inline Function) --------`--------     libvips_42!create_byte_list_block+0xac [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif_raw.c @ 287] 
02 000000a3`493fdd80 00007ffc`472338e5     libvips_42!LZW_GenerateStream+0x5d6 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif_raw.c @ 331] 
03 000000a3`493fde60 00007ffc`46fadd07     libvips_42!cgif_raw_addframe+0x155 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif_raw.c @ 564] 
04 000000a3`493fdf60 00007ffc`46fadd53     libvips_42!flushFrame+0xf07 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif.c @ 340] 
05 000000a3`493fe090 00007ffc`46db6d69     libvips_42!cgif_close+0x23 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif.c @ 462] 
06 000000a3`493fe0d0 00007ffc`46db7920     libvips_42!vips_foreign_save_cgif_build+0x3a9 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c @ 873] 
07 000000a3`493fe530 00007ffc`46ef7d3b     libvips_42!vips_foreign_save_cgif_file_build+0x30 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c @ 1059] 
08 000000a3`493fe560 00007ffc`46f0369b     libvips_42!vips_object_build+0x1b [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c @ 372] 
09 000000a3`493fe5d0 00007ffc`5a048a70     libvips_42!vips_cache_operation_buildp+0x13b [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/cache.c @ 834] 
0a 000000a3`493fe620 00007ffc`5a052ea0     libvips_cpp!vips::VImage::call_option_string+0x80
0b 000000a3`493fe690 00007ffc`5bda063e     libvips_cpp!vips::VImage::gifsave+0xf0
0c 000000a3`493fe6d0 00007ffc`5bd8f1be     sharp_win32_x64+0x2063e
0d 000000a3`493ff610 00007ff6`3bf1d058     sharp_win32_x64+0xf1be
0e 000000a3`493ff680 00007ff6`3c1f098e     node!v8::base::RandomNumberGenerator::max+0x97d8
0f 000000a3`493ff730 00007ff6`3c1da99d     node!uv_queue_work+0x28e
10 000000a3`493ff780 00007ff6`3d39ff10     node!uv_poll_stop+0xed
11 000000a3`493ff7d0 00007ffd`000b257d     node!inflateValidate+0x25220
12 000000a3`493ff800 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
13 000000a3`493ff830 00000000`00000000     ntdll!RtlUserThreadStart+0x28

Here's a more detailed version as well:

0:013> ~*k
   0  Id: 6740.5c0c Suspend: 1 Teb: 000000a3`42345000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`42bfe118 00007ffc`fe4ed554     ntdll!NtRemoveIoCompletionEx+0x14
01 000000a3`42bfe120 00007ff6`3c1eb3e8     KERNELBASE!GetQueuedCompletionStatusEx+0xc4
02 000000a3`42bfe1c0 00007ff6`3c1ec090     node!uv_loop_alive+0x358
03 000000a3`42bff250 00007ff6`3c1bd1c5     node!uv_run+0x150
04 000000a3`42bff290 00007ff6`3c0a48e2     node!node::SpinEventLoop+0x195
05 000000a3`42bff340 00007ff6`3c13d40d     node!ENGINE_get_load_privkey_function+0x25bc2
06 000000a3`42bff490 00007ff6`3c13c110     node!node::Start+0x132d
07 000000a3`42bff5c0 00007ff6`3befd80c     node!node::Start+0x30
08 000000a3`42bff600 00007ff6`3d37f08c     node!AES_cbc_encrypt+0x24e3c
09 000000a3`42bff7c0 00007ffd`000b257d     node!inflateValidate+0x439c
0a 000000a3`42bff800 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
0b 000000a3`42bff830 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   1  Id: 6740.1964 Suspend: 1 Teb: 000000a3`42347000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`433ff708 00007ffd`0104537e     ntdll!NtWaitForWorkViaWorkerFactory+0x14
01 000000a3`433ff710 00007ffd`000b257d     ntdll!TppWorkerThread+0x2ee
02 000000a3`433ff9f0 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
03 000000a3`433ffa20 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   2  Id: 6740.67d0 Suspend: 1 Teb: 000000a3`42349000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`43bff5a8 00007ffd`0104537e     ntdll!NtWaitForWorkViaWorkerFactory+0x14
01 000000a3`43bff5b0 00007ffd`000b257d     ntdll!TppWorkerThread+0x2ee
02 000000a3`43bff890 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
03 000000a3`43bff8c0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   3  Id: 6740.5d38 Suspend: 1 Teb: 000000a3`4234b000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`443ffa98 00007ffd`0104537e     ntdll!NtWaitForWorkViaWorkerFactory+0x14
01 000000a3`443ffaa0 00007ffd`000b257d     ntdll!TppWorkerThread+0x2ee
02 000000a3`443ffd80 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
03 000000a3`443ffdb0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   4  Id: 6740.6250 Suspend: 1 Teb: 000000a3`4234d000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`44bff468 00007ffd`00d72a46     win32u!NtUserGetMessage+0x14
01 000000a3`44bff470 00007ff6`3c1cf45e     USER32!GetMessageA+0x46
02 000000a3`44bff4d0 00007ffd`0105ca11     node!uv_udp_set_ttl+0x108e
03 000000a3`44bff550 00007ffd`01045986     ntdll!RtlpTpWorkCallback+0x171
04 000000a3`44bff630 00007ffd`000b257d     ntdll!TppWorkerThread+0x8f6
05 000000a3`44bff910 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
06 000000a3`44bff940 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   5  Id: 6740.64bc Suspend: 1 Teb: 000000a3`4234f000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`453ff2f8 00007ffc`fe44952e     ntdll!NtWaitForSingleObject+0x14
01 000000a3`453ff300 00007ff6`3c1cf4dd     KERNELBASE!WaitForSingleObjectEx+0x8e
02 000000a3`453ff3a0 00007ffd`0105ca11     node!uv_udp_set_ttl+0x110d
03 000000a3`453ff3f0 00007ffd`01045986     ntdll!RtlpTpWorkCallback+0x171
04 000000a3`453ff4d0 00007ffd`000b257d     ntdll!TppWorkerThread+0x8f6
05 000000a3`453ff7b0 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
06 000000a3`453ff7e0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   6  Id: 6740.64e4 Suspend: 1 Teb: 000000a3`42351000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`45bff998 00007ffd`0104537e     ntdll!NtWaitForWorkViaWorkerFactory+0x14
01 000000a3`45bff9a0 00007ffd`000b257d     ntdll!TppWorkerThread+0x2ee
02 000000a3`45bffc80 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
03 000000a3`45bffcb0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   7  Id: 6740.2590 Suspend: 1 Teb: 000000a3`42353000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`463fec18 00007ffc`fe4ed554     ntdll!NtRemoveIoCompletionEx+0x14
01 000000a3`463fec20 00007ff6`3c1eb3e8     KERNELBASE!GetQueuedCompletionStatusEx+0xc4
02 000000a3`463fecc0 00007ff6`3c1ec090     node!uv_loop_alive+0x358
03 000000a3`463ffd50 00007ff6`3c07facd     node!uv_run+0x150
04 000000a3`463ffd90 00007ff6`3c1da99d     node!ENGINE_get_load_privkey_function+0xdad
05 000000a3`463ffe10 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`463ffe60 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`463ffe90 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`463ffec0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   8  Id: 6740.6648 Suspend: 1 Teb: 000000a3`42355000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`46bff8e8 00007ffd`01078d24     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`46bff8f0 00007ffc`fe47e9e9     ntdll!RtlSleepConditionVariableCS+0x104
02 000000a3`46bff970 00007ff6`3c1daa70     KERNELBASE!SleepConditionVariableCS+0x29
03 000000a3`46bff9a0 00007ff6`3c07efac     node!uv_cond_wait+0x10
04 000000a3`46bff9d0 00007ff6`3c1da99d     node!ENGINE_get_load_privkey_function+0x28c
05 000000a3`46bffa60 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`46bffab0 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`46bffae0 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`46bffb10 00000000`00000000     ntdll!RtlUserThreadStart+0x28

   9  Id: 6740.4f58 Suspend: 1 Teb: 000000a3`42357000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`473ffa88 00007ffd`01078d24     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`473ffa90 00007ffc`fe47e9e9     ntdll!RtlSleepConditionVariableCS+0x104
02 000000a3`473ffb10 00007ff6`3c1daa70     KERNELBASE!SleepConditionVariableCS+0x29
03 000000a3`473ffb40 00007ff6`3c07efac     node!uv_cond_wait+0x10
04 000000a3`473ffb70 00007ff6`3c1da99d     node!ENGINE_get_load_privkey_function+0x28c
05 000000a3`473ffc00 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`473ffc50 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`473ffc80 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`473ffcb0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  10  Id: 6740.1d64 Suspend: 1 Teb: 000000a3`42359000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`47bffa68 00007ffd`01078d24     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`47bffa70 00007ffc`fe47e9e9     ntdll!RtlSleepConditionVariableCS+0x104
02 000000a3`47bffaf0 00007ff6`3c1daa70     KERNELBASE!SleepConditionVariableCS+0x29
03 000000a3`47bffb20 00007ff6`3c07efac     node!uv_cond_wait+0x10
04 000000a3`47bffb50 00007ff6`3c1da99d     node!ENGINE_get_load_privkey_function+0x28c
05 000000a3`47bffbe0 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`47bffc30 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`47bffc60 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`47bffc90 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  11  Id: 6740.2054 Suspend: 1 Teb: 000000a3`4235b000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`483ff9e8 00007ffd`01078d24     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`483ff9f0 00007ffc`fe47e9e9     ntdll!RtlSleepConditionVariableCS+0x104
02 000000a3`483ffa70 00007ff6`3c1daa70     KERNELBASE!SleepConditionVariableCS+0x29
03 000000a3`483ffaa0 00007ff6`3c07efac     node!uv_cond_wait+0x10
04 000000a3`483ffad0 00007ff6`3c1da99d     node!ENGINE_get_load_privkey_function+0x28c
05 000000a3`483ffb60 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`483ffbb0 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`483ffbe0 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`483ffc10 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  12  Id: 6740.65cc Suspend: 1 Teb: 000000a3`4235d000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`48bffa78 00007ffd`0104537e     ntdll!NtWaitForWorkViaWorkerFactory+0x14
01 000000a3`48bffa80 00007ffd`000b257d     ntdll!TppWorkerThread+0x2ee
02 000000a3`48bffd60 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
03 000000a3`48bffd90 00000000`00000000     ntdll!RtlUserThreadStart+0x28

# 13  Id: 6740.31b8 Suspend: 1 Teb: 000000a3`42361000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`493fdd78 00007ffc`47234466     ucrtbase!memcpy+0x2bb
01 (Inline Function) --------`--------     libvips_42!create_byte_list_block+0xac [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif_raw.c @ 287] 
02 000000a3`493fdd80 00007ffc`472338e5     libvips_42!LZW_GenerateStream+0x5d6 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif_raw.c @ 331] 
03 000000a3`493fde60 00007ffc`46fadd07     libvips_42!cgif_raw_addframe+0x155 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif_raw.c @ 564] 
04 000000a3`493fdf60 00007ffc`46fadd53     libvips_42!flushFrame+0xf07 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif.c @ 340] 
05 000000a3`493fe090 00007ffc`46db6d69     libvips_42!cgif_close+0x23 [/var/tmp/tmp-cgif-x86_64-w64-mingw32.static.posix.web/cgif-0.3.2.build_/../cgif-0.3.2/src/cgif.c @ 462] 
06 000000a3`493fe0d0 00007ffc`46db7920     libvips_42!vips_foreign_save_cgif_build+0x3a9 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c @ 873] 
07 000000a3`493fe530 00007ffc`46ef7d3b     libvips_42!vips_foreign_save_cgif_file_build+0x30 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c @ 1059] 
08 000000a3`493fe560 00007ffc`46f0369b     libvips_42!vips_object_build+0x1b [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c @ 372] 
09 000000a3`493fe5d0 00007ffc`5a048a70     libvips_42!vips_cache_operation_buildp+0x13b [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/cache.c @ 834] 
0a 000000a3`493fe620 00007ffc`5a052ea0     libvips_cpp!vips::VImage::call_option_string+0x80
0b 000000a3`493fe690 00007ffc`5bda063e     libvips_cpp!vips::VImage::gifsave+0xf0
0c 000000a3`493fe6d0 00007ffc`5bd8f1be     sharp_win32_x64+0x2063e
0d 000000a3`493ff610 00007ff6`3bf1d058     sharp_win32_x64+0xf1be
0e 000000a3`493ff680 00007ff6`3c1f098e     node!v8::base::RandomNumberGenerator::max+0x97d8
0f 000000a3`493ff730 00007ff6`3c1da99d     node!uv_queue_work+0x28e
10 000000a3`493ff780 00007ff6`3d39ff10     node!uv_poll_stop+0xed
11 000000a3`493ff7d0 00007ffd`000b257d     node!inflateValidate+0x25220
12 000000a3`493ff800 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
13 000000a3`493ff830 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  14  Id: 6740.180c Suspend: 1 Teb: 000000a3`42363000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`49bff808 00007ffd`01078d24     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`49bff810 00007ffc`fe47e9e9     ntdll!RtlSleepConditionVariableCS+0x104
02 000000a3`49bff890 00007ff6`3c1daa70     KERNELBASE!SleepConditionVariableCS+0x29
03 000000a3`49bff8c0 00007ff6`3c1f0894     node!uv_cond_wait+0x10
04 000000a3`49bff8f0 00007ff6`3c1da99d     node!uv_queue_work+0x194
05 000000a3`49bff940 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`49bff990 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`49bff9c0 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`49bff9f0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  15  Id: 6740.17c8 Suspend: 1 Teb: 000000a3`42365000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`4a3ffb58 00007ffd`01078d24     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`4a3ffb60 00007ffc`fe47e9e9     ntdll!RtlSleepConditionVariableCS+0x104
02 000000a3`4a3ffbe0 00007ff6`3c1daa70     KERNELBASE!SleepConditionVariableCS+0x29
03 000000a3`4a3ffc10 00007ff6`3c1f0894     node!uv_cond_wait+0x10
04 000000a3`4a3ffc40 00007ff6`3c1da99d     node!uv_queue_work+0x194
05 000000a3`4a3ffc90 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`4a3ffce0 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`4a3ffd10 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`4a3ffd40 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  16  Id: 6740.60b4 Suspend: 1 Teb: 000000a3`42367000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 000000a3`4abff9c8 00007ffd`01078d24     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`4abff9d0 00007ffc`fe47e9e9     ntdll!RtlSleepConditionVariableCS+0x104
02 000000a3`4abffa50 00007ff6`3c1daa70     KERNELBASE!SleepConditionVariableCS+0x29
03 000000a3`4abffa80 00007ff6`3c1f0894     node!uv_cond_wait+0x10
04 000000a3`4abffab0 00007ff6`3c1da99d     node!uv_queue_work+0x194
05 000000a3`4abffb00 00007ff6`3d39ff10     node!uv_poll_stop+0xed
06 000000a3`4abffb50 00007ffd`000b257d     node!inflateValidate+0x25220
07 000000a3`4abffb80 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
08 000000a3`4abffbb0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  17  Id: 6740.68d8 Suspend: 1 Teb: 000000a3`42369000 Unfrozen "libvips worker"
 # Child-SP          RetAddr               Call Site
00 000000a3`4b3ff688 00007ffd`010791db     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`4b3ff690 00007ffc`fe47eaa9     ntdll!RtlSleepConditionVariableSRW+0x13b
02 000000a3`4b3ff710 00007ffc`46f77fa2     KERNELBASE!SleepConditionVariableSRW+0x29
03 000000a3`4b3ff750 00007ffc`46f18160     libvips_42!g_cond_wait_until+0x7e [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread-win32.c @ 282] 
04 (Inline Function) --------`--------     libvips_42!vips__semaphore_downn_until+0x77 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/semaphore.c @ 127] 
05 000000a3`4b3ff7c0 00007ffc`46eee745     libvips_42!vips_semaphore_down_timeout+0x90 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/semaphore.c @ 180] 
06 000000a3`4b3ff810 00007ffc`46eee18f     libvips_42!vips_threadset_work+0x85 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/threadset.c @ 117] 
07 000000a3`4b3ff870 00007ffc`46f6d3d5     libvips_42!vips_thread_run+0x1f [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/thread.c @ 148] 
08 000000a3`4b3ff8b0 00007ffc`46f78323     libvips_42!g_thread_proxy+0x3c [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread.c @ 835] 
09 000000a3`4b3ff8e0 00007ffc`feaf9333     libvips_42!g_thread_win32_proxy+0x7 [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread-win32.c @ 437] 
0a 000000a3`4b3ff910 00007ffd`000b257d     ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x93
0b 000000a3`4b3ff940 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
0c 000000a3`4b3ff970 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  18  Id: 6740.521c Suspend: 1 Teb: 000000a3`4236b000 Unfrozen "libvips worker"
 # Child-SP          RetAddr               Call Site
00 000000a3`4bbff968 00007ffd`010791db     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`4bbff970 00007ffc`fe47eaa9     ntdll!RtlSleepConditionVariableSRW+0x13b
02 000000a3`4bbff9f0 00007ffc`46f77fa2     KERNELBASE!SleepConditionVariableSRW+0x29
03 000000a3`4bbffa30 00007ffc`46f18160     libvips_42!g_cond_wait_until+0x7e [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread-win32.c @ 282] 
04 (Inline Function) --------`--------     libvips_42!vips__semaphore_downn_until+0x77 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/semaphore.c @ 127] 
05 000000a3`4bbffaa0 00007ffc`46eee745     libvips_42!vips_semaphore_down_timeout+0x90 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/semaphore.c @ 180] 
06 000000a3`4bbffaf0 00007ffc`46eee18f     libvips_42!vips_threadset_work+0x85 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/threadset.c @ 117] 
07 000000a3`4bbffb50 00007ffc`46f6d3d5     libvips_42!vips_thread_run+0x1f [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/thread.c @ 148] 
08 000000a3`4bbffb90 00007ffc`46f78323     libvips_42!g_thread_proxy+0x3c [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread.c @ 835] 
09 000000a3`4bbffbc0 00007ffc`feaf9333     libvips_42!g_thread_win32_proxy+0x7 [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread-win32.c @ 437] 
0a 000000a3`4bbffbf0 00007ffd`000b257d     ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x93
0b 000000a3`4bbffc20 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
0c 000000a3`4bbffc50 00000000`00000000     ntdll!RtlUserThreadStart+0x28

  19  Id: 6740.198 Suspend: 1 Teb: 000000a3`4236d000 Unfrozen "libvips worker"
 # Child-SP          RetAddr               Call Site
00 000000a3`4c3ff4b8 00007ffd`010791db     ntdll!NtWaitForAlertByThreadId+0x14
01 000000a3`4c3ff4c0 00007ffc`fe47eaa9     ntdll!RtlSleepConditionVariableSRW+0x13b
02 000000a3`4c3ff540 00007ffc`46f77fa2     KERNELBASE!SleepConditionVariableSRW+0x29
03 000000a3`4c3ff580 00007ffc`46f18160     libvips_42!g_cond_wait_until+0x7e [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread-win32.c @ 282] 
04 (Inline Function) --------`--------     libvips_42!vips__semaphore_downn_until+0x77 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/semaphore.c @ 127] 
05 000000a3`4c3ff5f0 00007ffc`46eee745     libvips_42!vips_semaphore_down_timeout+0x90 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/semaphore.c @ 180] 
06 000000a3`4c3ff640 00007ffc`46eee18f     libvips_42!vips_threadset_work+0x85 [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/threadset.c @ 117] 
07 000000a3`4c3ff6a0 00007ffc`46f6d3d5     libvips_42!vips_thread_run+0x1f [/var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.posix.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/thread.c @ 148] 
08 000000a3`4c3ff6e0 00007ffc`46f78323     libvips_42!g_thread_proxy+0x3c [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread.c @ 835] 
09 000000a3`4c3ff710 00007ffc`feaf9333     libvips_42!g_thread_win32_proxy+0x7 [/var/tmp/tmp-glib-x86_64-w64-mingw32.static.posix.web/glib-2.80.0.build_/../glib-2.80.0/glib/gthread-win32.c @ 437] 
0a 000000a3`4c3ff740 00007ffd`000b257d     ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x93
0b 000000a3`4c3ff770 00007ffd`0106aa48     KERNEL32!BaseThreadInitThunk+0x1d
0c 000000a3`4c3ff7a0 00000000`00000000     ntdll!RtlUserThreadStart+0x28

@lovell
Copy link
Owner

lovell commented Jun 10, 2024

Thank you, this is very helpful, and suggests the crash might be from within the LZW compression logic of the cgif dependency.

The segfault appears to occur in one of the two calls to memcpy here:

https://github.com/dloebl/cgif/blob/43976ce4ace9ad60ba3cf7cf5aaabc2d480170f9/src/cgif_raw.c#L287-L291

I assume this code is attempting to write beyond the end of byteListBlock, which is allocated here:

https://github.com/dloebl/cgif/blob/43976ce4ace9ad60ba3cf7cf5aaabc2d480170f9/src/cgif_raw.c#L327

I'll keep investigating.

@kleisauke
Copy link
Contributor

I was able to reproduce this issue on Windows using:

$ vips copy 337010030-e9a3fdbf-b30f-4b60-8e73-9f98a5446695.jpg x.gif
$ echo %errorlevel%
-1073741819

However, I was unable to reproduce the issue on Linux, even when running with ASan/UBSan sanitizers:

$ python infra/helper.py reproduce libvips gifsave_buffer_fuzzer ~/Downloads/337010030-e9a3fdbf-b30f-4b60-8e73-9f98a5446695.jpg

(with this check removed)

I thought this might be a security feature of UCRT (Universal C Runtime in Windows), but linking against the debug version of the UCRT did not provide any additional information.

I'll try to build the binaries with ASan/UBSan on Windows, hopefully that will provide extra information.

@kleisauke
Copy link
Contributor

AddressSanitizer reports it as heap-buffer-overflow:

Details
$ set ASAN_SYMBOLIZER_PATH=C:\llvm-mingw-20240606-ucrt-x86_64\bin\llvm-symbolizer.exe
$ vips copy 337010030-e9a3fdbf-b30f-4b60-8e73-9f98a5446695.jpg x.gif
=================================================================
==121936==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x012989bf6c41 at pc 0x7ff80e71811c bp 0x000c54ef90b0 sp 0x000c54ef90f8
WRITE of size 255 at 0x012989bf6c41 thread T0
    #0 0x7ff80e71811b in __asan_memcpy /var/tmp/tmp-compiler-rt-sanitizers-x86_64-w64-mingw32.static.debug.web/llvm-project-18.1.7.src/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3
    #1 0x7fffbb5ea305 in create_byte_list_block /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif_raw.c:287:5
    #2 0x7fffbb5ea305 in LZW_GenerateStream /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif_raw.c:331:19
    #3 0x7fffbb5e85a0 in cgif_raw_addframe /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif_raw.c:559:9
    #4 0x7fffbb11f6c0 in flushFrame /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif.c:340:7
    #5 0x7fffbb11fcd5 in cgif_close /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif.c:488:11
    #6 0x7fffbab10b79 in vips_foreign_save_cgif_build /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c:873:2
    #7 0x7fffbab136aa in vips_foreign_save_cgif_target_build /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c:1007:6
    #8 0x7fffbaee2df1 in vips_object_build /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c:372:6
    #9 0x7fffbaf00ab2 in vips_cache_operation_buildp /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/cache.c:834:7
    #10 0x7fffbaf1188e in vips_call_required_optional /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:977:6
    #11 0x7fffbaf13067 in vips_call_by_name /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1017:11
    #12 0x7fffbaf1331a in vips_call_split_option_string /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1138:11
    #13 0x7fffbaef3c8d in vips_image_write_to_file /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/image.c:2704:12
    #14 0x7fffbaee8389 in vips_object_get_argument_to_string /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c:2243:8
    #15 0x7fffbaf13ded in vips_call_argv_output /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1420:8
    #16 0x7fffbaee3217 in vips_argument_map /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c:612:17
    #17 0x7fffbaf1391d in vips_call_argv /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1487:6
    #18 0x7ff7ff901a68 in main /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/tools/vips.c:884:7
    #19 0x7ff7ff901310 in __tmainCRTStartup /var/tmp/tmp-llvm-mingw-x86_64-w64-mingw32.static.debug.web/mstorsjo-llvm-mingw-ab7e195.build_/mingw-w64-mingw-w64-f97814b/mingw-w64-crt/crt/crtexe.c:267:15
    #20 0x7ff7ff901365 in .l_start /var/tmp/tmp-llvm-mingw-x86_64-w64-mingw32.static.debug.web/mstorsjo-llvm-mingw-ab7e195.build_/mingw-w64-mingw-w64-f97814b/mingw-w64-crt/crt/crtexe.c:188:9
    #21 0x7ff88389257c  (C:\WINDOWS\System32\KERNEL32.DLL+0x18001257c)
    #22 0x7ff884dcaf27  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18005af27)

0x012989bf6c41 is located 0 bytes after 676929-byte region [0x012989b51800,0x012989bf6c41)
allocated by thread T0 here:
    #0 0x7ff80e719641 in malloc /var/tmp/tmp-compiler-rt-sanitizers-x86_64-w64-mingw32.static.debug.web/llvm-project-18.1.7.src/compiler-rt/lib/asan/asan_malloc_win.cpp:98:3
    #1 0x7fffbb5e9ef1 in LZW_GenerateStream /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif_raw.c:329:19
    #2 0x7fffbb5e85a0 in cgif_raw_addframe /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif_raw.c:559:9
    #3 0x7fffbb11f6c0 in flushFrame /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif.c:340:7
    #4 0x7fffbb11fcd5 in cgif_close /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif.c:488:11
    #5 0x7fffbab10b79 in vips_foreign_save_cgif_build /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c:873:2
    #6 0x7fffbab136aa in vips_foreign_save_cgif_target_build /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/foreign/cgifsave.c:1007:6
    #7 0x7fffbaee2df1 in vips_object_build /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c:372:6
    #8 0x7fffbaf00ab2 in vips_cache_operation_buildp /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/cache.c:834:7
    #9 0x7fffbaf1188e in vips_call_required_optional /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:977:6
    #10 0x7fffbaf13067 in vips_call_by_name /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1017:11
    #11 0x7fffbaf1331a in vips_call_split_option_string /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1138:11
    #12 0x7fffbaef3c8d in vips_image_write_to_file /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/image.c:2704:12
    #13 0x7fffbaee8389 in vips_object_get_argument_to_string /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c:2243:8
    #14 0x7fffbaf13ded in vips_call_argv_output /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1420:8
    #15 0x7fffbaee3217 in vips_argument_map /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/object.c:612:17
    #16 0x7fffbaf1391d in vips_call_argv /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/libvips/iofuncs/operation.c:1487:6
    #17 0x7ff7ff901a68 in main /var/tmp/tmp-vips-web-x86_64-w64-mingw32.static.debug.web/vips-8.15.2.build_/../vips-8.15.2/tools/vips.c:884:7
    #18 0x7ff7ff901310 in __tmainCRTStartup /var/tmp/tmp-llvm-mingw-x86_64-w64-mingw32.static.debug.web/mstorsjo-llvm-mingw-ab7e195.build_/mingw-w64-mingw-w64-f97814b/mingw-w64-crt/crt/crtexe.c:267:15
    #19 0x7ff7ff901365 in .l_start /var/tmp/tmp-llvm-mingw-x86_64-w64-mingw32.static.debug.web/mstorsjo-llvm-mingw-ab7e195.build_/mingw-w64-mingw-w64-f97814b/mingw-w64-crt/crt/crtexe.c:188:9
    #20 0x7ff88389257c  (C:\WINDOWS\System32\KERNEL32.DLL+0x18001257c)
    #21 0x7ff884dcaf27  (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18005af27)

SUMMARY: AddressSanitizer: heap-buffer-overflow /var/tmp/tmp-cgif-x86_64-w64-mingw32.static.debug.web/cgif-0.4.0.build_/../cgif-0.4.0/src/cgif_raw.c:287:5 in create_byte_list_block
Shadow bytes around the buggy address:
  0x012989bf6980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x012989bf6a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x012989bf6a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x012989bf6b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x012989bf6b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x012989bf6c00: 00 00 00 00 00 00 00 00[01]fa fa fa fa fa fa fa
  0x012989bf6c80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x012989bf6d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x012989bf6d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x012989bf6e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x012989bf6e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==121936==ABORTING

@lovell
Copy link
Owner

lovell commented Jun 15, 2024

@dloebl Daniel, you may be interested in this discussion.

@dloebl
Copy link

dloebl commented Jun 16, 2024

Thanks for letting me know, @lovell! It's strange that this issue only shows up on Windows. I'll take a look today

@kleisauke
Copy link
Contributor

I may have found the culprit. It appears that the MaxByteListLen and MaxByteListBlockLen calculations in cgif assume that unsigned long is always 64 bits. However, on Windows and 32-bit systems, unsigned long is 32 bits.

For example, consider the following test program:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

#define MAX_CODE_LEN 12
#define BLOCK_SIZE 0xFF

int main() {
  uint32_t lzwPos = 1847622;
  uint64_t MaxByteListLen = MAX_CODE_LEN*lzwPos/8ul +2ul +1ul;
  uint64_t MaxByteListBlockLen = MAX_CODE_LEN*lzwPos*(BLOCK_SIZE+1ul)/8ul/BLOCK_SIZE +2ul +1ul +1ul;

  printf("MaxByteListLen: %" PRIu64 "\n", MaxByteListLen);
  printf("MaxByteListBlockLen: %" PRIu64 "\n", MaxByteListBlockLen);

  return 0;
}

When run on Fedora:

$ docker run --rm -v ${PWD}:/src -w /src -it fedora:40 sh -c "dnf install -y gcc && gcc test-cgif.c && ./a.out"
MaxByteListLen: 2771436
MaxByteListBlockLen: 2782305

And on Windows:

$ docker run --rm -v ${PWD}:/src -w /src -it mstorsjo/llvm-mingw:latest x86_64-w64-mingw32-clang test-cgif.c -o test.exe
$ ./test.exe
MaxByteListLen: 2771436
MaxByteListBlockLen: 676929

By changing the constants to unsigned long long:

@@ -7,8 +7,8 @@
 
 int main() {
   uint32_t lzwPos = 1847622;
-  uint64_t MaxByteListLen = MAX_CODE_LEN*lzwPos/8ul +2ul +1ul;
-  uint64_t MaxByteListBlockLen = MAX_CODE_LEN*lzwPos*(BLOCK_SIZE+1ul)/8ul/BLOCK_SIZE +2ul +1ul +1ul;
+  uint64_t MaxByteListLen = MAX_CODE_LEN*lzwPos/8ull +2ull +1ull;
+  uint64_t MaxByteListBlockLen = MAX_CODE_LEN*lzwPos*(BLOCK_SIZE+1ull)/8ull/BLOCK_SIZE +2ull +1ull +1ull;
 
   printf("MaxByteListLen: %" PRIu64 "\n", MaxByteListLen);
   printf("MaxByteListBlockLen: %" PRIu64 "\n", MaxByteListBlockLen);

The output for MaxByteListBlockLen becomes consistent on both platforms, both showing 2782305.

@kleisauke
Copy link
Contributor

PR dloebl/cgif#70 should fix this.

As an aside, this also affects the WebAssembly builds. For example, running the sample in this playground link results in a crash with the error message: RuntimeError: memory access out of bounds.

@dloebl
Copy link

dloebl commented Jun 18, 2024

I've just tagged a new release (v0.4.1) that should fix this issue: https://github.com/dloebl/cgif/releases/tag/v0.4.1

@lovell
Copy link
Owner

lovell commented Jun 19, 2024

Thank you @kleisauke for investigating this and thank you @dloebl for fixing cgif.

cgif v0.4.1 will hopefully be included in sharp as part of the next release, v0.33.5.

@lovell lovell added this to the v0.33.5 milestone Jun 19, 2024
@lovell lovell changed the title Experiencing silent crash when attempting to convert a JPEG to a GIF Windows: Experiencing silent crash when attempting to convert a JPEG to a GIF Jun 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants