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);