On Sun, Mar 09, 2008 at 08:27:25PM -0400, Jeff Johnson wrote:
> Using xmalloc just opens up a can-of-worms while lusers fuss about
> non-gcc compiler extension portability.

Aha, I had failed to notice that the "? :" bit was a gcc extension.

What I don't like is that normal users get some memory functions that
are fatal if they use gcc, while all others get non-fatal functions.
Perhaps the default should be for all normal compiles to get the non-
fatal functions, and then anyone that wanted to use the current gcc
defines could set something extra (such as -DFATAL_MEM).

One other reason I care about this is that I think the various bits of
code that are doing a strdup()-like action should be using a strdup()-
like call, not each one having their own set of strlen/malloc/strcpy
calls.  It's clearer and a bit safer.

I'm attaching a patch that adds the extra FATAL_MEM requirement, and
then uses xstrdup() in a few places (which would mean that strdup() is
being used for normal popt users).

I was also working on changing some code to use your newly-added
stpcpy() function, so I included that work too.  Some of the changes
are optimizations to avoid a strlen() call (when we can easily compute
the length via subtraction) and a fix for a potential memory leak if
realloc() returns NULL.

..wayne..
--- system.h    9 Mar 2008 20:24:45 -0000       1.14
+++ system.h    10 Mar 2008 01:40:23 -0000
@@ -78,7 +78,7 @@ static inline char * stpcpy (char *dest,
 #endif
 
 /* Memory allocation via macro defs to get meaningful locations from mtrace() 
*/
-#if defined(HAVE_MCHECK_H) && defined(__GNUC__)
+#if defined(FATAL_MEM) && defined(HAVE_MCHECK_H) && defined(__GNUC__)
 #define        vmefail()       (fprintf(stderr, "virtual memory 
exhausted.\n"), exit(EXIT_FAILURE), NULL)
 #define        xmalloc(_size)          (malloc(_size) ? : vmefail())
 #define        xcalloc(_nmemb, _size)  (calloc((_nmemb), (_size)) ? : 
vmefail())
--- findme.c    9 Mar 2008 20:24:45 -0000       1.19
+++ findme.c    10 Mar 2008 01:40:21 -0000
@@ -23,11 +23,10 @@ const char * POPT_findProgramPath(const 
 
     if (path == NULL) return NULL;
 
-    start = pathbuf = malloc(strlen(path) + 1);
+    start = pathbuf = xstrdup(path);
     if (pathbuf == NULL) goto exit;
     buf = malloc(strlen(path) + strlen(argv0) + sizeof("/"));
     if (buf == NULL) goto exit;
-    strcpy(pathbuf, path);
 
     chptr = NULL;
     do {
--- popt.c      9 Mar 2008 23:10:05 -0000       1.120
+++ popt.c      10 Mar 2008 01:40:22 -0000
@@ -196,10 +196,8 @@ poptContext poptGetContext(const char * 
     if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
        con->flags |= POPT_CONTEXT_POSIXMEHARDER;
 
-    if (name) {
-       char * t = malloc(strlen(name) + 1);
-       if (t) con->appName = strcpy(t, name);
-    }
+    if (name)
+       con->appName = xstrdup(name);
 
     invokeCallbacksPRE(con, con->options);
 
@@ -593,7 +591,7 @@ expandNextArg(/[EMAIL PROTECTED]@*/ poptContext 
        /[EMAIL PROTECTED] con @*/
 {
     const char * a = NULL;
-    size_t alen;
+    size_t alen, pos;
     char *t, *te;
     size_t tn = strlen(s) + 1;
     char c;
@@ -619,10 +617,9 @@ expandNextArg(/[EMAIL PROTECTED]@*/ poptContext 
 
            alen = strlen(a);
            tn += alen;
-           *te = '\0';
+           pos = te - t;
            t = realloc(t, tn);
-           te = t + strlen(t);
-           strncpy(te, a, alen); te += alen;
+           te = stpcpy(t + pos, a);
            continue;
            /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ break;
        default:
@@ -630,8 +627,13 @@ expandNextArg(/[EMAIL PROTECTED]@*/ poptContext 
        }
        *te++ = c;
     }
-    *te = '\0';
-    t = realloc(t, strlen(t) + 1);     /* XXX memory leak, hard to plug */
+    *te++ = '\0';
+    if (t + tn > te) {
+       char *ot = t;
+       t = realloc(t, te - t);
+       if (!t)
+           free(ot);
+    }
     return t;
 }
 
--- poptconfig.c        9 Mar 2008 20:24:45 -0000       1.37
+++ poptconfig.c        10 Mar 2008 01:40:22 -0000
@@ -224,8 +224,7 @@ int poptReadDefaultConfig(poptContext co
     if ((home = getenv("HOME"))) {
        fn = malloc(strlen(home) + 20);
        if (fn != NULL) {
-           strcpy(fn, home);
-           strcat(fn, "/.popt");
+           (void)stpcpy(stpcpy(fn, home), "/.popt");
            rc = poptReadConfigFile(con, fn);
            free(fn);
        } else
--- popthelp.c  8 Mar 2008 17:26:30 -0000       1.85
+++ popthelp.c  10 Mar 2008 01:40:23 -0000
@@ -237,7 +237,7 @@ singleOptionDefaultValue(size_t lineLeng
     if (le == NULL) return NULL;       /* XXX can't happen */
     *le = '\0';
     *le++ = '(';
-    strcpy(le, defstr);        le += strlen(le);
+    le = stpcpy(le, defstr);
     *le++ = ':';
     *le++ = ' ';
   if (opt->arg) {      /* XXX programmer error */
@@ -269,7 +269,7 @@ singleOptionDefaultValue(size_t lineLeng
     case POPT_ARG_STRING:
     {  const char * s = arg.argv[0];
        if (s == NULL) {
-           strcpy(le, "null"); le += strlen(le);
+           le = stpcpy(le, "null");
        } else {
            size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
            *le++ = '"';
@@ -332,18 +332,20 @@ static void singleOptionHelp(FILE * fp, 
 #define        prtlong (opt->longName != NULL) /* XXX splint needs a clue */
     if (!(prtshort || prtlong))
        goto out;
-    if (prtshort && prtlong)
-       sprintf(left, "-%c, %s%s", opt->shortName,
-               (F_ISSET(opt, ONEDASH) ? "-" : "--"),
-               opt->longName);
-    else if (prtshort) 
-       sprintf(left, "-%c", opt->shortName);
-    else if (prtlong)
+    if (prtshort && prtlong) {
+       char *dash = F_ISSET(opt, ONEDASH) ? "-" : "--";
+       left[0] = '-';
+       left[1] = opt->shortName;
+       (void)stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName);
+    } else if (prtshort) {
+       left[0] = '-';
+       left[1] = opt->shortName;
+    } else if (prtlong) {
+       char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? ""
+                  : (F_ISSET(opt, ONEDASH) ? "-" : "--");
        /* XXX --long always padded for alignment with/without "-X, ". */
-       sprintf(left, "    %s%s",
-               (poptArgType(opt) == POPT_ARG_MAINCALL ? "" :
-               (F_ISSET(opt, ONEDASH) ? "-" : "--")),
-               opt->longName);
+       (void)stpcpy(stpcpy(stpcpy(left, "    "), dash), opt->longName);
+    }
 #undef prtlong
 
     if (argDescrip) {
@@ -361,9 +363,8 @@ static void singleOptionHelp(FILE * fp, 
                if (t) {
                    char * te = t;
                    *te = '\0';
-                   if (help) {
-                       strcpy(te, help);       te += strlen(te);
-                   }
+                   if (help)
+                       te = stpcpy(te, help);
                    *te++ = ' ';
                    strcpy(te, defs);
                    defs = _free(defs);

Reply via email to