Change octal and hex parsing to not use strtoul so that they don't handle
'-'. From Martijn van Duren. Also add a warning if the conversion fails (like the gnu printf does)
This commit is contained in:
parent
9777eb9aeb
commit
f1d025f4e1
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: printf.c,v 1.50 2019/07/22 17:34:31 kre Exp $ */
|
/* $NetBSD: printf.c,v 1.51 2021/04/16 15:10:18 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1989, 1993
|
* Copyright (c) 1989, 1993
|
||||||
|
@ -41,7 +41,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1993\
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)printf.c 8.2 (Berkeley) 3/22/95";
|
static char sccsid[] = "@(#)printf.c 8.2 (Berkeley) 3/22/95";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: printf.c,v 1.50 2019/07/22 17:34:31 kre Exp $");
|
__RCSID("$NetBSD: printf.c,v 1.51 2021/04/16 15:10:18 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
|
@ -118,6 +118,10 @@ static char **gargv;
|
||||||
error = asprintf(cpp, f, func); \
|
error = asprintf(cpp, f, func); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define isodigit(c) ((c) >= '0' && (c) <= '7')
|
||||||
|
#define octtobin(c) (char)((c) - '0')
|
||||||
|
#define check(c, a) (c) >= (a) && (c) <= (a) + 5 ? (char)((c) - (a) + 10)
|
||||||
|
#define hextobin(c) (check(c, 'a') : check(c, 'A') : (char)((c) - '0'))
|
||||||
#ifdef main
|
#ifdef main
|
||||||
int main(int, char *[]);
|
int main(int, char *[]);
|
||||||
#endif
|
#endif
|
||||||
|
@ -482,9 +486,9 @@ conv_escape_str(char *str, void (*do_putchar)(int), int quiet)
|
||||||
static char *
|
static char *
|
||||||
conv_escape(char *str, char *conv_ch, int quiet)
|
conv_escape(char *str, char *conv_ch, int quiet)
|
||||||
{
|
{
|
||||||
char value;
|
char value = 0;
|
||||||
char ch;
|
char ch, *begin;
|
||||||
char num_buf[4], *num_end;
|
int c;
|
||||||
|
|
||||||
ch = *str++;
|
ch = *str++;
|
||||||
|
|
||||||
|
@ -499,13 +503,11 @@ conv_escape(char *str, char *conv_ch, int quiet)
|
||||||
|
|
||||||
case '0': case '1': case '2': case '3':
|
case '0': case '1': case '2': case '3':
|
||||||
case '4': case '5': case '6': case '7':
|
case '4': case '5': case '6': case '7':
|
||||||
num_buf[0] = ch;
|
str--;
|
||||||
ch = str[0];
|
for (c = 3; c-- && isodigit(*str); str++) {
|
||||||
num_buf[1] = ch;
|
value <<= 3;
|
||||||
num_buf[2] = (char)(ch != '\0' ? str[1] : '\0');
|
value += octtobin(*str);
|
||||||
num_buf[3] = '\0';
|
}
|
||||||
value = (char)strtoul(num_buf, &num_end, 8);
|
|
||||||
str += num_end - (num_buf + 1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
|
@ -515,12 +517,18 @@ conv_escape(char *str, char *conv_ch, int quiet)
|
||||||
* way to detect the end of the constant.
|
* way to detect the end of the constant.
|
||||||
* Supporting 2 byte constants is a compromise.
|
* Supporting 2 byte constants is a compromise.
|
||||||
*/
|
*/
|
||||||
ch = str[0];
|
begin = str;
|
||||||
num_buf[0] = ch;
|
for (c = 2; c-- && isxdigit((unsigned char)*str); str++) {
|
||||||
num_buf[1] = (char)(ch != '\0' ? str[1] : '\0');
|
value <<= 4;
|
||||||
num_buf[2] = '\0';
|
const char d = hextobin(*str);
|
||||||
value = (char)strtoul(num_buf, &num_end, 16);
|
value += d;
|
||||||
str += num_end - num_buf;
|
}
|
||||||
|
if (str == begin) {
|
||||||
|
if (!quiet)
|
||||||
|
warnx("\\x%s: missing hexadecimal number "
|
||||||
|
"in escape", begin);
|
||||||
|
rval = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\\': value = '\\'; break; /* backslash */
|
case '\\': value = '\\'; break; /* backslash */
|
||||||
|
|
Loading…
Reference in New Issue