All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 1/5] Make xstrndup common
@ 2007-04-28 18:53 Josh Triplett
  2007-04-28 22:47 ` Junio C Hamano
  2007-04-29 18:19 ` Daniel Barkalow
  0 siblings, 2 replies; 10+ messages in thread
From: Josh Triplett @ 2007-04-28 18:53 UTC (permalink / raw)
  To: git; +Cc: Daniel Barkalow

[-- Attachment #1: Type: text/plain, Size: 653 bytes --]

Daniel Barkalow wrote:
> It was implemented in commit.c; move it with the other x memory functions.
[...]
> +static inline char *xstrndup(const char *str, int len)
> +{
> +	char *ret = xmalloc(len + 1);
> +	memcpy(ret, str, len);
> +	ret[len] = '\0';
> +	return ret;
> +}
> +

I don't know if it matters, but this definition of xstrndup, like the version
in commit.c, doesn't match the definition of strndup.  strndup duplicates a
string, copying up to n characters or the length of the string.  This xstrndup
always copies n characters, reading past the end of the string if it doesn't
have at least n characters.

- Josh Triplett


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-28 18:53 [PATCH 1/5] Make xstrndup common Josh Triplett
@ 2007-04-28 22:47 ` Junio C Hamano
  2007-04-29 18:19 ` Daniel Barkalow
  1 sibling, 0 replies; 10+ messages in thread
From: Junio C Hamano @ 2007-04-28 22:47 UTC (permalink / raw)
  To: Josh Triplett; +Cc: git, Daniel Barkalow

Josh Triplett <josh@freedesktop.org> writes:

> Daniel Barkalow wrote:
>> It was implemented in commit.c; move it with the other x memory functions.
> [...]
>> +static inline char *xstrndup(const char *str, int len)
>> +{
>> +	char *ret = xmalloc(len + 1);
>> +	memcpy(ret, str, len);
>> +	ret[len] = '\0';
>> +	return ret;
>> +}
>> +
>
> I don't know if it matters, but this definition of xstrndup, like the version
> in commit.c, doesn't match the definition of strndup.  strndup duplicates a
> string, copying up to n characters or the length of the string.  This xstrndup
> always copies n characters, reading past the end of the string if it doesn't
> have at least n characters.

Very well caught indeed, thanks.  In the original context in
commit.c, this function is always given length computed by
inspecting the source text by the caller, so the code was
correct, but if we are making it available as a general utility
routine, we probably cannot depend on that assumption anymore.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-28 18:53 [PATCH 1/5] Make xstrndup common Josh Triplett
  2007-04-28 22:47 ` Junio C Hamano
@ 2007-04-29 18:19 ` Daniel Barkalow
  2007-04-29 20:29   ` Josh Triplett
  1 sibling, 1 reply; 10+ messages in thread
From: Daniel Barkalow @ 2007-04-29 18:19 UTC (permalink / raw)
  To: Josh Triplett; +Cc: git

On Sat, 28 Apr 2007, Josh Triplett wrote:

> Daniel Barkalow wrote:
> > It was implemented in commit.c; move it with the other x memory functions.
> [...]
> > +static inline char *xstrndup(const char *str, int len)
> > +{
> > +	char *ret = xmalloc(len + 1);
> > +	memcpy(ret, str, len);
> > +	ret[len] = '\0';
> > +	return ret;
> > +}
> > +
> 
> I don't know if it matters, but this definition of xstrndup, like the version
> in commit.c, doesn't match the definition of strndup.  strndup duplicates a
> string, copying up to n characters or the length of the string.  This xstrndup
> always copies n characters, reading past the end of the string if it doesn't
> have at least n characters.

Good catch. Replacing the memcpy with strncpy solves this, right? 
(Potentially allocating a bit of extra memory if someone is actually using 
it on too short a string for some reason, of course).

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-29 18:19 ` Daniel Barkalow
@ 2007-04-29 20:29   ` Josh Triplett
  2007-04-29 20:39     ` Junio C Hamano
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Josh Triplett @ 2007-04-29 20:29 UTC (permalink / raw)
  To: Daniel Barkalow; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 1604 bytes --]

Daniel Barkalow wrote:
> On Sat, 28 Apr 2007, Josh Triplett wrote:
>> Daniel Barkalow wrote:
>>> It was implemented in commit.c; move it with the other x memory functions.
>> [...]
>>> +static inline char *xstrndup(const char *str, int len)
>>> +{
>>> +	char *ret = xmalloc(len + 1);
>>> +	memcpy(ret, str, len);
>>> +	ret[len] = '\0';
>>> +	return ret;
>>> +}
>>> +
>> I don't know if it matters, but this definition of xstrndup, like the version
>> in commit.c, doesn't match the definition of strndup.  strndup duplicates a
>> string, copying up to n characters or the length of the string.  This xstrndup
>> always copies n characters, reading past the end of the string if it doesn't
>> have at least n characters.
> 
> Good catch. Replacing the memcpy with strncpy solves this, right? 
> (Potentially allocating a bit of extra memory if someone is actually using 
> it on too short a string for some reason, of course).

That would work, but it seems bad to allocate excess memory.  How about just
using strlen and setting len to that if shorter, before doing the xmalloc and
memcpy?  Yes, that makes two passes over the string, but I don't see any way
around that.

I just checked the glibc source for strndup, and it does exactly the same
thing, except that it uses the glibc-specific function strnlen rather than
using strlen and figuring out the smaller of the two lengths.  That probably
increases efficiency if we have a string longer than, but we can't portably
use strnlen, so we'd have to check for it; doesn't seem worth the trouble.

- Josh Triplett


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-29 20:29   ` Josh Triplett
@ 2007-04-29 20:39     ` Junio C Hamano
  2007-04-29 20:40     ` Adam Roben
  2007-04-30 13:12     ` Johannes Schindelin
  2 siblings, 0 replies; 10+ messages in thread
From: Junio C Hamano @ 2007-04-29 20:39 UTC (permalink / raw)
  To: Josh Triplett; +Cc: Daniel Barkalow, git

Josh Triplett <josh@freedesktop.org> writes:

> Daniel Barkalow wrote:
> ...
>> Good catch. Replacing the memcpy with strncpy solves this, right? 
>> (Potentially allocating a bit of extra memory if someone is actually using 
>> it on too short a string for some reason, of course).
>
> That would work, but it seems bad to allocate excess memory.  How about just
> using strlen and setting len to that if shorter, before doing the xmalloc and
> memcpy?  Yes, that makes two passes over the string, but I don't see any way
> around that.

Hand-rolling strnlen() would be needed anyway, because there is
no guarantee that the incoming string is NUL terminated.  In the
worst case the string may point at a region of memory filled
with non-NUL to the end, which coincides with a page boundary,
and the next page may be an unmapped one; your strlen() would
sigbus.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-29 20:29   ` Josh Triplett
  2007-04-29 20:39     ` Junio C Hamano
@ 2007-04-29 20:40     ` Adam Roben
  2007-04-30 13:12     ` Johannes Schindelin
  2 siblings, 0 replies; 10+ messages in thread
From: Adam Roben @ 2007-04-29 20:40 UTC (permalink / raw)
  To: Josh Triplett; +Cc: Daniel Barkalow, git

On Apr 29, 2007, at 1:29 PM, Josh Triplett wrote:

> Daniel Barkalow wrote:
>> On Sat, 28 Apr 2007, Josh Triplett wrote:
>>> Daniel Barkalow wrote:
>>>> It was implemented in commit.c; move it with the other x memory  
>>>> functions.
>>> [...]
>>>> +static inline char *xstrndup(const char *str, int len)
>>>> +{
>>>> +	char *ret = xmalloc(len + 1);
>>>> +	memcpy(ret, str, len);
>>>> +	ret[len] = '\0';
>>>> +	return ret;
>>>> +}
>>>> +
>>> I don't know if it matters, but this definition of xstrndup, like  
>>> the version
>>> in commit.c, doesn't match the definition of strndup.  strndup  
>>> duplicates a
>>> string, copying up to n characters or the length of the string.   
>>> This xstrndup
>>> always copies n characters, reading past the end of the string if  
>>> it doesn't
>>> have at least n characters.
>>
>> Good catch. Replacing the memcpy with strncpy solves this, right?
>> (Potentially allocating a bit of extra memory if someone is  
>> actually using
>> it on too short a string for some reason, of course).
>
> That would work, but it seems bad to allocate excess memory.  How  
> about just
> using strlen and setting len to that if shorter, before doing the  
> xmalloc and
> memcpy?  Yes, that makes two passes over the string, but I don't  
> see any way
> around that.

    An easy way around that is to do the string copy yourself,  
walking the string until you either find '\0' or reach len copied  
characters.

-Adam

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-29 20:29   ` Josh Triplett
  2007-04-29 20:39     ` Junio C Hamano
  2007-04-29 20:40     ` Adam Roben
@ 2007-04-30 13:12     ` Johannes Schindelin
  2007-04-30 20:50       ` Jeff King
  2 siblings, 1 reply; 10+ messages in thread
From: Johannes Schindelin @ 2007-04-30 13:12 UTC (permalink / raw)
  To: Josh Triplett; +Cc: Daniel Barkalow, git

Hi,

On Sun, 29 Apr 2007, Josh Triplett wrote:

> Daniel Barkalow wrote:
> > On Sat, 28 Apr 2007, Josh Triplett wrote:
> >> Daniel Barkalow wrote:
> >>> It was implemented in commit.c; move it with the other x memory functions.
> >> [...]
> >>> +static inline char *xstrndup(const char *str, int len)
> >>> +{
> >>> +	char *ret = xmalloc(len + 1);
> >>> +	memcpy(ret, str, len);
> >>> +	ret[len] = '\0';
> >>> +	return ret;
> >>> +}
> >>> +
> >> I don't know if it matters, but this definition of xstrndup, like the 
> >> version in commit.c, doesn't match the definition of strndup.  
> >> strndup duplicates a string, copying up to n characters or the length 
> >> of the string.  This xstrndup always copies n characters, reading 
> >> past the end of the string if it doesn't have at least n characters.
> > 
> > Good catch. Replacing the memcpy with strncpy solves this, right? 
> > (Potentially allocating a bit of extra memory if someone is actually 
> > using it on too short a string for some reason, of course).
> 
> That would work, but it seems bad to allocate excess memory.  How about 
> just using strlen and setting len to that if shorter, before doing the 
> xmalloc and memcpy?  Yes, that makes two passes over the string, but I 
> don't see any way around that.

Unless I am missing something, I think this should work:

static inline char *xstrndup(const char *str, int len)
{
	char *result = strndup(str, len);
	if (result == NULL)
		die ("xstrndup(): out of memory");
	return result;
}

Hmm?

Ciao,
Dscho

P.S.: If you feel real paranoid about it, you might insert

	if (result == NULL) {
		release_pack_memory(len, -1);
		result = strndup(str, len);
	}

before the if (...), but I think that's overkill.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-30 13:12     ` Johannes Schindelin
@ 2007-04-30 20:50       ` Jeff King
  2007-04-30 22:21         ` Johannes Schindelin
  0 siblings, 1 reply; 10+ messages in thread
From: Jeff King @ 2007-04-30 20:50 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Josh Triplett, Daniel Barkalow, git

On Mon, Apr 30, 2007 at 03:12:50PM +0200, Johannes Schindelin wrote:

> Unless I am missing something, I think this should work:
> 
> static inline char *xstrndup(const char *str, int len)
> {
> 	char *result = strndup(str, len);
> 	if (result == NULL)
> 		die ("xstrndup(): out of memory");
> 	return result;
> }
> 
> Hmm?

I can't speak for the original authors, but I imagine part of the
impetus was that strndup is a GNU-ism.

-Peff

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] Make xstrndup common
  2007-04-30 20:50       ` Jeff King
@ 2007-04-30 22:21         ` Johannes Schindelin
  0 siblings, 0 replies; 10+ messages in thread
From: Johannes Schindelin @ 2007-04-30 22:21 UTC (permalink / raw)
  To: Jeff King; +Cc: Josh Triplett, Daniel Barkalow, git

Hi,

On Mon, 30 Apr 2007, Jeff King wrote:

> On Mon, Apr 30, 2007 at 03:12:50PM +0200, Johannes Schindelin wrote:
> 
> > Unless I am missing something, I think this should work:
> > 
> > static inline char *xstrndup(const char *str, int len)
> > {
> > 	char *result = strndup(str, len);
> > 	if (result == NULL)
> > 		die ("xstrndup(): out of memory");
> > 	return result;
> > }
> > 
> > Hmm?
> 
> I can't speak for the original authors, but I imagine part of the
> impetus was that strndup is a GNU-ism.

D'oh! I never thought this was a GNU-ism.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] Make xstrndup common
@ 2007-04-28 17:05 Daniel Barkalow
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Barkalow @ 2007-04-28 17:05 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

It was implemented in commit.c; move it with the other x memory functions.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 commit.c          |    8 --------
 git-compat-util.h |    8 ++++++++
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/commit.c b/commit.c
index f1ba972..aa7059c 100644
--- a/commit.c
+++ b/commit.c
@@ -718,14 +718,6 @@ static char *logmsg_reencode(const struct commit *commit,
 	return out;
 }
 
-static char *xstrndup(const char *text, int len)
-{
-	char *result = xmalloc(len + 1);
-	memcpy(result, text, len);
-	result[len] = '\0';
-	return result;
-}
-
 static void fill_person(struct interp *table, const char *msg, int len)
 {
 	int start, end, tz = 0;
diff --git a/git-compat-util.h b/git-compat-util.h
index 2c84016..615c353 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -197,6 +197,14 @@ static inline void *xmalloc(size_t size)
 	return ret;
 }
 
+static inline char *xstrndup(const char *str, int len)
+{
+	char *ret = xmalloc(len + 1);
+	memcpy(ret, str, len);
+	ret[len] = '\0';
+	return ret;
+}
+
 static inline void *xrealloc(void *ptr, size_t size)
 {
 	void *ret = realloc(ptr, size);
-- 
1.5.1.2.255.g6ead4-dirty

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-04-30 22:22 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-28 18:53 [PATCH 1/5] Make xstrndup common Josh Triplett
2007-04-28 22:47 ` Junio C Hamano
2007-04-29 18:19 ` Daniel Barkalow
2007-04-29 20:29   ` Josh Triplett
2007-04-29 20:39     ` Junio C Hamano
2007-04-29 20:40     ` Adam Roben
2007-04-30 13:12     ` Johannes Schindelin
2007-04-30 20:50       ` Jeff King
2007-04-30 22:21         ` Johannes Schindelin
  -- strict thread matches above, loose matches on Subject: below --
2007-04-28 17:05 Daniel Barkalow

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.