git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Dec 26, 2005, 20:34 UTC
Message-ID
<Pine.LNX.4.63.0512262134290.19331@wbgn013.biozentrum.uni-wuerzburg.de>
In-Reply-To
<7vzmmnisix.fsf@assigned-by-dhcp.cox.net>
Hi,
On Mon, 26 Dec 2005, Junio C Hamano wrote:
Show 20 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > diff --git a/csum-file.c b/csum-file.c
> > index 5f9249a..2c0f097 100644
> > --- a/csum-file.c
> > +++ b/csum-file.c
> > @@ -121,6 +121,9 @@ int sha1write_compressed(struct sha1file
> >  	unsigned long maxsize;
> >  	void *out;
> >  
> > +	if (size == 0)
> > +		return 0;
> > +
> >  	memset(&stream, 0, sizeof(stream));
> >  	deflateInit(&stream, Z_DEFAULT_COMPRESSION);
> >  	maxsize = deflateBound(&stream, size);
> 
> I think this and the one in sha1_file.c::write_sha1_file() are
> wrong; 0-size input would not result in 0-size output.  Have you
> tested them by actually exercising the codepaths you touched?

No, I did not test them. At least not consciously (I did the whole work on Dec 24, when I was lying in bed, ill, trying to distract myself from being miserable).

The reason I did it this way: If zlib inflates a buffer of 0 bytes, it makes no sense to expect anything than 0 bytes to come out of it, right? Therefore, if zlib encounters a deflated buffer of 0 bytes, it should inflate it to 0 bytes. So it is a good idea in any case to write out 0 bytes.

However, thinking of it again, it might break backwards compatibility. But I don't think so.

Show 8 quoted lines
> > diff --git a/diffcore-pathspec.c b/diffcore-pathspec.c
> > index 68fe009..a12337a 100644
> > --- a/diffcore-pathspec.c
> > +++ b/diffcore-pathspec.c
> > @@ -48,10 +48,14 @@ void diffcore_pathspec(const char **path
> 
> diffcore-pathspec and diffcore-order can probably return without
> touching diff_queued_diff if there is no work to be done.

To be honest: I did not completely understand what that code does. It seemed obvious, but I got a track record of breaking things. So I was cautious. I will not try to modify it myself without a good test case.

Show 14 quoted lines
> > @@ -353,7 +353,8 @@ static void write_index_file(const char 
> >  {
> >  	struct sha1file *f;
> >  	struct object_entry **sorted_by_sha =
> > -		xcalloc(nr_objects, sizeof(struct object_entry *));
> > +		xcalloc(nr_objects ? nr_objects : 1,
> > +				sizeof(struct object_entry *));
> >  	struct object_entry **list = sorted_by_sha;
> >  	struct object_entry **last = sorted_by_sha + nr_objects;
> >  	unsigned int array[256];
> 
> This can be simplified by sorted_by_sha = list = last = NULL
> when nr_objects == 0 and avoiding qsort; that is what you did in
> pack-objects, I think.
If nr_objects == 0, we could write out a fixed index.

We could alternatively exit(1), because what sense does it make to have an index if the pack contains 0 objects? However, this has consequences: Every user of index-pack (does "fetch-pack --keep" call it?) has to be aware that empty packs are illegal.

Again, I did this so that the tool does not break. I'll try to come up with something better soon.

Show 16 quoted lines
> > @@ -448,8 +449,10 @@ int main(int argc, char **argv)
> >  
> >  	open_pack_file();
> >  	parse_pack_header();
> > -	objects = xcalloc(nr_objects, sizeof(struct object_entry));
> > -	deltas = xcalloc(nr_objects, sizeof(struct delta_entry));
> > +	objects = xcalloc(nr_objects ? nr_objects : 1,
> > +			sizeof(struct object_entry));
> > +	deltas = xcalloc(nr_objects ? nr_objects : 1,
> > +			sizeof(struct delta_entry));
> >  	parse_pack_objects();
> >  	free(deltas);
> >  	write_index_file(index_name, sha1);
> 
> Likewise I suspect.  After all the special case is only when
> reindexing an empty pack ;-).
Right.
Show 6 quoted lines
> My inclination is to do things in these steps:
> 
>  - apply cleanups that actually simplify the logic, while
>    leaving the ones that you needed to do (size ?  size : 1)
>    unmodified (BTW, must next_in/next_out point at non NULL when
>    avail_in/avail_out are zero?).

I was cautious. Maybe at some point in future, zlib relies on that. But it is probably better to try not calling zlib at all in these cases.

Show 13 quoted lines
>  - change x*alloc like this, once the above is done:
> 
>         static inline void *xmalloc(size_t size)
>         {
>                 void *ret = malloc(size);
>         #ifdef MALLOC_CAN_RETURN_NULL_ON_0SIZE
>                 if (!ret && !size)
>                         ret = malloc(size+1);
>         #endif
>                 if (!ret)
>                         die("Out of memory, malloc failed");
>                 return ret;
>         }
Sounds easiest.

Ciao, Dscho

Previous: Junio C HamanoNext: Junio C Hamano
Message 20 of 24 in “dietlibc compatibility”
  1. 0/4 dietlibc compatibilityEric Wong, Dec 24, 2005
  2. 1/4 git.c: extra #include for dietlibc (and possibly other C libraries)Eric Wong, Dec 24, 2005
  3. Junio C HamanoDec 26, 2005
  4. 2/4 short circuit out of a few places where we would allocate zero bytesEric Wong, Dec 24, 2005
  5. Johannes SchindelinDec 24, 2005
  6. H. Peter AnvinDec 28, 2005
  7. Linus TorvaldsDec 28, 2005
  8. Junio C HamanoDec 28, 2005
  9. H. Peter AnvinDec 28, 2005
  10. 3/4 add xmktime() function that always accounts for the TZ envEric Wong, Dec 24, 2005
  11. Johannes SchindelinDec 24, 2005
  12. Junio C HamanoDec 24, 2005
  13. Eric WongDec 24, 2005
  14. Junio C HamanoDec 24, 2005
  15. 4/4 git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}Eric Wong, Dec 24, 2005
  16. Junio C HamanoDec 24, 2005
  17. Eric WongDec 24, 2005
  18. Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}Johannes Schindelin, Dec 26, 2005
  19. Junio C HamanoDec 26, 2005
  20. Johannes SchindelinDec 26, 2005
  21. avoid asking ?alloc() for zero bytes.Junio C Hamano, Dec 26, 2005
  22. Johannes SchindelinDec 26, 2005
  23. Johannes SchindelinDec 28, 2005
  24. Eric WongDec 30, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.