Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/printf Change octal and hex parsing to not use strto...
details: https://anonhg.NetBSD.org/src/rev/fb90f6d37a90
branches: trunk
changeset: 378546:fb90f6d37a90
user: christos <christos%NetBSD.org@localhost>
date: Fri Apr 16 15:10:18 2021 +0000
description:
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)
diffstat:
usr.bin/printf/printf.c | 44 ++++++++++++++++++++++++++------------------
1 files changed, 26 insertions(+), 18 deletions(-)
diffs (86 lines):
diff -r 01c2baab223b -r fb90f6d37a90 usr.bin/printf/printf.c
--- a/usr.bin/printf/printf.c Fri Apr 16 13:02:47 2021 +0000
+++ b/usr.bin/printf/printf.c Fri Apr 16 15:10:18 2021 +0000
@@ -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
@@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)printf.c 8.2 (Berkeley) 3/22/95";
#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 /* not lint */
@@ -118,6 +118,10 @@ static char **gargv;
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
int main(int, char *[]);
#endif
@@ -482,9 +486,9 @@ conv_escape_str(char *str, void (*do_put
static char *
conv_escape(char *str, char *conv_ch, int quiet)
{
- char value;
- char ch;
- char num_buf[4], *num_end;
+ char value = 0;
+ char ch, *begin;
+ int c;
ch = *str++;
@@ -499,13 +503,11 @@ conv_escape(char *str, char *conv_ch, in
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
- num_buf[0] = ch;
- ch = str[0];
- num_buf[1] = ch;
- num_buf[2] = (char)(ch != '\0' ? str[1] : '\0');
- num_buf[3] = '\0';
- value = (char)strtoul(num_buf, &num_end, 8);
- str += num_end - (num_buf + 1);
+ str--;
+ for (c = 3; c-- && isodigit(*str); str++) {
+ value <<= 3;
+ value += octtobin(*str);
+ }
break;
case 'x':
@@ -515,12 +517,18 @@ conv_escape(char *str, char *conv_ch, in
* way to detect the end of the constant.
* Supporting 2 byte constants is a compromise.
*/
- ch = str[0];
- num_buf[0] = ch;
- num_buf[1] = (char)(ch != '\0' ? str[1] : '\0');
- num_buf[2] = '\0';
- value = (char)strtoul(num_buf, &num_end, 16);
- str += num_end - num_buf;
+ begin = str;
+ for (c = 2; c-- && isxdigit((unsigned char)*str); str++) {
+ value <<= 4;
+ const char d = hextobin(*str);
+ value += d;
+ }
+ if (str == begin) {
+ if (!quiet)
+ warnx("\\x%s: missing hexadecimal number "
+ "in escape", begin);
+ rval = 1;
+ }
break;
case '\\': value = '\\'; break; /* backslash */
Home |
Main Index |
Thread Index |
Old Index