2007-03-16 Charles Wilson <cygwin@...>
* libc/argz/argz_insert.c: before pointer is
invalid after *argz realloc. Compute offset
between before and *argz, and use it after
reallocation instead.
A little algebra should demonstrate the correctness of this patch.
given:
delta = before - *argz
then:
before = *argz + delta
therefore:
memmove(before + len, -> *argz + delta + len,
before, -> *argz + delta,
*argz + *argz_len - before ->
*argz + *argz_len - *argz - delta ->
*argz_len - delta
);
memcpy(before, -> *argz + delta
entry,
len
);
For a more thorough description, see:
http://cygwin.com/ml/cygwin/2007-03/msg00533.html
--
Chuck
------------------------------------------------------------------------
Index: libc/argz/argz_insert.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/argz/argz_insert.c,v
retrieving revision 1.3
diff -u -r1.3 argz_insert.c
--- libc/argz/argz_insert.c 8 Sep 2005 21:07:43 -0000 1.3
+++ libc/argz/argz_insert.c 16 Mar 2007 20:00:11 -0000
@@ -28,13 +28,16 @@
while (before != *argz && before[-1])
before--;
+ /* delta will always be non-negative, and < *argz_len */
+ ptrdiff_t delta = before - *argz;
+
len = strlen(entry) + 1;
if(!(*argz = (char *)realloc(*argz, *argz_len + len)))
return ENOMEM;
- memmove(before + len, before, *argz + *argz_len - before);
- memcpy(before, entry, len);
+ memmove(*argz + delta + len, *argz + delta, *argz_len - delta);
+ memcpy(*argz + delta, entry, len);
*argz_len += len;