* [PATCH 0/4] dietlibc compatibility
@ 2005-12-24 12:10 Eric Wong
2005-12-24 12:11 ` [PATCH 1/4] git.c: extra #include for dietlibc (and possibly other C libraries) Eric Wong
` (3 more replies)
0 siblings, 4 replies; 24+ messages in thread
From: Eric Wong @ 2005-12-24 12:10 UTC (permalink / raw)
To: git list
I've started statically-linking git binaries against dietlibc to avoid
having to recompile it for every machine/distro and chroot (lots!) I
would use it in.
For building git (on a Debian unstable system with dietlibc-dev),
I used the following make vars:
CC=diet -v gcc
NO_STRCASESTR=YesPlease
NO_SETENV=YesPlease
The dietlibc setenv() doesn't seem very nice to **envp in git.c,
resulting in $PATH being clobbered when it runs execve(). This
caused tests to fail. Fortunately, gitsetenv() saved the day.
The following patches fix other issues I had with dietlibc.
--
Eric Wong
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH 1/4] git.c: extra #include for dietlibc (and possibly other C libraries)
2005-12-24 12:10 [PATCH 0/4] dietlibc compatibility Eric Wong
@ 2005-12-24 12:11 ` Eric Wong
2005-12-26 17:01 ` Junio C Hamano
2005-12-24 12:12 ` [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes Eric Wong
` (2 subsequent siblings)
3 siblings, 1 reply; 24+ messages in thread
From: Eric Wong @ 2005-12-24 12:11 UTC (permalink / raw)
To: git list
struct winsize is defined in <termios.h>, and that's not pulled
in by other #includes in that file
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
ae5641fcbc58509572d080c33a20c829b82ae9b0
diff --git a/git.c b/git.c
index e795ddb..434a3d9 100644
--- a/git.c
+++ b/git.c
@@ -9,6 +9,7 @@
#include <limits.h>
#include <stdarg.h>
#include <sys/ioctl.h>
+#include <termios.h>
#include "git-compat-util.h"
#ifndef PATH_MAX
--
1.0.GIT
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes
2005-12-24 12:10 [PATCH 0/4] dietlibc compatibility Eric Wong
2005-12-24 12:11 ` [PATCH 1/4] git.c: extra #include for dietlibc (and possibly other C libraries) Eric Wong
@ 2005-12-24 12:12 ` Eric Wong
2005-12-24 12:44 ` Johannes Schindelin
2005-12-28 4:22 ` H. Peter Anvin
2005-12-24 12:13 ` [PATCH 3/4] add xmktime() function that always accounts for the TZ env Eric Wong
2005-12-24 12:14 ` [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc} Eric Wong
3 siblings, 2 replies; 24+ messages in thread
From: Eric Wong @ 2005-12-24 12:12 UTC (permalink / raw)
To: git list
dietlibc versions of malloc, calloc and realloc all return NULL if
they're told to allocate 0 bytes, causes the x* wrappers to die().
There are several more places where these calls could end up asking
for 0 bytes, too...
Maybe simply not die()-ing in the x* wrappers if 0/NULL is returned
when the requested size is zero is a safer and easier way to go.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
commit.c | 3 +++
diffcore-rename.c | 2 +-
2 files changed, 4 insertions(+), 1 deletions(-)
ee9d90c652be126345dec2ac204284e80e685160
diff --git a/commit.c b/commit.c
index e867b86..edd4ded 100644
--- a/commit.c
+++ b/commit.c
@@ -560,6 +560,9 @@ void sort_in_topological_order(struct co
next = next->next;
count++;
}
+
+ if (!count)
+ return;
/* allocate an array to help sort the list */
nodes = xcalloc(count, sizeof(*nodes));
/* link the list to the array */
diff --git a/diffcore-rename.c b/diffcore-rename.c
index dba965c..39d9126 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -282,7 +282,7 @@ void diffcore_rename(struct diff_options
else if (detect_rename == DIFF_DETECT_COPY)
register_rename_src(p->one, 1);
}
- if (rename_dst_nr == 0 ||
+ if (rename_dst_nr == 0 || rename_src_nr == 0 ||
(0 < rename_limit && rename_limit < rename_dst_nr))
goto cleanup; /* nothing to do */
--
1.0.GIT
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 3/4] add xmktime() function that always accounts for the TZ env
2005-12-24 12:10 [PATCH 0/4] dietlibc compatibility Eric Wong
2005-12-24 12:11 ` [PATCH 1/4] git.c: extra #include for dietlibc (and possibly other C libraries) Eric Wong
2005-12-24 12:12 ` [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes Eric Wong
@ 2005-12-24 12:13 ` Eric Wong
2005-12-24 12:45 ` Johannes Schindelin
2005-12-24 19:18 ` Junio C Hamano
2005-12-24 12:14 ` [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc} Eric Wong
3 siblings, 2 replies; 24+ messages in thread
From: Eric Wong @ 2005-12-24 12:13 UTC (permalink / raw)
To: git list
This function was added because mktime in dietlibc doesn't seem to
account for the TZ env. Also, xmktime() now shares the same
always-summer bug TZ parsing elsewhere, so at least we can
be wrong about summer consistently.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
cache.h | 2 ++
convert-objects.c | 4 ++--
date.c | 30 ++++++++++++++++++++++++++----
3 files changed, 30 insertions(+), 6 deletions(-)
3b0763ae6fce6c69021e1216660f4c0ee301512b
diff --git a/cache.h b/cache.h
index cb87bec..c5ff4b7 100644
--- a/cache.h
+++ b/cache.h
@@ -5,6 +5,7 @@
#include SHA1_HEADER
#include <zlib.h>
+#include <time.h>
#if ZLIB_VERNUM < 0x1200
#define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
@@ -236,6 +237,7 @@ extern void *read_object_with_reference(
const char *show_date(unsigned long time, int timezone);
int parse_date(const char *date, char *buf, int bufsize);
+time_t xmktime(struct tm *tm);
void datestamp(char *buf, int bufsize);
unsigned long approxidate(const char *);
diff --git a/convert-objects.c b/convert-objects.c
index b49bce2..0fe1229 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -178,7 +178,7 @@ static unsigned long parse_oldstyle_date
const char *next = strptime(buf, *fmt, &tm);
if (next) {
if (!*next)
- return mktime(&tm);
+ return xmktime(&tm);
buf = next;
} else {
const char **p = timezones;
@@ -195,7 +195,7 @@ static unsigned long parse_oldstyle_date
fmt++;
} while (*buf && *fmt);
printf("left: %s\n", buf);
- return mktime(&tm);
+ return xmktime(&tm);
}
static int convert_date_line(char *dst, void **buf, unsigned long *sp)
diff --git a/date.c b/date.c
index 3e11500..5596476 100644
--- a/date.c
+++ b/date.c
@@ -141,6 +141,28 @@ static int match_string(const char *date
return i;
}
+time_t xmktime(struct tm *tm)
+{
+ time_t ret = my_mktime(tm);
+ char * tz = getenv("TZ");
+
+ if (tz) {
+ int i;
+ for (i = 0; i < NR_TZ; i++) {
+ int match = match_string(tz, timezone_names[i].name);
+ if (match >= 3) {
+ int off = timezone_names[i].offset;
+
+ /* This is bogus, but we like summer */
+ off += timezone_names[i].dst;
+
+ ret += 60*off;
+ }
+ }
+ }
+ return ret;
+}
+
static int skip_alpha(const char *date)
{
int i = 0;
@@ -436,10 +458,10 @@ int parse_date(const char *date, char *r
date += match;
}
- /* mktime uses local timezone */
+ /* (x)mktime uses local timezone */
then = my_mktime(&tm);
if (offset == -1)
- offset = (then - mktime(&tm)) / 60;
+ offset = (then - xmktime(&tm)) / 60;
if (then == -1)
return -1;
@@ -464,7 +486,7 @@ void datestamp(char *buf, int bufsize)
static void update_tm(struct tm *tm, unsigned long sec)
{
- time_t n = mktime(tm) - sec;
+ time_t n = xmktime(tm) - sec;
localtime_r(&n, tm);
}
@@ -642,5 +664,5 @@ unsigned long approxidate(const char *da
tm.tm_mday = number;
if (tm.tm_mon > now.tm_mon)
tm.tm_year--;
- return mktime(&tm);
+ return xmktime(&tm);
}
--
1.0.GIT
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-24 12:10 [PATCH 0/4] dietlibc compatibility Eric Wong
` (2 preceding siblings ...)
2005-12-24 12:13 ` [PATCH 3/4] add xmktime() function that always accounts for the TZ env Eric Wong
@ 2005-12-24 12:14 ` Eric Wong
2005-12-24 18:28 ` Junio C Hamano
3 siblings, 1 reply; 24+ messages in thread
From: Eric Wong @ 2005-12-24 12:14 UTC (permalink / raw)
To: git list
dietlibc versions of these allocators returns NULL if a size of zero is
specified. Obviously, this is a problem with the x* wrappers since
we check for them returning NULL.
Down the line, it'd be better to hunt down and eliminate all calls to
these functions when they are called with a zero argument. I've already
added some checks for these cases that were exposed by tests.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git-compat-util.h | 23 ++++++++++++++++++++---
1 files changed, 20 insertions(+), 3 deletions(-)
113dca27f9f95a76a0f98929720f5f567c7586b2
diff --git a/git-compat-util.h b/git-compat-util.h
index 0c98c99..bd2f150 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -62,7 +62,12 @@ extern char *gitstrcasestr(const char *h
static inline void *xmalloc(size_t size)
{
- void *ret = malloc(size);
+ void *ret;
+
+ if (!size)
+ return NULL;
+
+ ret = malloc(size);
if (!ret)
die("Out of memory, malloc failed");
return ret;
@@ -70,7 +75,14 @@ static inline void *xmalloc(size_t size)
static inline void *xrealloc(void *ptr, size_t size)
{
- void *ret = realloc(ptr, size);
+ void *ret;
+
+ if (!size) {
+ free(ptr);
+ return NULL;
+ }
+
+ ret = realloc(ptr, size);
if (!ret)
die("Out of memory, realloc failed");
return ret;
@@ -78,7 +90,12 @@ static inline void *xrealloc(void *ptr,
static inline void *xcalloc(size_t nmemb, size_t size)
{
- void *ret = calloc(nmemb, size);
+ void *ret;
+
+ if (!nmemb || !size)
+ return NULL;
+
+ ret = calloc(nmemb, size);
if (!ret)
die("Out of memory, calloc failed");
return ret;
--
1.0.GIT
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes
2005-12-24 12:12 ` [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes Eric Wong
@ 2005-12-24 12:44 ` Johannes Schindelin
2005-12-28 4:22 ` H. Peter Anvin
1 sibling, 0 replies; 24+ messages in thread
From: Johannes Schindelin @ 2005-12-24 12:44 UTC (permalink / raw)
To: Eric Wong; +Cc: git list
Hi,
On Sat, 24 Dec 2005, Eric Wong wrote:
> dietlibc versions of malloc, calloc and realloc all return NULL if
> they're told to allocate 0 bytes, causes the x* wrappers to die().
>
> There are several more places where these calls could end up asking
> for 0 bytes, too...
>
> Maybe simply not die()-ing in the x* wrappers if 0/NULL is returned
> when the requested size is zero is a safer and easier way to go.
I would prefer that, too. But the cleanest way would be to prevent calls
to *alloc if the size is 0...
Ciao,
Dscho
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 3/4] add xmktime() function that always accounts for the TZ env
2005-12-24 12:13 ` [PATCH 3/4] add xmktime() function that always accounts for the TZ env Eric Wong
@ 2005-12-24 12:45 ` Johannes Schindelin
2005-12-24 19:18 ` Junio C Hamano
1 sibling, 0 replies; 24+ messages in thread
From: Johannes Schindelin @ 2005-12-24 12:45 UTC (permalink / raw)
To: Eric Wong; +Cc: git list
Hi,
On Sat, 24 Dec 2005, Eric Wong wrote:
> This function was added because mktime in dietlibc doesn't seem to
> account for the TZ env. Also, xmktime() now shares the same
> always-summer bug TZ parsing elsewhere, so at least we can
> be wrong about summer consistently.
How about making this a compat function, which is used when the Makefile
variable MKTIME_IGNORES_TZ is set?
Ciao,
Dscho
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-24 12:14 ` [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc} Eric Wong
@ 2005-12-24 18:28 ` Junio C Hamano
2005-12-24 21:15 ` Eric Wong
0 siblings, 1 reply; 24+ messages in thread
From: Junio C Hamano @ 2005-12-24 18:28 UTC (permalink / raw)
To: Eric Wong; +Cc: git
Eric Wong <normalperson@yhbt.net> writes:
> dietlibc versions of these allocators returns NULL if a size of zero is
> specified. Obviously, this is a problem with the x* wrappers since
> we check for them returning NULL.
>
> Down the line, it'd be better to hunt down and eliminate all calls to
> these functions when they are called with a zero argument. I've already
> added some checks for these cases that were exposed by tests.
I agree that it is a bug to rely on *alloc(0) not returning
NULL, but this patch is too risky. It would be a good thing to
have debugging variant of x* wrappers that barf on a 0-byte
allocation request to find the offending callers, instead of
returning NULL, maybe like the attached patch.
Since eradicating *alloc(0) calls is the right way to go, but it
takes time. Touching x* wrappers for general public should not
be done before it is done. It breaks things for everybody,
while the current code is broken only for diet people and
developers that use the debugging variant of x* wrappers.
-- >8 --
diff --git a/git-compat-util.h b/git-compat-util.h
index 0c98c99..08fd6bc 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -60,9 +60,17 @@ extern int gitsetenv(const char *, const
extern char *gitstrcasestr(const char *haystack, const char *needle);
#endif
+#ifdef DEBUG_0ALLOC
+#define debug_0alloc(sz) assert(0 < (sz))
+#else
+#define debug_0alloc(sz)
+#endif
+
static inline void *xmalloc(size_t size)
{
void *ret = malloc(size);
+
+ debug_0alloc(size);
if (!ret)
die("Out of memory, malloc failed");
return ret;
@@ -71,6 +79,7 @@ static inline void *xmalloc(size_t size)
static inline void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
+ debug_0alloc(size);
if (!ret)
die("Out of memory, realloc failed");
return ret;
@@ -79,6 +88,7 @@ static inline void *xrealloc(void *ptr,
static inline void *xcalloc(size_t nmemb, size_t size)
{
void *ret = calloc(nmemb, size);
+ debug_0alloc(nmemb);
if (!ret)
die("Out of memory, calloc failed");
return ret;
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 3/4] add xmktime() function that always accounts for the TZ env
2005-12-24 12:13 ` [PATCH 3/4] add xmktime() function that always accounts for the TZ env Eric Wong
2005-12-24 12:45 ` Johannes Schindelin
@ 2005-12-24 19:18 ` Junio C Hamano
2005-12-24 19:52 ` Eric Wong
1 sibling, 1 reply; 24+ messages in thread
From: Junio C Hamano @ 2005-12-24 19:18 UTC (permalink / raw)
To: Eric Wong; +Cc: git
Eric Wong <normalperson@yhbt.net> writes:
> This function was added because mktime in dietlibc doesn't seem to
> account for the TZ env. Also, xmktime() now shares the same
> always-summer bug TZ parsing elsewhere,
Where elsewhere?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 3/4] add xmktime() function that always accounts for the TZ env
2005-12-24 19:18 ` Junio C Hamano
@ 2005-12-24 19:52 ` Eric Wong
2005-12-24 21:10 ` Junio C Hamano
0 siblings, 1 reply; 24+ messages in thread
From: Eric Wong @ 2005-12-24 19:52 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Junio C Hamano <junkio@cox.net> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
>
> > This function was added because mktime in dietlibc doesn't seem to
> > account for the TZ env. Also, xmktime() now shares the same
> > always-summer bug TZ parsing elsewhere,
>
> Where elsewhere?
match_alpha() in date.c
--
Eric Wong
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 3/4] add xmktime() function that always accounts for the TZ env
2005-12-24 19:52 ` Eric Wong
@ 2005-12-24 21:10 ` Junio C Hamano
0 siblings, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2005-12-24 21:10 UTC (permalink / raw)
To: Eric Wong; +Cc: git
Eric Wong <normalperson@yhbt.net> writes:
> Junio C Hamano <junkio@cox.net> wrote:
>> Eric Wong <normalperson@yhbt.net> writes:
>>
>> > This function was added because mktime in dietlibc doesn't seem to
>> > account for the TZ env. Also, xmktime() now shares the same
>> > always-summer bug TZ parsing elsewhere,
>>
>> Where elsewhere?
>
> match_alpha() in date.c
Then probably we should extract partime.c from rcs and munge
that.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-24 18:28 ` Junio C Hamano
@ 2005-12-24 21:15 ` Eric Wong
2005-12-26 18:16 ` [PATCH] Avoid allocating 0 bytes, was " Johannes Schindelin
0 siblings, 1 reply; 24+ messages in thread
From: Eric Wong @ 2005-12-24 21:15 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Junio C Hamano <junkio@cox.net> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
>
> > dietlibc versions of these allocators returns NULL if a size of zero is
> > specified. Obviously, this is a problem with the x* wrappers since
> > we check for them returning NULL.
> >
> > Down the line, it'd be better to hunt down and eliminate all calls to
> > these functions when they are called with a zero argument. I've already
> > added some checks for these cases that were exposed by tests.
>
> I agree that it is a bug to rely on *alloc(0) not returning
> NULL, but this patch is too risky. It would be a good thing to
> have debugging variant of x* wrappers that barf on a 0-byte
> allocation request to find the offending callers, instead of
> returning NULL, maybe like the attached patch.
>
> Since eradicating *alloc(0) calls is the right way to go, but it
> takes time. Touching x* wrappers for general public should not
> be done before it is done. It breaks things for everybody,
> while the current code is broken only for diet people and
> developers that use the debugging variant of x* wrappers.
I'll be using the following patch to collect results for the next few
days without interrupting my work on other projects. I'll post
patches to remove *alloc(0) calls when I find them.
diff --git a/git-compat-util.h b/git-compat-util.h
index 0c98c99..43be289 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -60,9 +60,41 @@ extern int gitsetenv(const char *, const
extern char *gitstrcasestr(const char *haystack, const char *needle);
#endif
+static void fork_for_core (const char * caller)
+{
+ pid_t child = fork();
+ if (child == 0) {
+ int i;
+ char out[4096];
+ char * progname = "unknown";
+ FILE * dbg = fopen("/var/tmp/git_alloc_dbg.log","a");
+
+ for(i = 0; environ[i]; i++) {
+ if (strstr(environ[i],"_=") == environ[i])
+ progname = environ[i];
+ }
+
+ snprintf(out, 4096, "%s:%s: pid %d dumping core for pid %d\n",
+ progname, caller, getpid(), getppid());
+
+ fputs(out, stderr);
+ fputs(out, dbg);
+ fflush(NULL);
+
+ abort();
+ }
+}
+
static inline void *xmalloc(size_t size)
{
- void *ret = malloc(size);
+ void *ret;
+
+ if (!size) {
+ fork_for_core(__func__);
+ return NULL;
+ }
+
+ ret = malloc(size);
if (!ret)
die("Out of memory, malloc failed");
return ret;
@@ -70,7 +102,15 @@ static inline void *xmalloc(size_t size)
static inline void *xrealloc(void *ptr, size_t size)
{
- void *ret = realloc(ptr, size);
+ void *ret;
+
+ if (!size) {
+ fork_for_core(__func__);
+ free(ptr);
+ return NULL;
+ }
+
+ ret = realloc(ptr, size);
if (!ret)
die("Out of memory, realloc failed");
return ret;
@@ -78,7 +118,14 @@ static inline void *xrealloc(void *ptr,
static inline void *xcalloc(size_t nmemb, size_t size)
{
- void *ret = calloc(nmemb, size);
+ void *ret;
+
+ if (!nmemb || !size) {
+ fork_for_core(__func__);
+ return NULL;
+ }
+
+ ret = calloc(nmemb, size);
if (!ret)
die("Out of memory, calloc failed");
return ret;
--
Eric Wong
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 1/4] git.c: extra #include for dietlibc (and possibly other C libraries)
2005-12-24 12:11 ` [PATCH 1/4] git.c: extra #include for dietlibc (and possibly other C libraries) Eric Wong
@ 2005-12-26 17:01 ` Junio C Hamano
0 siblings, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2005-12-26 17:01 UTC (permalink / raw)
To: Eric Wong; +Cc: git
Eric Wong <normalperson@yhbt.net> writes:
> struct winsize is defined in <termios.h>, and that's not pulled
> in by other #includes in that file
With glibc, sys/ioctl.h seems to pull it in. Input from people
on other platforms is appreciated on this.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-24 21:15 ` Eric Wong
@ 2005-12-26 18:16 ` Johannes Schindelin
2005-12-26 19:10 ` Junio C Hamano
2005-12-30 23:00 ` Eric Wong
0 siblings, 2 replies; 24+ messages in thread
From: Johannes Schindelin @ 2005-12-26 18:16 UTC (permalink / raw)
To: Eric Wong; +Cc: Junio C Hamano, git
This is the result of a relatively quick audit of the source code. There
might still be a few odd places lurking out there, but I am quite certain
I caught most if not all.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
csum-file.c | 3 +++
diff.c | 6 +++--
diffcore-order.c | 8 ++++++-
diffcore-pathspec.c | 12 +++++++----
index-pack.c | 11 ++++++----
pack-objects.c | 6 ++++-
read-tree.c | 17 +++++++++------
sha1_file.c | 56 ++++++++++++++++++++++++++-------------------------
tree-diff.c | 4 ++++
unpack-objects.c | 2 +-
10 files changed, 76 insertions(+), 49 deletions(-)
751737aeec4dd3cc1afd1d1d3fa529cfc74535e0
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);
diff --git a/diff.c b/diff.c
index c815918..daee05b 100644
--- a/diff.c
+++ b/diff.c
@@ -504,9 +504,9 @@ static void prepare_temp_file(const char
}
if (S_ISLNK(st.st_mode)) {
int ret;
- char *buf, buf_[1024];
- buf = ((sizeof(buf_) < st.st_size) ?
- xmalloc(st.st_size) : buf_);
+ char buf[MAXPATHLEN + 1];
+ if (st.st_size > MAXPATHLEN)
+ die("Unbelievably long symlink: %", name);
ret = readlink(name, buf, st.st_size);
if (ret < 0)
die("readlink(%s)", name);
diff --git a/diffcore-order.c b/diffcore-order.c
index b381223..94a4996 100644
--- a/diffcore-order.c
+++ b/diffcore-order.c
@@ -61,6 +61,8 @@ static void prepare_order(const char *or
}
if (pass == 0) {
order_cnt = cnt;
+ if (cnt == 0)
+ return;
order = xmalloc(sizeof(*order) * cnt);
}
}
@@ -105,9 +107,13 @@ static int compare_pair_order(const void
void diffcore_order(const char *orderfile)
{
struct diff_queue_struct *q = &diff_queued_diff;
- struct pair_order *o = xmalloc(sizeof(*o) * q->nr);
+ struct pair_order *o;
int i;
+ if (q->nr == 0)
+ return;
+
+ o = xmalloc(sizeof(*o) * q->nr);
prepare_order(orderfile);
for (i = 0; i < q->nr; i++) {
o[i].pair = q->queue[i];
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
for (i = 0; pathspec[i]; i++)
;
speccnt = i;
- spec = xmalloc(sizeof(*spec) * speccnt);
- for (i = 0; pathspec[i]; i++) {
- spec[i].spec = pathspec[i];
- spec[i].len = strlen(pathspec[i]);
+ if (speccnt == 0)
+ spec = NULL;
+ else {
+ spec = xmalloc(sizeof(*spec) * speccnt);
+ for (i = 0; pathspec[i]; i++) {
+ spec[i].spec = pathspec[i];
+ spec[i].len = strlen(pathspec[i]);
+ }
}
for (i = 0; i < q->nr; i++) {
diff --git a/index-pack.c b/index-pack.c
index d4ce3af..2927632 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -103,7 +103,7 @@ static void *unpack_entry_data(unsigned
unsigned long pack_limit = pack_size - 20;
unsigned long pos = *current_pos;
z_stream stream;
- void *buf = xmalloc(size);
+ void *buf = xmalloc(size ? size : 1);
memset(&stream, 0, sizeof(stream));
stream.next_out = buf;
@@ -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];
@@ -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);
diff --git a/pack-objects.c b/pack-objects.c
index caf3b6b..f5a147f 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -406,7 +406,8 @@ static void prepare_pack(int window, int
fprintf(stderr, "Packing %d objects\n", nr_objects);
- sorted_by_type = create_sorted_list(type_size_sort);
+ if (nr_objects > 0)
+ sorted_by_type = create_sorted_list(type_size_sort);
if (window && depth)
find_deltas(sorted_by_type, window+1, depth);
write_pack_file();
@@ -540,7 +541,8 @@ int main(int argc, char **argv)
if (non_empty && !nr_objects)
return 0;
- sorted_by_sha = create_sorted_list(sha1_sort);
+ if (nr_objects > 0)
+ sorted_by_sha = create_sorted_list(sha1_sort);
SHA1_Init(&ctx);
list = sorted_by_sha;
for (i = 0; i < nr_objects; i++) {
diff --git a/read-tree.c b/read-tree.c
index e3b9c0d..a46c6fe 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -294,17 +294,20 @@ static int unpack_trees(merge_fn_t fn)
{
int indpos = 0;
unsigned len = object_list_length(trees);
- struct tree_entry_list **posns =
- xmalloc(len * sizeof(struct tree_entry_list *));
+ struct tree_entry_list **posns;
int i;
struct object_list *posn = trees;
merge_size = len;
- for (i = 0; i < len; i++) {
- posns[i] = ((struct tree *) posn->item)->entries;
- posn = posn->next;
+
+ if (len) {
+ posns = xmalloc(len * sizeof(struct tree_entry_list *));
+ for (i = 0; i < len; i++) {
+ posns[i] = ((struct tree *) posn->item)->entries;
+ posn = posn->next;
+ }
+ if (unpack_trees_rec(posns, len, "", fn, &indpos))
+ return -1;
}
- if (unpack_trees_rec(posns, len, "", fn, &indpos))
- return -1;
if (trivial_merges_only && nontrivial_merge)
die("Merge requires file-level merging");
diff --git a/sha1_file.c b/sha1_file.c
index 8bebbb2..0d60884 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1371,35 +1371,37 @@ int write_sha1_file(void *buf, unsigned
return -1;
}
- /* Set it up */
- memset(&stream, 0, sizeof(stream));
- deflateInit(&stream, Z_BEST_COMPRESSION);
- size = deflateBound(&stream, len+hdrlen);
- compressed = xmalloc(size);
-
- /* Compress it */
- stream.next_out = compressed;
- stream.avail_out = size;
-
- /* First header.. */
- stream.next_in = hdr;
- stream.avail_in = hdrlen;
- while (deflate(&stream, 0) == Z_OK)
- /* nothing */;
-
- /* Then the data itself.. */
- stream.next_in = buf;
- stream.avail_in = len;
- while (deflate(&stream, Z_FINISH) == Z_OK)
- /* nothing */;
- deflateEnd(&stream);
- size = stream.total_out;
+ if (len + hdrlen > 0) {
+ /* Set it up */
+ memset(&stream, 0, sizeof(stream));
+ deflateInit(&stream, Z_BEST_COMPRESSION);
+ size = deflateBound(&stream, len+hdrlen);
+ compressed = xmalloc(size);
+
+ /* Compress it */
+ stream.next_out = compressed;
+ stream.avail_out = size;
- if (write(fd, compressed, size) != size)
- die("unable to write file");
+ /* First header.. */
+ stream.next_in = hdr;
+ stream.avail_in = hdrlen;
+ while (deflate(&stream, 0) == Z_OK)
+ /* nothing */;
+
+ /* Then the data itself.. */
+ stream.next_in = buf;
+ stream.avail_in = len;
+ while (deflate(&stream, Z_FINISH) == Z_OK)
+ /* nothing */;
+ deflateEnd(&stream);
+ size = stream.total_out;
+
+ if (write(fd, compressed, size) != size)
+ die("unable to write file");
+ free(compressed);
+ }
fchmod(fd, 0444);
close(fd);
- free(compressed);
return move_temp_to_file(tmpfile, filename);
}
@@ -1429,7 +1431,7 @@ int write_sha1_to_fd(int fd, const unsig
memset(&stream, 0, sizeof(stream));
deflateInit(&stream, Z_BEST_COMPRESSION);
size = deflateBound(&stream, len + hdrlen);
- temp_obj = buf = xmalloc(size);
+ temp_obj = buf = xmalloc(size ? size : 1);
/* Compress it */
stream.next_out = buf;
diff --git a/tree-diff.c b/tree-diff.c
index 0ef06a9..382092b 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -263,6 +263,10 @@ void diff_tree_setup_paths(const char **
paths = p;
nr_paths = count_paths(paths);
+ if (nr_paths == 0) {
+ pathlens = NULL;
+ return;
+ }
pathlens = xmalloc(nr_paths * sizeof(int));
for (i=0; i<nr_paths; i++)
pathlens[i] = strlen(paths[i]);
diff --git a/unpack-objects.c b/unpack-objects.c
index 5c5cb12..572eeee 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -53,7 +53,7 @@ static void use(int bytes)
static void *get_data(unsigned long size)
{
z_stream stream;
- void *buf = xmalloc(size);
+ void *buf = xmalloc(size ? size : 1);
memset(&stream, 0, sizeof(stream));
--
1.0.GIT
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-26 18:16 ` [PATCH] Avoid allocating 0 bytes, was " Johannes Schindelin
@ 2005-12-26 19:10 ` Junio C Hamano
2005-12-26 20:34 ` Johannes Schindelin
2005-12-30 23:00 ` Eric Wong
1 sibling, 1 reply; 24+ messages in thread
From: Junio C Hamano @ 2005-12-26 19:10 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Eric Wong, git
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> This is the result of a relatively quick audit of the source code. There
> might still be a few odd places lurking out there, but I am quite certain
> I caught most if not all.
Thanks.
> 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?
> 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.
> @@ -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.
> @@ -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 ;-).
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?).
- 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;
}
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-26 19:10 ` Junio C Hamano
@ 2005-12-26 20:34 ` Johannes Schindelin
2005-12-26 22:03 ` [PATCH] avoid asking ?alloc() for zero bytes Junio C Hamano
2005-12-28 20:38 ` [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc} Johannes Schindelin
0 siblings, 2 replies; 24+ messages in thread
From: Johannes Schindelin @ 2005-12-26 20:34 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Eric Wong, git
Hi,
On Mon, 26 Dec 2005, Junio C Hamano wrote:
> 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.
> > 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.
> > @@ -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.
> > @@ -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.
> 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.
> - 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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH] avoid asking ?alloc() for zero bytes.
2005-12-26 20:34 ` Johannes Schindelin
@ 2005-12-26 22:03 ` Junio C Hamano
2005-12-26 22:18 ` Johannes Schindelin
2005-12-28 20:38 ` [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc} Johannes Schindelin
1 sibling, 1 reply; 24+ messages in thread
From: Junio C Hamano @ 2005-12-26 22:03 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Eric Wong, git
Avoid asking for zero bytes when that change simplifies overall
logic. Later we would change the wrapper to ask for 1 byte on
platforms that return NULL for zero byte request.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
* Here is what I have now that roughly corresponds to your
patch, which has been somewhat tested.
The final phase of making sure we return something from
x*alloc() is not done yet.
diff.c | 6 +++---
diffcore-order.c | 6 +++++-
diffcore-pathspec.c | 3 +++
index-pack.c | 22 ++++++++++++++--------
read-tree.c | 17 ++++++++++-------
tree-diff.c | 4 ++++
6 files changed, 39 insertions(+), 19 deletions(-)
da95c79803d90ce8eaf82b0c04dbde11c096ad87
diff --git a/diff.c b/diff.c
index c815918..bfc864d 100644
--- a/diff.c
+++ b/diff.c
@@ -504,9 +504,9 @@ static void prepare_temp_file(const char
}
if (S_ISLNK(st.st_mode)) {
int ret;
- char *buf, buf_[1024];
- buf = ((sizeof(buf_) < st.st_size) ?
- xmalloc(st.st_size) : buf_);
+ char buf[PATH_MAX + 1]; /* ought to be SYMLINK_MAX */
+ if (sizeof(buf) <= st.st_size)
+ die("symlink too long: %s", name);
ret = readlink(name, buf, st.st_size);
if (ret < 0)
die("readlink(%s)", name);
diff --git a/diffcore-order.c b/diffcore-order.c
index b381223..0bc2b22 100644
--- a/diffcore-order.c
+++ b/diffcore-order.c
@@ -105,9 +105,13 @@ static int compare_pair_order(const void
void diffcore_order(const char *orderfile)
{
struct diff_queue_struct *q = &diff_queued_diff;
- struct pair_order *o = xmalloc(sizeof(*o) * q->nr);
+ struct pair_order *o;
int i;
+ if (!q->nr)
+ return;
+
+ o = xmalloc(sizeof(*o) * q->nr);
prepare_order(orderfile);
for (i = 0; i < q->nr; i++) {
o[i].pair = q->queue[i];
diff --git a/diffcore-pathspec.c b/diffcore-pathspec.c
index 68fe009..139fe88 100644
--- a/diffcore-pathspec.c
+++ b/diffcore-pathspec.c
@@ -48,6 +48,9 @@ void diffcore_pathspec(const char **path
for (i = 0; pathspec[i]; i++)
;
speccnt = i;
+ if (!speccnt)
+ return;
+
spec = xmalloc(sizeof(*spec) * speccnt);
for (i = 0; pathspec[i]; i++) {
spec[i].spec = pathspec[i];
diff --git a/index-pack.c b/index-pack.c
index d4ce3af..541d7bc 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -352,18 +352,24 @@ static int sha1_compare(const void *_a,
static void write_index_file(const char *index_name, unsigned char *sha1)
{
struct sha1file *f;
- struct object_entry **sorted_by_sha =
- xcalloc(nr_objects, sizeof(struct object_entry *));
- struct object_entry **list = sorted_by_sha;
- struct object_entry **last = sorted_by_sha + nr_objects;
+ struct object_entry **sorted_by_sha, **list, **last;
unsigned int array[256];
int i;
SHA_CTX ctx;
- for (i = 0; i < nr_objects; ++i)
- sorted_by_sha[i] = &objects[i];
- qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
- sha1_compare);
+ if (nr_objects) {
+ sorted_by_sha =
+ xcalloc(nr_objects, sizeof(struct object_entry *));
+ list = sorted_by_sha;
+ last = sorted_by_sha + nr_objects;
+ for (i = 0; i < nr_objects; ++i)
+ sorted_by_sha[i] = &objects[i];
+ qsort(sorted_by_sha, nr_objects, sizeof(sorted_by_sha[0]),
+ sha1_compare);
+
+ }
+ else
+ sorted_by_sha = list = last = NULL;
unlink(index_name);
f = sha1create("%s", index_name);
diff --git a/read-tree.c b/read-tree.c
index e3b9c0d..a46c6fe 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -294,17 +294,20 @@ static int unpack_trees(merge_fn_t fn)
{
int indpos = 0;
unsigned len = object_list_length(trees);
- struct tree_entry_list **posns =
- xmalloc(len * sizeof(struct tree_entry_list *));
+ struct tree_entry_list **posns;
int i;
struct object_list *posn = trees;
merge_size = len;
- for (i = 0; i < len; i++) {
- posns[i] = ((struct tree *) posn->item)->entries;
- posn = posn->next;
+
+ if (len) {
+ posns = xmalloc(len * sizeof(struct tree_entry_list *));
+ for (i = 0; i < len; i++) {
+ posns[i] = ((struct tree *) posn->item)->entries;
+ posn = posn->next;
+ }
+ if (unpack_trees_rec(posns, len, "", fn, &indpos))
+ return -1;
}
- if (unpack_trees_rec(posns, len, "", fn, &indpos))
- return -1;
if (trivial_merges_only && nontrivial_merge)
die("Merge requires file-level merging");
diff --git a/tree-diff.c b/tree-diff.c
index 0ef06a9..382092b 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -263,6 +263,10 @@ void diff_tree_setup_paths(const char **
paths = p;
nr_paths = count_paths(paths);
+ if (nr_paths == 0) {
+ pathlens = NULL;
+ return;
+ }
pathlens = xmalloc(nr_paths * sizeof(int));
for (i=0; i<nr_paths; i++)
pathlens[i] = strlen(paths[i]);
--
1.0.GIT
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH] avoid asking ?alloc() for zero bytes.
2005-12-26 22:03 ` [PATCH] avoid asking ?alloc() for zero bytes Junio C Hamano
@ 2005-12-26 22:18 ` Johannes Schindelin
0 siblings, 0 replies; 24+ messages in thread
From: Johannes Schindelin @ 2005-12-26 22:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Eric Wong, git
Hi,
On Mon, 26 Dec 2005, Junio C Hamano wrote:
> Avoid asking for zero bytes when that change simplifies overall
> logic. Later we would change the wrapper to ask for 1 byte on
> platforms that return NULL for zero byte request.
>
> Signed-off-by: Junio C Hamano <junkio@cox.net>
>
> ---
>
> * Here is what I have now that roughly corresponds to your
> patch, which has been somewhat tested.
Thanks.
> The final phase of making sure we return something from
> x*alloc() is not done yet.
Tomorrow I'll compare the two patches and find out what, if anything, is
needed.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes
2005-12-24 12:12 ` [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes Eric Wong
2005-12-24 12:44 ` Johannes Schindelin
@ 2005-12-28 4:22 ` H. Peter Anvin
2005-12-28 4:38 ` Linus Torvalds
1 sibling, 1 reply; 24+ messages in thread
From: H. Peter Anvin @ 2005-12-28 4:22 UTC (permalink / raw)
To: Eric Wong; +Cc: git list
Eric Wong wrote:
> dietlibc versions of malloc, calloc and realloc all return NULL if
> they're told to allocate 0 bytes, causes the x* wrappers to die().
>
> There are several more places where these calls could end up asking
> for 0 bytes, too...
>
> Maybe simply not die()-ing in the x* wrappers if 0/NULL is returned
> when the requested size is zero is a safer and easier way to go.
>
Better yet, either always return NULL or allocate 1 byte in that case,
to get consistent behaviour.
-hpa
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes
2005-12-28 4:22 ` H. Peter Anvin
@ 2005-12-28 4:38 ` Linus Torvalds
2005-12-28 5:07 ` Junio C Hamano
2005-12-28 16:58 ` H. Peter Anvin
0 siblings, 2 replies; 24+ messages in thread
From: Linus Torvalds @ 2005-12-28 4:38 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Eric Wong, git list
On Tue, 27 Dec 2005, H. Peter Anvin wrote:
>
> Better yet, either always return NULL or allocate 1 byte in that case, to get
> consistent behaviour.
Yes. However, if you do the "return NULL" case (which is nicest), you'll
have to wrap "free()" too. There are some libraries where passing "free()"
a NULL pointer causes a SIGSEGV.
That said, I think that would be preferable to changing the source code to
unnecessarily avoid zero-sized allocations. Having a "xfree()" to match
"xmalloc()" makes sense.
Linus
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes
2005-12-28 4:38 ` Linus Torvalds
@ 2005-12-28 5:07 ` Junio C Hamano
2005-12-28 16:58 ` H. Peter Anvin
1 sibling, 0 replies; 24+ messages in thread
From: Junio C Hamano @ 2005-12-28 5:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
Linus Torvalds <torvalds@osdl.org> writes:
> That said, I think that would be preferable to changing the source code to
> unnecessarily avoid zero-sized allocations.
Yes, that has essentially been the plan (according to the
discussion lead to 7e4a2a848377241b8fb4f624d1151bbf2f8d5814
commit on the list).
After eradicating zero-sized allocations where that change makes
the overall code cleaner (which Johannes and Eric did most of
the heavylifting and I think mostly done), we would apply
something like this, instead of doing x*alloc(size ? size : 1)
at the calling site.
About die(), I think the current code structure is fine. If we
were doing a library, propagating NULL from C library *alloc()
back to our caller and having the caller deal with it is the
right thing, but most of the callers of x*alloc() are our main
programs and there aren't much they can do when we run out of
memory.
---
diff --git a/git-compat-util.h b/git-compat-util.h
index 0c98c99..a71728e 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -63,6 +63,8 @@ extern char *gitstrcasestr(const char *h
static inline void *xmalloc(size_t size)
{
void *ret = malloc(size);
+ if (!ret && !size)
+ ret = malloc(1); /* funny c library */
if (!ret)
die("Out of memory, malloc failed");
return ret;
@@ -71,6 +73,8 @@ static inline void *xmalloc(size_t size)
static inline void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
+ if (!ret && !size)
+ ret = realloc(ptr, 1); /* funny c library */
if (!ret)
die("Out of memory, realloc failed");
return ret;
@@ -79,6 +83,8 @@ static inline void *xrealloc(void *ptr,
static inline void *xcalloc(size_t nmemb, size_t size)
{
void *ret = calloc(nmemb, size);
+ if (!ret && (!nmemb || !size))
+ ret = calloc(1, 1); /* funny c library */
if (!ret)
die("Out of memory, calloc failed");
return ret;
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes
2005-12-28 4:38 ` Linus Torvalds
2005-12-28 5:07 ` Junio C Hamano
@ 2005-12-28 16:58 ` H. Peter Anvin
1 sibling, 0 replies; 24+ messages in thread
From: H. Peter Anvin @ 2005-12-28 16:58 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Eric Wong, git list
Linus Torvalds wrote:
>
> On Tue, 27 Dec 2005, H. Peter Anvin wrote:
>
>>Better yet, either always return NULL or allocate 1 byte in that case, to get
>>consistent behaviour.
>
> Yes. However, if you do the "return NULL" case (which is nicest), you'll
> have to wrap "free()" too. There are some libraries where passing "free()"
> a NULL pointer causes a SIGSEGV.
>
> That said, I think that would be preferable to changing the source code to
> unnecessarily avoid zero-sized allocations. Having a "xfree()" to match
> "xmalloc()" makes sense.
>
Yeah, although that might break GNU code which uses xmalloc that is
included (GNU doesn't have xfree.) The easiest is just to allocate 1
byte when the user asks for 0.
Anyone knows what GNU xmalloc does?
-hpa
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-26 20:34 ` Johannes Schindelin
2005-12-26 22:03 ` [PATCH] avoid asking ?alloc() for zero bytes Junio C Hamano
@ 2005-12-28 20:38 ` Johannes Schindelin
1 sibling, 0 replies; 24+ messages in thread
From: Johannes Schindelin @ 2005-12-28 20:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Eric Wong, git
Hi,
On Mon, 26 Dec 2005, Johannes Schindelin wrote:
> On Mon, 26 Dec 2005, Junio C Hamano wrote:
>
> > 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.
Now I did. To make a long story short: this patch is wrong, wrong, wrong.
Further, I think it is safe to assume that deflateBound() returns > 0.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc}
2005-12-26 18:16 ` [PATCH] Avoid allocating 0 bytes, was " Johannes Schindelin
2005-12-26 19:10 ` Junio C Hamano
@ 2005-12-30 23:00 ` Eric Wong
1 sibling, 0 replies; 24+ messages in thread
From: Eric Wong @ 2005-12-30 23:00 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> diff --git a/index-pack.c b/index-pack.c
> index d4ce3af..2927632 100644
> --- a/index-pack.c
> +++ b/index-pack.c
> @@ -103,7 +103,7 @@ static void *unpack_entry_data(unsigned
> unsigned long pack_limit = pack_size - 20;
> unsigned long pos = *current_pos;
> z_stream stream;
> - void *buf = xmalloc(size);
> + void *buf = xmalloc(size ? size : 1);
>
> memset(&stream, 0, sizeof(stream));
> stream.next_out = buf;
This is the only one I've managed to hit upon further use the past week
of usage. No way to break out of the function, either, because
current_pos needs to be updated (and it is changed despite a zero-byte
blob object being in my repository).
--
Eric Wong
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2005-12-30 23:01 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-24 12:10 [PATCH 0/4] dietlibc compatibility Eric Wong
2005-12-24 12:11 ` [PATCH 1/4] git.c: extra #include for dietlibc (and possibly other C libraries) Eric Wong
2005-12-26 17:01 ` Junio C Hamano
2005-12-24 12:12 ` [PATCH 2/4] short circuit out of a few places where we would allocate zero bytes Eric Wong
2005-12-24 12:44 ` Johannes Schindelin
2005-12-28 4:22 ` H. Peter Anvin
2005-12-28 4:38 ` Linus Torvalds
2005-12-28 5:07 ` Junio C Hamano
2005-12-28 16:58 ` H. Peter Anvin
2005-12-24 12:13 ` [PATCH 3/4] add xmktime() function that always accounts for the TZ env Eric Wong
2005-12-24 12:45 ` Johannes Schindelin
2005-12-24 19:18 ` Junio C Hamano
2005-12-24 19:52 ` Eric Wong
2005-12-24 21:10 ` Junio C Hamano
2005-12-24 12:14 ` [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc} Eric Wong
2005-12-24 18:28 ` Junio C Hamano
2005-12-24 21:15 ` Eric Wong
2005-12-26 18:16 ` [PATCH] Avoid allocating 0 bytes, was " Johannes Schindelin
2005-12-26 19:10 ` Junio C Hamano
2005-12-26 20:34 ` Johannes Schindelin
2005-12-26 22:03 ` [PATCH] avoid asking ?alloc() for zero bytes Junio C Hamano
2005-12-26 22:18 ` Johannes Schindelin
2005-12-28 20:38 ` [PATCH] Avoid allocating 0 bytes, was Re: [PATCH 4/4] git-compat-util.h: dietlibc-friendly x{malloc,realloc,calloc} Johannes Schindelin
2005-12-30 23:00 ` Eric Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).