2012.12.12 23:42 "[Tiff] Dealing with unportability of malloc(0)", by Tom Lane

2012.12.12 23:42 "[Tiff] Dealing with unportability of malloc(0)", by Tom Lane

I noticed that Bob Friesenhahn recently committed this change to make _TIFFmalloc() behave the same on platforms where malloc(0) returns a zero-sized chunk of memory as it does on platforms where the same call returns NULL:

*** 257,262 ****
--- 257,265 ----
  _TIFFmalloc(tmsize_t s)
+ if (s == 0)
+ return ((void *) NULL);
        return (malloc((size_t) s));

I'd like to suggest that this be considered further and perhaps flipped to the opposite convention, ie, always return an actual block of memory. That's not hard to accomplish by increasing a request size of 0 to 1 byte:

        if (s == 0)
- return ((void *) NULL);
+ s = 1;

The reason I think the never-null convention is preferable is that the null-for-zero convention tends to require doctoring up call sites. The typical pattern is

        ptr = _TIFFmalloc(some_request);
        if (ptr == NULL)
                // throw error

If there's any possibility that some_request is (validly) zero, this code is now broken, because it will throw errors when it should not.

Now, libtiff is more fortunate than many projects in that most places that might have this problem are calling _TIFFCheckMalloc, which means that there are fewer places to fix than there might be. But I doubt

that that's really the only one. In fact, if that *were* the only one, we'd not need this patch at all, because that call site already tries to dodge the platform dependency.

... unfortunately, it does so incorrectly. _TIFFCheckMalloc is coded to call _TIFFCheckRealloc, and the latter is miswritten so that it is guaranteed to throw error for a zero request, no matter which behavior the underlying malloc and realloc calls have.

And, just to add insult to injury, first it will leak the old block if there is one, since neither realloc() nor free() will get called.

None of this is terribly hard to fix, but first we need a policy decision about which platform-specific behavior we want to standardize on. I gave my argument above, does anyone want to advocate for the other way? Are there pieces of libtiff where the null-for-zero convention is preferable?

                        regards, tom lane