From c5fc88cea5a985ac752b2ab62271d1420a39fa36 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Tue, 2 Jun 2020 18:48:53 +0200 Subject: [PATCH 236/325] printf: Let printf_doformat() use malloc() to work around FreeBSD bug 246630 Obtained from: ElectroBSD --- usr.bin/printf/printf.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c index 94667f381a60..53b9c5607e06 100644 --- a/usr.bin/printf/printf.c +++ b/usr.bin/printf/printf.c @@ -214,11 +214,15 @@ printf_doformat(char *fmt, int *rval) static const char skip1[] = "#'-+ 0"; int fieldwidth, haveprec, havewidth, mod_ldbl, precision; char convch, nextch; - char start[strlen(fmt) + 1]; + char *start; char **fargv; char *dptr; int l; + if ((start = malloc(strlen(fmt) + 1)) == NULL) { + warnx("%s", strerror(ENOMEM)); + return (NULL); + } dptr = start; *dptr++ = '%'; *dptr = 0; @@ -258,6 +262,7 @@ printf_doformat(char *fmt, int *rval) int idx = atoi(fmt); if (fargv == NULL) { warnx("incomplete use of n$"); + free(start); return (NULL); } if (idx <= myargc) { @@ -268,11 +273,14 @@ printf_doformat(char *fmt, int *rval) fmt += l + 1; } else if (fargv != NULL) { warnx("incomplete use of n$"); + free(start); return (NULL); } - if (getint(&fieldwidth)) + if (getint(&fieldwidth)) { + free(start); return (NULL); + } if (gargv > maxargv) maxargv = gargv; havewidth = 1; @@ -302,6 +310,7 @@ printf_doformat(char *fmt, int *rval) int idx = atoi(fmt); if (fargv == NULL) { warnx("incomplete use of n$"); + free(start); return (NULL); } if (idx <= myargc) { @@ -312,11 +321,14 @@ printf_doformat(char *fmt, int *rval) fmt += l + 1; } else if (fargv != NULL) { warnx("incomplete use of n$"); + free(start); return (NULL); } - if (getint(&precision)) + if (getint(&precision)) { + free(start); return (NULL); + } if (gargv > maxargv) maxargv = gargv; haveprec = 1; @@ -335,6 +347,7 @@ printf_doformat(char *fmt, int *rval) haveprec = 0; if (!*fmt) { warnx("missing format character"); + free(start); return (NULL); } *dptr++ = *fmt; @@ -355,6 +368,7 @@ printf_doformat(char *fmt, int *rval) fmt++; if (!strchr("aAeEfFgG", *fmt)) { warnx("bad modifier L for %%%c", *fmt); + free(start); return (NULL); } } else { @@ -380,6 +394,7 @@ printf_doformat(char *fmt, int *rval) start[strlen(start) - 1] = 's'; if ((p = strdup(getstr())) == NULL) { warnx("%s", strerror(ENOMEM)); + free(start); return (NULL); } getout = escape(p, 0, &len); @@ -387,8 +402,10 @@ printf_doformat(char *fmt, int *rval) /* Restore format for next loop. */ free(p); - if (getout) + if (getout) { + free(start); return (end_fmt); + } break; } case 'c': { @@ -413,8 +430,10 @@ printf_doformat(char *fmt, int *rval) int signedconv; signedconv = (convch == 'd' || convch == 'i'); - if ((f = mknum(start, convch)) == NULL) + if ((f = mknum(start, convch)) == NULL) { + free(start); return (NULL); + } if (getnum(&val, &uval, signedconv)) *rval = 1; if (signedconv) @@ -439,9 +458,11 @@ printf_doformat(char *fmt, int *rval) } default: warnx("illegal format character %c", convch); + free(start); return (NULL); } *fmt = nextch; + free(start); /* return the gargv to the next element */ return (fmt); } -- 2.32.0