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