[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`.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
diff --git a/ChangeLog b/ChangeLog
index 0ec6870..d3583a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c
index 0dc0a61..788a37b 100644
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -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