[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>
Prioritize the anti-aliasing renderer module.

View File

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