This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix two bugs in argz


Ok. When you get a chance, could you check into the XPDF problem reported for newlib on Cygwin and see if it was caused by the recent math changes (e.g. atan2) which change the behavior to match glibc.

Thanks,

-- Jeff J.

Corinna Vinschen wrote:
Corinna Vinschen wrote:
[...]
* libc/argz/argz_create_sep.c (argz_create_sep): Initialize *argz_len
to zero.
* libc/include/argz.h: Guard against multiple inclusion. Guard for
use with C++.
Thanks, applied.

More problems with argz:


- Per the glibc documentation, (NULL, 0) is a valid argz vector.  For
  instance, glibc's argz_create_sep returns an (argz, argz_len) vector
  of (NULL, 0) if the input string is empty, while newlib's
  argz_create_sep returns ("", 1) instead of (NULL, 0).  Newlib doesn't
  handle the (NULL, 0) vector always correctly.  The below patch is
  supposed to fix that.

- argz_extract has a subtil bug.  Consider the above case where the
  (argz, argz_len) vector is ("", 1).  This is a valid value, one empty
  argument.  When calling argz_extract on that vector, the loop counter
  variable i is initialized to argz_len - 2, which is -1 in this case.
  The problem is, i is of type size_t, which is an *unsigned* type.  So,
  actually i gets initialized to 4294967295 and the loop invariably
  crashes at one point, accessing invalid memory addresses.


Fix below. Ok to apply?



Corinna


	* libc/argz/argz_add_sep.c (argz_add_sep): Handle empty string
	argument.
	* libc/argz/argz_append.c (argz_append): Handle empty buf argument.
	* libc/argz/argz_create_sep.c (argz_create_sep): Return (NULL, 0)
	on empty input strings.
	* libc/argz/argz_extract.c (argz_extract): Check argz_len before
	looping through argz.
	* libc/argz/argz_stringify.c (argz_stringify): Ditto.


Index: libc/argz/argz_add_sep.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/argz/argz_add_sep.c,v
retrieving revision 1.2
diff -u -p -r1.2 argz_add_sep.c
--- libc/argz/argz_add_sep.c 6 Jun 2003 19:57:51 -0000 1.2
+++ libc/argz/argz_add_sep.c 24 May 2007 12:35:11 -0000
@@ -23,11 +23,14 @@ _DEFUN (argz_add_sep, (argz, argz_len, s
argz_create_sep (str, sep, &str_argz, &str_argz_len);
- *argz_len += str_argz_len;
+ if (str_argz_len)
+ {
+ *argz_len += str_argz_len;
- if(!(*argz = (char *)realloc(*argz, *argz_len)))
- return ENOMEM;
+ if(!(*argz = (char *)realloc(*argz, *argz_len)))
+ return ENOMEM;
- memcpy(*argz + last, str_argz, str_argz_len);
+ memcpy(*argz + last, str_argz, str_argz_len);
+ }
return 0;
}
Index: libc/argz/argz_append.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/argz/argz_append.c,v
retrieving revision 1.2
diff -u -p -r1.2 argz_append.c
--- libc/argz/argz_append.c 6 Jun 2003 19:57:51 -0000 1.2
+++ libc/argz/argz_append.c 24 May 2007 12:35:11 -0000
@@ -16,13 +16,16 @@ _DEFUN (argz_append, (argz, argz_len, bu
const char *buf _AND
size_t buf_len)
{
- size_t last = *argz_len;
+ if (buf_len)
+ {
+ size_t last = *argz_len;
- *argz_len += buf_len;
+ *argz_len += buf_len;
- if(!(*argz = (char *)realloc(*argz, *argz_len)))
- return ENOMEM;
+ if(!(*argz = (char *)realloc(*argz, *argz_len)))
+ return ENOMEM;
- memcpy(*argz + last, buf, buf_len);
+ memcpy(*argz + last, buf, buf_len);
+ }
return 0;
}
Index: libc/argz/argz_create_sep.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/argz/argz_create_sep.c,v
retrieving revision 1.3
diff -u -p -r1.3 argz_create_sep.c
--- libc/argz/argz_create_sep.c 23 May 2007 16:36:22 -0000 1.3
+++ libc/argz/argz_create_sep.c 24 May 2007 12:35:11 -0000
@@ -25,13 +25,21 @@ _DEFUN (argz_create_sep, (string, sep, a
char *token = 0;
char *iter = 0;
+ *argz_len = 0;
+
+ if (!string || string[0] == '\0')
+ {
+ *argz= NULL;
+ *argz_len = 0;
+ return 0;
+ }
+
delim[0] = sep;
delim[1] = '\0';
running = strdup(string);
old_running = running;
- *argz_len = 0;
while ((token = strsep(&running, delim)))
{
len = strlen(token);
Index: libc/argz/argz_extract.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/argz/argz_extract.c,v
retrieving revision 1.2
diff -u -p -r1.2 argz_extract.c
--- libc/argz/argz_extract.c 6 Jun 2003 19:57:51 -0000 1.2
+++ libc/argz/argz_extract.c 24 May 2007 12:35:11 -0000
@@ -17,14 +17,15 @@ _DEFUN (argz_extract, (argz, argz_len, a
int j = 0;
const size_t count = argz_count(argz, argz_len);
- for (i = argz_len - 2; i > 0; i--)
- {
- if (argz[i] == '\0')
- {
- j++;
- argv[count - j] = &argz[i + 1];
- }
- }
+ if (argz_len > 1)
+ for (i = argz_len - 2; i > 0; i--)
+ {
+ if (argz[i] == '\0')
+ {
+ j++;
+ argv[count - j] = &argz[i + 1];
+ }
+ }
argv[0] = &argz[0];
argv[count] = NULL;
}
Index: libc/argz/argz_stringify.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/argz/argz_stringify.c,v
retrieving revision 1.2
diff -u -p -r1.2 argz_stringify.c
--- libc/argz/argz_stringify.c 6 Jun 2003 19:57:51 -0000 1.2
+++ libc/argz/argz_stringify.c 24 May 2007 12:35:11 -0000
@@ -16,9 +16,10 @@ _DEFUN (argz_stringify, (argz, argz_len,
size_t i;
/* len includes trailing \0, which we don't want to replace. */
- for (i = 0; i < argz_len - 1; i++)
- {
- if (argz[i] == '\0')
- argz[i] = sep;
- }
+ if (argz_len > 1)
+ for (i = 0; i < argz_len - 1; i++)
+ {
+ if (argz[i] == '\0')
+ argz[i] = sep;
+ }
}





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]