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@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
_______________________________________________
macports-users mailing list
macports-users@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macports-users

Reply via email to