Handle null characters in the format string. A \0 in the argument passed to %b

still results in trucation but this is be much harder to fix.
This commit is contained in:
stefanf 2005-04-14 17:02:34 +00:00
parent 43b3c752b6
commit 2fed363379

View File

@ -90,7 +90,7 @@ static const char rcsid[] =
static int asciicode(void); static int asciicode(void);
static char *doformat(char *, int *); static char *doformat(char *, int *);
static int escape(char *, int); static int escape(char *, int, size_t *);
static int getchr(void); static int getchr(void);
static int getfloating(long double *, int); static int getfloating(long double *, int);
static int getint(int *); static int getint(int *);
@ -109,6 +109,7 @@ progprintf(int argc, char *argv[])
main(int argc, char *argv[]) main(int argc, char *argv[])
#endif #endif
{ {
size_t len;
int ch, chopped, end, rval; int ch, chopped, end, rval;
char *format, *fmt, *start; char *format, *fmt, *start;
@ -138,12 +139,13 @@ main(int argc, char *argv[])
* arguments, arguments of zero/null string are provided to use * arguments, arguments of zero/null string are provided to use
* up the format string. * up the format string.
*/ */
chopped = escape(fmt = format = *argv, 1);/* backslash interpretation */ fmt = format = *argv;
chopped = escape(fmt, 1, &len); /* backslash interpretation */
rval = end = 0; rval = end = 0;
gargv = ++argv; gargv = ++argv;
for (;;) { for (;;) {
start = fmt; start = fmt;
while (*fmt != '\0') { while (fmt < format + len) {
if (fmt[0] == '%') { if (fmt[0] == '%') {
fwrite(start, 1, fmt - start, stdout); fwrite(start, 1, fmt - start, stdout);
if (fmt[1] == '%') { if (fmt[1] == '%') {
@ -246,6 +248,7 @@ doformat(char *start, int *rval)
*fmt = '\0'; *fmt = '\0';
switch (convch) { switch (convch) {
case 'b': { case 'b': {
size_t len;
char *p; char *p;
int getout; int getout;
@ -258,7 +261,7 @@ doformat(char *start, int *rval)
warnx2("%s", strerror(ENOMEM), NULL); warnx2("%s", strerror(ENOMEM), NULL);
return (NULL); return (NULL);
} }
getout = escape(p, 0); getout = escape(p, 0, &len);
*(fmt - 1) = 's'; *(fmt - 1) = 's';
PF(start, p); PF(start, p);
*(fmt - 1) = 'b'; *(fmt - 1) = 'b';
@ -356,12 +359,12 @@ mkquad(char *str, int ch)
} }
static int static int
escape(char *fmt, int percent) escape(char *fmt, int percent, size_t *len)
{ {
char *store; char *save, *store;
int value, c; int value, c;
for (store = fmt; (c = *fmt); ++fmt, ++store) { for (save = store = fmt; (c = *fmt); ++fmt, ++store) {
if (c != '\\') { if (c != '\\') {
*store = c; *store = c;
continue; continue;
@ -370,6 +373,7 @@ escape(char *fmt, int percent)
case '\0': /* EOS, user error */ case '\0': /* EOS, user error */
*store = '\\'; *store = '\\';
*++store = '\0'; *++store = '\0';
*len = store - save;
return (0); return (0);
case '\\': /* backslash */ case '\\': /* backslash */
case '\'': /* single quote */ case '\'': /* single quote */
@ -383,6 +387,7 @@ escape(char *fmt, int percent)
break; break;
case 'c': case 'c':
*store = '\0'; *store = '\0';
*len = store - save;
return (1); return (1);
case 'f': /* form-feed */ case 'f': /* form-feed */
*store = '\f'; *store = '\f';
@ -420,6 +425,7 @@ escape(char *fmt, int percent)
} }
} }
*store = '\0'; *store = '\0';
*len = store - save;
return (0); return (0);
} }