[sfnt] Fix crash in `Load_SBit_Png` on Windows x64.
This change fixes a crash that occurs in `Load_SBit_Png` when running on a 64-bit Windows OS. A memory access violation exception would be raised by `setjmp` if the `jmp_buf` is not aligned to a 16-byte memory boundary. This is due to setjmp executing `movdqa` instructions to store 128-bit XMM registers to memory, which require correct memory alignment. This problem occurs because `png_create_read_struct` uses `malloc` and `free` for memory management, which only guarantees 8-byte alignment on Windows. Instead, to fix the problem, `png_create_read_struct_2` is used on 64-bit Windows, which allows for user-defined memory allocation and deallocation callbacks to be specified. These callbacks forward the allocation and deallocation requests to `_aligned_alloc` and `_aligned_free`, ensuring that the allocated `png_struct` and internal `jmp_buf` have the requisite 16-byte alignment. * src/sfnt/pngshim.c <_WIN64>: Include `malloc.h`. (malloc_callback, free_callback) <_WIN64>: New functions. (Load_SBit_Png) <_WIN64>: Use `png_create_read_struct_2` instead of `png_create_read_struct`
This commit is contained in:
parent
f7d7e7f9f7
commit
dbf9142f7e
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
||||||
|
2021-02-27 Jesse Towner <townerj@gmail.com>
|
||||||
|
|
||||||
|
[sfnt] Fix crash in `Load_SBit_Png` on Windows x64.
|
||||||
|
|
||||||
|
This change fixes a crash that occurs in `Load_SBit_Png` when
|
||||||
|
running on a 64-bit Windows OS. A memory access violation exception
|
||||||
|
would be raised by `setjmp` if the `jmp_buf` is not aligned to a
|
||||||
|
16-byte memory boundary. This is due to setjmp executing `movdqa`
|
||||||
|
instructions to store 128-bit XMM registers to memory, which require
|
||||||
|
correct memory alignment. This problem occurs because
|
||||||
|
`png_create_read_struct` uses `malloc` and `free` for memory
|
||||||
|
management, which only guarantees 8-byte alignment on Windows.
|
||||||
|
|
||||||
|
Instead, to fix the problem, `png_create_read_struct_2` is used on
|
||||||
|
64-bit Windows, which allows for user-defined memory allocation and
|
||||||
|
deallocation callbacks to be specified. These callbacks forward the
|
||||||
|
allocation and deallocation requests to `_aligned_alloc` and
|
||||||
|
`_aligned_free`, ensuring that the allocated `png_struct` and
|
||||||
|
internal `jmp_buf` have the requisite 16-byte alignment.
|
||||||
|
|
||||||
|
* src/sfnt/pngshim.c <_WIN64>: Include `malloc.h`.
|
||||||
|
(malloc_callback, free_callback) <_WIN64>: New functions.
|
||||||
|
(Load_SBit_Png) <_WIN64>: Use `png_create_read_struct_2` instead of
|
||||||
|
`png_create_read_struct`
|
||||||
|
|
||||||
2021-02-25 Werner Lemberg <wl@gnu.org>
|
2021-02-25 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[woff2] Fix memory leak.
|
[woff2] Fix memory leak.
|
||||||
|
|
|
@ -33,6 +33,16 @@
|
||||||
|
|
||||||
#include "sferrors.h"
|
#include "sferrors.h"
|
||||||
|
|
||||||
|
/* Use _aligned_malloc / _aligned_free on 64-bit Windows to ensure that */
|
||||||
|
/* the jmp_buf needed for ft_setjmp is aligned to a 16-byte boundary. */
|
||||||
|
/* If the jmp_buf is not aligned to a 16-byte boundary then a memory */
|
||||||
|
/* access violation exception will occur upon ft_setjmp being called. */
|
||||||
|
#ifdef _WIN64
|
||||||
|
#ifndef PNG_USER_MEM_SUPPORTED
|
||||||
|
#error "libpng user-defined memory allocation is required for 64-bit Windows"
|
||||||
|
#endif
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This code is freely based on cairo-png.c. There's so many ways */
|
/* This code is freely based on cairo-png.c. There's so many ways */
|
||||||
/* to call libpng, and the way cairo does it is defacto standard. */
|
/* to call libpng, and the way cairo does it is defacto standard. */
|
||||||
|
@ -221,6 +231,32 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
|
||||||
|
/* Memory allocation callback to ensure that the jmp_buf that is stored */
|
||||||
|
/* within the png_struct has 16-byte alignment for 64-bit Windows. */
|
||||||
|
static png_voidp
|
||||||
|
malloc_callback( png_structp png,
|
||||||
|
png_alloc_size_t size )
|
||||||
|
{
|
||||||
|
FT_UNUSED( png );
|
||||||
|
return _aligned_malloc( size, 16 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Memory deallocation callback to release memory that was allocated */
|
||||||
|
/* with the matching memory allocation callback above. */
|
||||||
|
static void
|
||||||
|
free_callback( png_structp png,
|
||||||
|
png_voidp ptr )
|
||||||
|
{
|
||||||
|
FT_UNUSED( png );
|
||||||
|
_aligned_free( ptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _WIN64 */
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_data_from_FT_Stream( png_structp png,
|
read_data_from_FT_Stream( png_structp png,
|
||||||
png_bytep data,
|
png_bytep data,
|
||||||
|
@ -292,10 +328,20 @@
|
||||||
|
|
||||||
FT_Stream_OpenMemory( &stream, data, png_len );
|
FT_Stream_OpenMemory( &stream, data, png_len );
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
png = png_create_read_struct_2( PNG_LIBPNG_VER_STRING,
|
||||||
|
&error,
|
||||||
|
error_callback,
|
||||||
|
warning_callback,
|
||||||
|
NULL,
|
||||||
|
malloc_callback,
|
||||||
|
free_callback );
|
||||||
|
#else
|
||||||
png = png_create_read_struct( PNG_LIBPNG_VER_STRING,
|
png = png_create_read_struct( PNG_LIBPNG_VER_STRING,
|
||||||
&error,
|
&error,
|
||||||
error_callback,
|
error_callback,
|
||||||
warning_callback );
|
warning_callback );
|
||||||
|
#endif
|
||||||
if ( !png )
|
if ( !png )
|
||||||
{
|
{
|
||||||
error = FT_THROW( Out_Of_Memory );
|
error = FT_THROW( Out_Of_Memory );
|
||||||
|
|
Loading…
Reference in New Issue