error using MacPorts zlib, not present with system zlib?
Eric Cronin
ecronin at macports.org
Wed Feb 22 13:50:52 PST 2012
On 22.02.2012 15:32, Adam Mercer wrote:
> Hi
>
> Not sure of the correct place to discuss this but in tracking down a
> build issue with a port I've found an interesting issue with MacPorts
> zlib.
>
> This simple test code illustrates the problem:
>
> [ram at mimir tmp]$ cat test.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <zlib.h>
>
> int main(void)
> {
> void *file;
<snip>
> c = gzgetc(file);
This code is wrong. The zlib documentation says gzgetc takes a gzFile*
not a void*.
> Does anyone know why MacPorts zlib treats this as an error but the
> system version doesn't?
I'm not near a Mac right now, but I believe the system version of zlib
is pretty ancient. In version 1.2.4 there was a "Wholesale replacement
of gz* functions with faster versions" according to zlib.net, one of
which I suspect was the replacement of the gzgetc() function with a
macro.
C treats void* very unsafely, silently converting it to and from other
pointer types whenever it knows how. So converting the gzFile* gzopen()
returned to the void* 'file' is legal. Then, if gzgetc() is an actual
function declared as 'char gzgetc(gzFile*)' the compiler will allow the
void* be passed to the function, and within the function it is treated
as a gzFile*. But if gzgetc is just a macro the compiler doesn't know
to convert 'file' to a gzFile*, so you get errors about trying to treat
void as struct/union. If the API said gzgetc took a void* they would
fix this by casting "g" to a gzFile* inside the macro that replaced the
function, but the API doesn't say this, and so the zlib authors don't...
The current version is actually both faster and safer since it catches
this type of void* abuse.
So tldr answer: patch the port using libz to use a gzFile* or to cast
the void* gack to a gzFile* before calling functions expecting a
gzFile*.
Thanks,
Eric
More information about the macports-users
mailing list