Hi,

savestr is a function very similar to strdup.  If it runs into an out
of memory condition, its behavior depends on the current status of the
program.  If patch is in "plan a" mode, it will set an out_of_memory
flag, returns NULL and patch will try later on with "plan b" again.
If it is in "plan b", it will call fatal instead.

This means that savestr can return NULL.  During initialization, we
should use a xstrdup() function instead.  If we don't have enough
memory for initialization, "plan b" would also fail.


Tobias

Index: patch.c
===================================================================
RCS file: /cvs/src/usr.bin/patch/patch.c,v
retrieving revision 1.51
diff -u -p -r1.51 patch.c
--- patch.c     26 Nov 2013 13:19:07 -0000      1.51
+++ patch.c     17 Nov 2014 15:44:04 -0000
@@ -213,7 +213,7 @@ main(int argc, char *argv[])
                warn_on_invalid_line = true;
 
                if (outname == NULL)
-                       outname = savestr(filearg[0]);
+                       outname = xstrdup(filearg[0]);
 
                /* for ed script just up and do it and exit */
                if (diff_type == ED_DIFF) {
@@ -491,10 +491,10 @@ get_some_switches(void)
                        /* FALLTHROUGH */
                case 'z':
                        /* must directly follow 'b' case for backwards compat */
-                       simple_backup_suffix = savestr(optarg);
+                       simple_backup_suffix = xstrdup(optarg);
                        break;
                case 'B':
-                       origprae = savestr(optarg);
+                       origprae = xstrdup(optarg);
                        break;
                case 'c':
                        diff_type = CONTEXT_DIFF;
@@ -532,7 +532,7 @@ get_some_switches(void)
                case 'i':
                        if (++filec == MAXFILEC)
                                fatal("too many file arguments\n");
-                       filearg[filec] = savestr(optarg);
+                       filearg[filec] = xstrdup(optarg);
                        break;
                case 'l':
                        canonicalize = true;
@@ -544,7 +544,7 @@ get_some_switches(void)
                        noreverse = true;
                        break;
                case 'o':
-                       outname = savestr(optarg);
+                       outname = xstrdup(optarg);
                        break;
                case 'p':
                        strippath = atoi(optarg);
@@ -588,12 +588,12 @@ get_some_switches(void)
        Argv += optind;
 
        if (Argc > 0) {
-               filearg[0] = savestr(*Argv++);
+               filearg[0] = xstrdup(*Argv++);
                Argc--;
                while (Argc > 0) {
                        if (++filec == MAXFILEC)
                                fatal("too many file arguments\n");
-                       filearg[filec] = savestr(*Argv++);
+                       filearg[filec] = xstrdup(*Argv++);
                        Argc--;
                }
        }
Index: util.c
===================================================================
RCS file: /cvs/src/usr.bin/patch/util.c,v
retrieving revision 1.36
diff -u -p -r1.36 util.c
--- util.c      26 Nov 2013 13:19:07 -0000      1.36
+++ util.c      17 Nov 2014 15:44:04 -0000
@@ -192,6 +192,22 @@ savestr(const char *s)
 }
 
 /*
+ * Allocate a unique area for a string.  Call fatal if out of memory.
+ */
+char *
+xstrdup(const char *s)
+{
+       char    *rv;
+
+       if (!s)
+               s = "Oops";
+       rv = strdup(s);
+       if (rv == NULL)
+               fatal("out of memory\n");
+       return rv;
+}
+
+/*
  * Vanilla terminal output (buffered).
  */
 void
Index: util.h
===================================================================
RCS file: /cvs/src/usr.bin/patch/util.h,v
retrieving revision 1.15
diff -u -p -r1.15 util.h
--- util.h      20 Jun 2005 07:14:06 -0000      1.15
+++ util.h      17 Nov 2014 15:44:04 -0000
@@ -40,6 +40,7 @@ void          pfatal(const char *, ...)
 void           ask(const char *, ...)
                    __attribute__((__format__(__printf__, 1, 2)));
 char           *savestr(const char *);
+char           *xstrdup(const char *);
 void           set_signals(int);
 void           ignore_signals(void);
 void           makedirs(const char *, bool);

Reply via email to