Werner Lemberg pushed to branch master at FreeType / FreeType
Commits:
-
dbf9142f
by Jesse Towner at 2021-02-27T13:28:13+01:00
2 changed files:
Changes:
1 |
+2021-02-27 Jesse Towner <townerj@gmail.com>
|
|
2 |
+ |
|
3 |
+ [sfnt] Fix crash in `Load_SBit_Png` on Windows x64.
|
|
4 |
+ |
|
5 |
+ This change fixes a crash that occurs in `Load_SBit_Png` when
|
|
6 |
+ running on a 64-bit Windows OS. A memory access violation exception
|
|
7 |
+ would be raised by `setjmp` if the `jmp_buf` is not aligned to a
|
|
8 |
+ 16-byte memory boundary. This is due to setjmp executing `movdqa`
|
|
9 |
+ instructions to store 128-bit XMM registers to memory, which require
|
|
10 |
+ correct memory alignment. This problem occurs because
|
|
11 |
+ `png_create_read_struct` uses `malloc` and `free` for memory
|
|
12 |
+ management, which only guarantees 8-byte alignment on Windows.
|
|
13 |
+ |
|
14 |
+ Instead, to fix the problem, `png_create_read_struct_2` is used on
|
|
15 |
+ 64-bit Windows, which allows for user-defined memory allocation and
|
|
16 |
+ deallocation callbacks to be specified. These callbacks forward the
|
|
17 |
+ allocation and deallocation requests to `_aligned_alloc` and
|
|
18 |
+ `_aligned_free`, ensuring that the allocated `png_struct` and
|
|
19 |
+ internal `jmp_buf` have the requisite 16-byte alignment.
|
|
20 |
+ |
|
21 |
+ * src/sfnt/pngshim.c <_WIN64>: Include `malloc.h`.
|
|
22 |
+ (malloc_callback, free_callback) <_WIN64>: New functions.
|
|
23 |
+ (Load_SBit_Png) <_WIN64>: Use `png_create_read_struct_2` instead of
|
|
24 |
+ `png_create_read_struct`
|
|
25 |
+ |
|
1 | 26 |
2021-02-25 Werner Lemberg <wl@gnu.org>
|
2 | 27 |
|
3 | 28 |
[woff2] Fix memory leak.
|
... | ... | @@ -33,6 +33,16 @@ |
33 | 33 |
|
34 | 34 |
#include "sferrors.h"
|
35 | 35 |
|
36 |
+ /* Use _aligned_malloc / _aligned_free on 64-bit Windows to ensure that */
|
|
37 |
+ /* the jmp_buf needed for ft_setjmp is aligned to a 16-byte boundary. */
|
|
38 |
+ /* If the jmp_buf is not aligned to a 16-byte boundary then a memory */
|
|
39 |
+ /* access violation exception will occur upon ft_setjmp being called. */
|
|
40 |
+#ifdef _WIN64
|
|
41 |
+#ifndef PNG_USER_MEM_SUPPORTED
|
|
42 |
+#error "libpng user-defined memory allocation is required for 64-bit Windows"
|
|
43 |
+#endif
|
|
44 |
+#include <malloc.h>
|
|
45 |
+#endif
|
|
36 | 46 |
|
37 | 47 |
/* This code is freely based on cairo-png.c. There's so many ways */
|
38 | 48 |
/* to call libpng, and the way cairo does it is defacto standard. */
|
... | ... | @@ -221,6 +231,32 @@ |
221 | 231 |
}
|
222 | 232 |
|
223 | 233 |
|
234 |
+#ifdef _WIN64
|
|
235 |
+ |
|
236 |
+ /* Memory allocation callback to ensure that the jmp_buf that is stored */
|
|
237 |
+ /* within the png_struct has 16-byte alignment for 64-bit Windows. */
|
|
238 |
+ static png_voidp
|
|
239 |
+ malloc_callback( png_structp png,
|
|
240 |
+ png_alloc_size_t size )
|
|
241 |
+ {
|
|
242 |
+ FT_UNUSED( png );
|
|
243 |
+ return _aligned_malloc( size, 16 );
|
|
244 |
+ }
|
|
245 |
+ |
|
246 |
+ |
|
247 |
+ /* Memory deallocation callback to release memory that was allocated */
|
|
248 |
+ /* with the matching memory allocation callback above. */
|
|
249 |
+ static void
|
|
250 |
+ free_callback( png_structp png,
|
|
251 |
+ png_voidp ptr )
|
|
252 |
+ {
|
|
253 |
+ FT_UNUSED( png );
|
|
254 |
+ _aligned_free( ptr );
|
|
255 |
+ }
|
|
256 |
+ |
|
257 |
+#endif /* _WIN64 */
|
|
258 |
+ |
|
259 |
+ |
|
224 | 260 |
static void
|
225 | 261 |
read_data_from_FT_Stream( png_structp png,
|
226 | 262 |
png_bytep data,
|
... | ... | @@ -292,10 +328,20 @@ |
292 | 328 |
|
293 | 329 |
FT_Stream_OpenMemory( &stream, data, png_len );
|
294 | 330 |
|
331 |
+#ifdef _WIN64
|
|
332 |
+ png = png_create_read_struct_2( PNG_LIBPNG_VER_STRING,
|
|
333 |
+ &error,
|
|
334 |
+ error_callback,
|
|
335 |
+ warning_callback,
|
|
336 |
+ NULL,
|
|
337 |
+ malloc_callback,
|
|
338 |
+ free_callback );
|
|
339 |
+#else
|
|
295 | 340 |
png = png_create_read_struct( PNG_LIBPNG_VER_STRING,
|
296 | 341 |
&error,
|
297 | 342 |
error_callback,
|
298 | 343 |
warning_callback );
|
344 |
+#endif
|
|
299 | 345 |
if ( !png )
|
300 | 346 |
{
|
301 | 347 |
error = FT_THROW( Out_Of_Memory );
|