[gzip] Use exact type for `ft_gzip_alloc` and `ft_gzip_free`.

While a function pointer may be cast to another function pointer
type, it is required to cast the function pointer back to the
original function pointer type before calling it.  If a parameter is
a pointer the exact pointer type is required.  Using a pointer to a
different underlying type is technically undefined behavior.  The
wrapper functions `ft_gzip_alloc` and `ft_gzip_free` took
`FT_Memory` (a `FT_MemoryRec_*`) instead of `voidpf` (`void*`), so
when gzip calls these callbacks through `alloc_func` or `free_func`
it invokes undefined behavior.  On most platforms this works out as
expected, but newer undefined behavior detectors and targets like
wasm can detect this and will produce an error.

* src/gzip/ftgzip.c (ft_gzip_alloc, ft_gzip_free): Update signatures
to exactly match `alloc_func` and `free_func`, respectively.
Internally, cast the `void*` opaque pointer to `FT_Memory`.
This commit is contained in:
Ben Wagner 2021-05-18 14:49:50 -04:00 committed by Werner Lemberg
parent 81852fbccc
commit 06e21ffedf
2 changed files with 37 additions and 13 deletions

View File

@ -1,3 +1,23 @@
2021-05-19 Ben Wagner <bungeman@chromium.org>
[gzip] Use exact type for `ft_gzip_alloc` and `ft_gzip_free`.
While a function pointer may be cast to another function pointer
type, it is required to cast the function pointer back to the
original function pointer type before calling it. If a parameter is
a pointer the exact pointer type is required. Using a pointer to a
different underlying type is technically undefined behavior. The
wrapper functions `ft_gzip_alloc` and `ft_gzip_free` took
`FT_Memory` (a `FT_MemoryRec_*`) instead of `voidpf` (`void*`), so
when gzip calls these callbacks through `alloc_func` or `free_func`
it invokes undefined behavior. On most platforms this works out as
expected, but newer undefined behavior detectors and targets like
wasm can detect this and will produce an error.
* src/gzip/ftgzip.c (ft_gzip_alloc, ft_gzip_free): Update signatures
to exactly match `alloc_func` and `free_func`, respectively.
Internally, cast the `void*` opaque pointer to `FT_Memory`.
2021-05-18 Alexei Podtelezhnikov <apodtele@gmail.com> 2021-05-18 Alexei Podtelezhnikov <apodtele@gmail.com>
Prioritize the anti-aliasing renderer module. Prioritize the anti-aliasing renderer module.

View File

@ -121,10 +121,11 @@
'malloc/free' */ 'malloc/free' */
static voidpf static voidpf
ft_gzip_alloc( FT_Memory memory, ft_gzip_alloc( voidpf opaque,
uInt items, uInt items,
uInt size ) uInt size )
{ {
FT_Memory memory = (FT_Memory)opaque;
FT_ULong sz = (FT_ULong)size * items; FT_ULong sz = (FT_ULong)size * items;
FT_Error error; FT_Error error;
FT_Pointer p = NULL; FT_Pointer p = NULL;
@ -137,9 +138,12 @@
static void static void
ft_gzip_free( FT_Memory memory, ft_gzip_free( voidpf opaque,
voidpf address ) voidpf address )
{ {
FT_Memory memory = (FT_Memory)opaque;
FT_MEM_FREE( address ); FT_MEM_FREE( address );
} }
@ -151,14 +155,14 @@
unsigned items, unsigned items,
unsigned size ) unsigned size )
{ {
return ft_gzip_alloc( (FT_Memory)opaque, items, size ); return ft_gzip_alloc( opaque, items, size );
} }
local void local void
zcfree( voidpf opaque, zcfree( voidpf opaque,
voidpf ptr ) voidpf ptr )
{ {
ft_gzip_free( (FT_Memory)opaque, ptr ); ft_gzip_free( opaque, ptr );
} }
#endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */ #endif /* !SYSTEM_ZLIB && !USE_ZLIB_ZCALLOC */
@ -305,8 +309,8 @@
} }
/* initialize zlib -- there is no zlib header in the compressed stream */ /* initialize zlib -- there is no zlib header in the compressed stream */
zstream->zalloc = (alloc_func)ft_gzip_alloc; zstream->zalloc = ft_gzip_alloc;
zstream->zfree = (free_func) ft_gzip_free; zstream->zfree = ft_gzip_free;
zstream->opaque = stream->memory; zstream->opaque = stream->memory;
zstream->avail_in = 0; zstream->avail_in = 0;
@ -742,8 +746,8 @@
stream.next_out = output; stream.next_out = output;
stream.avail_out = (uInt)*output_len; stream.avail_out = (uInt)*output_len;
stream.zalloc = (alloc_func)ft_gzip_alloc; stream.zalloc = ft_gzip_alloc;
stream.zfree = (free_func) ft_gzip_free; stream.zfree = ft_gzip_free;
stream.opaque = memory; stream.opaque = memory;
/* This is a temporary fix and will be removed once the internal /* This is a temporary fix and will be removed once the internal