From 27a561273e88286b02e65682c0a43c78c7ff4c46 Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Fri, 24 Jun 2022 22:11:02 +0100 Subject: [PATCH] Consolidate some ASCII tables in `isc/ascii` and `isc/hex` There were a number of places that had copies of various ASCII tables (case conversion, hex and decimal conversion) that are intended to be faster than the ctype.h macros, or avoid locale pollution. Move them into libisc, and wrap the lookup tables with macros that avoid the ctype.h gotchas. --- lib/dns/compress.c | 70 ++++++---------- lib/dns/name.c | 135 +++++++++---------------------- lib/dns/rbtdb.c | 10 +-- lib/dns/rcode.c | 3 +- lib/dns/rdata.c | 55 ++++--------- lib/dns/rdata/any_255/tsig_250.c | 2 +- lib/dns/rdata/in_1/wks_11.c | 8 +- lib/dns/sdlz.c | 26 ++---- lib/dns/ttl.c | 6 +- lib/isc/Makefile.am | 2 + lib/isc/ascii.c | 67 +++++++++++++++ lib/isc/hash.c | 44 +++------- lib/isc/hex.c | 25 +++++- lib/isc/include/isc/ascii.h | 38 +++++++++ lib/isc/include/isc/hex.h | 13 +++ lib/isc/symtab.c | 7 +- lib/isc/tm.c | 7 +- lib/isccc/symtab.c | 7 +- 18 files changed, 251 insertions(+), 274 deletions(-) create mode 100644 lib/isc/ascii.c create mode 100644 lib/isc/include/isc/ascii.h diff --git a/lib/dns/compress.c b/lib/dns/compress.c index 607c7c273a..08699c6e3c 100644 --- a/lib/dns/compress.c +++ b/lib/dns/compress.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -30,31 +31,6 @@ #define CCTX_MAGIC ISC_MAGIC('C', 'C', 'T', 'X') #define VALID_CCTX(x) ISC_MAGIC_VALID(x, CCTX_MAGIC) -static unsigned char maptolower[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, - 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, - 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, - 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, - 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, - 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, - 0xfc, 0xfd, 0xfe, 0xff -}; - /* * The tableindex array below is of size 256, one entry for each * unsigned char value. The tableindex array elements are dependent on @@ -262,7 +238,7 @@ dns_compress_find(dns_compress_t *cctx, const dns_name_t *name, node = node->next) { unsigned int l, count; unsigned char c; - unsigned char *label1, *label2; + unsigned char *p1, *p2; if (node->name.length != length) { continue; @@ -273,11 +249,11 @@ dns_compress_find(dns_compress_t *cctx, const dns_name_t *name, continue; } - label1 = node->name.ndata; - label2 = p; + p1 = node->name.ndata; + p2 = p; while (l-- > 0) { - count = *label1++; - if (count != *label2++) { + count = *p1++; + if (count != *p2++) { goto cont1; } @@ -286,34 +262,34 @@ dns_compress_find(dns_compress_t *cctx, const dns_name_t *name, /* Loop unrolled for performance */ while (count > 3) { - c = maptolower[label1[0]]; - if (c != maptolower[label2[0]]) - { + c = isc_ascii_tolower(p1[0]); + if (c != + isc_ascii_tolower(p2[0])) { goto cont1; } - c = maptolower[label1[1]]; - if (c != maptolower[label2[1]]) - { + c = isc_ascii_tolower(p1[1]); + if (c != + isc_ascii_tolower(p2[1])) { goto cont1; } - c = maptolower[label1[2]]; - if (c != maptolower[label2[2]]) - { + c = isc_ascii_tolower(p1[2]); + if (c != + isc_ascii_tolower(p2[2])) { goto cont1; } - c = maptolower[label1[3]]; - if (c != maptolower[label2[3]]) - { + c = isc_ascii_tolower(p1[3]); + if (c != + isc_ascii_tolower(p2[3])) { goto cont1; } count -= 4; - label1 += 4; - label2 += 4; + p1 += 4; + p2 += 4; } while (count-- > 0) { - c = maptolower[*label1++]; - if (c != maptolower[*label2++]) - { + c = isc_ascii_tolower(*p1++); + if (c != + isc_ascii_tolower(*p2++)) { goto cont1; } } diff --git a/lib/dns/name.c b/lib/dns/name.c index 0407c3b085..10075a8582 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -18,8 +18,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -47,53 +49,6 @@ typedef enum { typedef enum { fw_start = 0, fw_ordinary, fw_newcurrent } fw_state; -static char digitvalue[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/ - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/ - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/ -}; - -static unsigned char maptolower[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, - 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, - 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, - 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, - 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, - 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, - 0xfc, 0xfd, 0xfe, 0xff -}; - -#define CONVERTTOASCII(c) -#define CONVERTFROMASCII(c) - #define INIT_OFFSETS(name, var, default_offsets) \ if ((name)->offsets != NULL) \ var = (name)->offsets; \ @@ -561,26 +516,26 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, /* Loop unrolled for performance */ while (count > 3) { - chdiff = (int)maptolower[label1[0]] - - (int)maptolower[label2[0]]; + chdiff = (int)isc_ascii_tolower(label1[0]) - + (int)isc_ascii_tolower(label2[0]); if (chdiff != 0) { *orderp = chdiff; goto done; } - chdiff = (int)maptolower[label1[1]] - - (int)maptolower[label2[1]]; + chdiff = (int)isc_ascii_tolower(label1[1]) - + (int)isc_ascii_tolower(label2[1]); if (chdiff != 0) { *orderp = chdiff; goto done; } - chdiff = (int)maptolower[label1[2]] - - (int)maptolower[label2[2]]; + chdiff = (int)isc_ascii_tolower(label1[2]) - + (int)isc_ascii_tolower(label2[2]); if (chdiff != 0) { *orderp = chdiff; goto done; } - chdiff = (int)maptolower[label1[3]] - - (int)maptolower[label2[3]]; + chdiff = (int)isc_ascii_tolower(label1[3]) - + (int)isc_ascii_tolower(label2[3]); if (chdiff != 0) { *orderp = chdiff; goto done; @@ -590,8 +545,8 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, label2 += 4; } while (count-- > 0) { - chdiff = (int)maptolower[*label1++] - - (int)maptolower[*label2++]; + chdiff = (int)isc_ascii_tolower(*label1++) - + (int)isc_ascii_tolower(*label2++); if (chdiff != 0) { *orderp = chdiff; goto done; @@ -693,20 +648,20 @@ dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) { /* Loop unrolled for performance */ while (count > 3) { - c = maptolower[label1[0]]; - if (c != maptolower[label2[0]]) { + c = isc_ascii_tolower(label1[0]); + if (c != isc_ascii_tolower(label2[0])) { return (false); } - c = maptolower[label1[1]]; - if (c != maptolower[label2[1]]) { + c = isc_ascii_tolower(label1[1]); + if (c != isc_ascii_tolower(label2[1])) { return (false); } - c = maptolower[label1[2]]; - if (c != maptolower[label2[2]]) { + c = isc_ascii_tolower(label1[2]); + if (c != isc_ascii_tolower(label2[2])) { return (false); } - c = maptolower[label1[3]]; - if (c != maptolower[label2[3]]) { + c = isc_ascii_tolower(label1[3]); + if (c != isc_ascii_tolower(label2[3])) { return (false); } count -= 4; @@ -714,8 +669,8 @@ dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) { label2 += 4; } while (count-- > 0) { - c = maptolower[*label1++]; - if (c != maptolower[*label2++]) { + c = isc_ascii_tolower(*label1++); + if (c != isc_ascii_tolower(*label2++)) { return (false); } } @@ -792,8 +747,8 @@ dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) { count = count1; while (count > 0) { count--; - c1 = maptolower[*label1++]; - c2 = maptolower[*label2++]; + c1 = isc_ascii_tolower(*label1++); + c2 = isc_ascii_tolower(*label2++); if (c1 < c2) { return (-1); } else if (c1 > c2) { @@ -1177,9 +1132,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, return (DNS_R_LABELTOOLONG); } count++; - CONVERTTOASCII(c); if (downcase) { - c = maptolower[c & 0xff]; + c = isc_ascii_tolower(c); } *ndata++ = c; nrem--; @@ -1203,9 +1157,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, return (DNS_R_LABELTOOLONG); } count++; - CONVERTTOASCII(c); if (downcase) { - c = maptolower[c & 0xff]; + c = isc_ascii_tolower(c); } *ndata++ = c; nrem--; @@ -1221,8 +1174,7 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, if (!isdigit((unsigned char)c)) { return (DNS_R_BADESCAPE); } - value *= 10; - value += digitvalue[c & 0xff]; + value = 10 * value + c - '0'; digits++; if (digits == 3) { if (value > 255) { @@ -1233,7 +1185,7 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, } count++; if (downcase) { - value = maptolower[value]; + value = isc_ascii_tolower(value); } *ndata++ = value; nrem--; @@ -1281,7 +1233,7 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, while (n2 > 0) { c = *label++; if (downcase) { - c = maptolower[c & 0xff]; + c = isc_ascii_tolower(c); } *ndata++ = c; n2--; @@ -1430,7 +1382,6 @@ dns_name_totext2(const dns_name_t *name, unsigned int options, return (ISC_R_NOSPACE); } *tdata++ = '\\'; - CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem -= 2; @@ -1442,7 +1393,6 @@ dns_name_totext2(const dns_name_t *name, unsigned int options, if (trem == 0) { return (ISC_R_NOSPACE); } - CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem--; @@ -1571,7 +1521,6 @@ dns_name_tofilenametext(const dns_name_t *name, bool omit_final_dot, if (c >= 0x41 && c <= 0x5A) { c += 0x20; } - CONVERTFROMASCII(c); *tdata++ = c; ndata++; trem--; @@ -1667,7 +1616,7 @@ dns_name_downcase(const dns_name_t *source, dns_name_t *name, if (count < 64) { INSIST(nlen >= count); while (count > 0) { - *ndata++ = maptolower[(*sndata++)]; + *ndata++ = isc_ascii_tolower(*sndata++); nlen--; count--; } @@ -1852,7 +1801,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t dctx, break; case fw_ordinary: if (downcase) { - c = maptolower[c]; + c = isc_ascii_tolower(c); } *ndata++ = c; n--; @@ -2604,19 +2553,6 @@ dns_name_isula(const dns_name_t *name) { return (false); } -/* - * Use a simple table as we don't want all the locale stuff - * associated with ishexdigit(). - */ -const char ishex[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - bool dns_name_istat(const dns_name_t *name) { unsigned char len; @@ -2641,8 +2577,8 @@ dns_name_istat(const dns_name_t *name) { return (false); } - if (ndata[0] != '_' || maptolower[ndata[1]] != 't' || - maptolower[ndata[2]] != 'a') + if (ndata[0] != '_' || isc_ascii_tolower(ndata[1]) != 't' || + isc_ascii_tolower(ndata[2]) != 'a') { return (false); } @@ -2651,8 +2587,9 @@ dns_name_istat(const dns_name_t *name) { while (len > 0) { INSIST(len >= 5); - if (ndata[0] != '-' || !ishex[ndata[1]] || !ishex[ndata[2]] || - !ishex[ndata[3]] || !ishex[ndata[4]]) + if (ndata[0] != '-' || !isc_hex_char(ndata[1]) || + !isc_hex_char(ndata[2]) || !isc_hex_char(ndata[3]) || + !isc_hex_char(ndata[4])) { return (false); } diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index f131902d36..38220271ff 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -9374,9 +9375,10 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) { if (CASEFULLYLOWER(header)) { for (size_t i = 0; i < name->length; i++) { - name->ndata[i] = tolower(name->ndata[i]); + name->ndata[i] = isc_ascii_tolower(name->ndata[i]); } } else { + uint8_t *nd = name->ndata; for (size_t i = 0; i < name->length; i++) { if (mask == (1 << 7)) { bits = header->upper[i / 8]; @@ -9384,10 +9386,8 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) { } else { mask <<= 1; } - - name->ndata[i] = ((bits & mask) != 0) - ? toupper(name->ndata[i]) - : tolower(name->ndata[i]); + nd[i] = (bits & mask) ? isc_ascii_toupper(nd[i]) + : isc_ascii_tolower(nd[i]); } } diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c index 2af0a8faa7..4954612d15 100644 --- a/lib/dns/rcode.c +++ b/lib/dns/rcode.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -474,7 +475,7 @@ dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source) { return (ISC_R_SUCCESS); \ } - switch (tolower((unsigned char)source->base[0])) { + switch (isc_ascii_tolower(source->base[0])) { case 'a': COMPARE("any", dns_rdataclass_any); break; diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 23c863edbb..ccc79b1e46 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -355,28 +356,20 @@ static dns_name_t const gc_msdcs = DNS_NAME_INITNONABSOLUTE(gc_msdcs_data, */ static int locator_pton(const char *src, unsigned char *dst) { - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[NS_LOCATORSZ]; unsigned char *tp = tmp, *endp; - const char *xdigits; int ch, seen_xdigits; - unsigned int val; + unsigned int val, hexval; memset(tp, '\0', NS_LOCATORSZ); endp = tp + NS_LOCATORSZ; seen_xdigits = 0; val = 0; while ((ch = *src++) != '\0') { - const char *pch; - - pch = strchr((xdigits = xdigits_l), ch); - if (pch == NULL) { - pch = strchr((xdigits = xdigits_u), ch); - } - if (pch != NULL) { + hexval = isc_hex_char(ch); + if (hexval != 0) { val <<= 4; - val |= (pch - xdigits); + val |= (ch - hexval); if (++seen_xdigits > 4) { return (0); } @@ -603,9 +596,6 @@ typemap_test(isc_region_t *sr, bool allow_empty) { return (ISC_R_SUCCESS); } -static const char hexdigits[] = "0123456789abcdef"; -static const char decdigits[] = "0123456789"; - static isc_result_t check_private(isc_buffer_t *source, dns_secalg_t alg) { isc_region_t sr; @@ -1396,8 +1386,8 @@ dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) { return (DNS_R_UNKNOWN); } - a = tolower((unsigned char)source->base[0]); - b = tolower((unsigned char)source->base[n - 1]); + a = isc_ascii_tolower(source->base[0]); + b = isc_ascii_tolower(source->base[n - 1]); hash = ((a + n) * b) % 256; @@ -2070,38 +2060,21 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { static int hexvalue(char value) { - const char *s; - unsigned char c; - - c = (unsigned char)value; - - if (!isascii(c)) { + int hexval = isc_hex_char(value); + if (hexval == 0) { return (-1); + } else { + return (value - hexval); } - if (isupper(c)) { - c = tolower(c); - } - if ((s = strchr(hexdigits, c)) == NULL) { - return (-1); - } - return ((int)(s - hexdigits)); } static int decvalue(char value) { - const char *s; - - /* - * isascii() is valid for full range of int values, no need to - * mask or cast. - */ - if (!isascii(value)) { + if (isdigit((unsigned char)value)) { + return (value - '0'); + } else { return (-1); } - if ((s = strchr(decdigits, value)) == NULL) { - return (-1); - } - return ((int)(s - decdigits)); } static void diff --git a/lib/dns/rdata/any_255/tsig_250.c b/lib/dns/rdata/any_255/tsig_250.c index 3dbd73349b..081622864f 100644 --- a/lib/dns/rdata/any_255/tsig_250.c +++ b/lib/dns/rdata/any_255/tsig_250.c @@ -169,7 +169,7 @@ totext_any_tsig(ARGS_TOTEXT) { *bufp-- = 0; *bufp-- = ' '; do { - *bufp-- = decdigits[sigtime % 10]; + *bufp-- = '0' + sigtime % 10; sigtime /= 10; } while (sigtime != 0); bufp++; diff --git a/lib/dns/rdata/in_1/wks_11.c b/lib/dns/rdata/in_1/wks_11.c index 0f026f6c71..3c31b4a02d 100644 --- a/lib/dns/rdata/in_1/wks_11.c +++ b/lib/dns/rdata/in_1/wks_11.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -70,7 +71,6 @@ fromtext_in_wks(ARGS_FROMTEXT) { const char *ps = NULL; unsigned int n; char service[32]; - int i; isc_result_t result; REQUIRE(type == dns_rdatatype_wks); @@ -136,11 +136,7 @@ fromtext_in_wks(ARGS_FROMTEXT) { * case sensitive and the database is usually in lowercase. */ strlcpy(service, DNS_AS_STR(token), sizeof(service)); - for (i = strlen(service) - 1; i >= 0; i--) { - if (isupper(service[i] & 0xff)) { - service[i] = tolower(service[i] & 0xff); - } - } + isc_ascii_strtolower(service); port = strtol(DNS_AS_STR(token), &e, 10); if (*e != 0 && !mygetservbyname(service, ps, &port) && diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index c99f63cb5f..28ee82fb6f 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -52,6 +52,7 @@ #include #include +#include #include #include #include @@ -238,19 +239,6 @@ sdlz_log(int level, const char *fmt, ...) { va_end(ap); } -/*% Converts the input string to lowercase, in place. */ -static void -dns_sdlz_tolower(char *str) { - unsigned int len = strlen(str); - unsigned int i; - - for (i = 0; i < len; i++) { - if (str[i] >= 'A' && str[i] <= 'Z') { - str[i] += 32; - } - } -} - static unsigned int initial_size(const char *data) { unsigned int len = (strlen(data) / 64) + 1; @@ -570,8 +558,8 @@ getnodedata(dns_db_t *db, const dns_name_t *name, bool create, isorigin = dns_name_equal(name, &sdlz->common.origin); /* make sure strings are always lowercase */ - dns_sdlz_tolower(zonestr); - dns_sdlz_tolower(namestr); + isc_ascii_strtolower(zonestr); + isc_ascii_strtolower(namestr); MAYBE_LOCK(sdlz->dlzimp); @@ -787,7 +775,7 @@ createiterator(dns_db_t *db, unsigned int options, sdlziter->origin = NULL; /* make sure strings are always lowercase */ - dns_sdlz_tolower(zonestr); + isc_ascii_strtolower(zonestr); MAYBE_LOCK(sdlz->dlzimp); result = sdlz->dlzimp->methods->allnodes( @@ -1541,8 +1529,8 @@ dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx, isc_buffer_putuint8(&b2, 0); /* make sure strings are always lowercase */ - dns_sdlz_tolower(namestr); - dns_sdlz_tolower(clientstr); + isc_ascii_strtolower(namestr); + isc_ascii_strtolower(clientstr); /* Call SDLZ driver's find zone method */ if (imp->methods->allowzonexfr != NULL) { @@ -1651,7 +1639,7 @@ dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx, isc_buffer_putuint8(&b, 0); /* make sure strings are always lowercase */ - dns_sdlz_tolower(namestr); + isc_ascii_strtolower(namestr); /* Call SDLZ driver's find zone method */ MAYBE_LOCK(imp); diff --git a/lib/dns/ttl.c b/lib/dns/ttl.c index 9c6a8aebec..0f6b5a5b7c 100644 --- a/lib/dns/ttl.c +++ b/lib/dns/ttl.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -119,13 +120,10 @@ dns_ttl_totext(uint32_t src, bool verbose, bool upcase, isc_buffer_t *target) { /* * The unit letter is the last character in the * used region of the buffer. - * - * toupper() does not need its argument to be masked of cast - * here because region.base is type unsigned char *. */ isc_buffer_usedregion(target, ®ion); region.base[region.length - 1] = - toupper(region.base[region.length - 1]); + isc_ascii_toupper(region.base[region.length - 1]); } return (ISC_R_SUCCESS); } diff --git a/lib/isc/Makefile.am b/lib/isc/Makefile.am index 5e4f7db42f..adc147b968 100644 --- a/lib/isc/Makefile.am +++ b/lib/isc/Makefile.am @@ -6,6 +6,7 @@ libisc_ladir = $(includedir)/isc libisc_la_HEADERS = \ include/isc/aes.h \ include/isc/align.h \ + include/isc/ascii.h \ include/isc/assertions.h \ include/isc/astack.h \ include/isc/async.h \ @@ -116,6 +117,7 @@ libisc_la_SOURCES = \ netmgr/tlsdns.c \ netmgr/udp.c \ aes.c \ + ascii.c \ assertions.c \ astack.c \ async.c \ diff --git a/lib/isc/ascii.c b/lib/isc/ascii.c new file mode 100644 index 0000000000..71d136619b --- /dev/null +++ b/lib/isc/ascii.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#include +#include + +#include + +const uint8_t isc__ascii_tolower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0xff +}; + +const uint8_t isc__ascii_toupper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0xff +}; diff --git a/lib/isc/hash.c b/lib/isc/hash.c index 522e140f85..7e2b17c2df 100644 --- a/lib/isc/hash.c +++ b/lib/isc/hash.c @@ -16,6 +16,7 @@ #include #include "entropy_private.h" +#include "isc/ascii.h" #include "isc/hash.h" /* IWYU pragma: keep */ #include "isc/once.h" #include "isc/random.h" @@ -48,31 +49,6 @@ isc_hash_initialize(void) { hash_initialized = true; } -static uint8_t maptolower[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, - 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, - 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, - 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, - 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, - 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, - 0xfc, 0xfd, 0xfe, 0xff -}; - const void * isc_hash_get_initializer(void) { if (!hash_initialized) { @@ -113,12 +89,13 @@ isc_hash64(const void *data, const size_t length, const bool case_sensitive) { if (case_sensitive) { isc_siphash24(isc_hash_key, data, length, (uint8_t *)&hval); } else { - uint8_t input[1024]; + const uint8_t *byte = data; + uint8_t lower[1024]; REQUIRE(length <= 1024); - for (unsigned int i = 0; i < length; i++) { - input[i] = maptolower[((const uint8_t *)data)[i]]; + for (unsigned i = 0; i < length; i++) { + lower[i] = isc_ascii_tolower(byte[i]); } - isc_siphash24(isc_hash_key, input, length, (uint8_t *)&hval); + isc_siphash24(isc_hash_key, lower, length, (uint8_t *)&hval); } return (hval); @@ -136,12 +113,13 @@ isc_hash32(const void *data, const size_t length, const bool case_sensitive) { if (case_sensitive) { isc_halfsiphash24(isc_hash_key, data, length, (uint8_t *)&hval); } else { - uint8_t input[1024]; + const uint8_t *byte = data; + uint8_t lower[1024]; REQUIRE(length <= 1024); - for (unsigned int i = 0; i < length; i++) { - input[i] = maptolower[((const uint8_t *)data)[i]]; + for (unsigned i = 0; i < length; i++) { + lower[i] = isc_ascii_tolower(byte[i]); } - isc_halfsiphash24(isc_hash_key, input, length, + isc_halfsiphash24(isc_hash_key, lower, length, (uint8_t *)&hval); } diff --git a/lib/isc/hex.c b/lib/isc/hex.c index be67f035bb..a2aa07c466 100644 --- a/lib/isc/hex.c +++ b/lib/isc/hex.c @@ -13,7 +13,6 @@ /*! \file */ -#include #include #include @@ -22,6 +21,23 @@ #include #include +#define D ('0' - 0x0) /* ascii '0' to hex */ +#define U ('A' - 0xA) /* ascii 'A' to hex */ +#define L ('a' - 0xa) /* ascii 'a' to hex */ + +const uint8_t isc__hex_char[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, D, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, 0, 0, U, + U, U, U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, L, L, L, L, L, L, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#undef D +#undef U +#undef L + #define RETERR(x) \ do { \ isc_result_t _r = (x); \ @@ -86,12 +102,13 @@ hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target) { static isc_result_t hex_decode_char(hex_decode_ctx_t *ctx, int c) { - const char *s; + uint8_t hexval; - if ((s = strchr(hex, toupper(c))) == NULL) { + hexval = isc_hex_char(c); + if (hexval == 0) { return (ISC_R_BADHEX); } - ctx->val[ctx->digits++] = (int)(s - hex); + ctx->val[ctx->digits++] = c - hexval; if (ctx->digits == 2) { unsigned char num; diff --git a/lib/isc/include/isc/ascii.h b/lib/isc/include/isc/ascii.h new file mode 100644 index 0000000000..486e1c540e --- /dev/null +++ b/lib/isc/include/isc/ascii.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#pragma once + +#include + +/* + * ASCII case conversion + */ +extern const uint8_t isc__ascii_tolower[256]; +extern const uint8_t isc__ascii_toupper[256]; + +/* + * Wrappers so we don't have to cast all over the place like + */ +#define isc_ascii_tolower(c) isc__ascii_tolower[(uint8_t)(c)] +#define isc_ascii_toupper(c) isc__ascii_toupper[(uint8_t)(c)] + +/* + * Convert a string to lower case in place + */ +static inline void +isc_ascii_strtolower(char *str) { + for (size_t len = strlen(str); len > 0; len--, str++) { + *str = isc_ascii_tolower(*str); + } +} diff --git a/lib/isc/include/isc/hex.h b/lib/isc/include/isc/hex.h index d5f714e986..4599bfc893 100644 --- a/lib/isc/include/isc/hex.h +++ b/lib/isc/include/isc/hex.h @@ -20,6 +20,19 @@ ISC_LANG_BEGINDECLS +/* + * An `isc__hex_char` table entry is non-zero if the character is a hex digit; + * You can subtract the table entry from the character to convert the hex digit + * to its value. e.g. 'a' - isc__hex_char['a'] == 10. Unlike + * isxdigit(), this saves you from needing another case analysis. + */ +extern const uint8_t isc__hex_char[256]; + +/* + * Wrapper so we don't have to cast all over the place like + */ +#define isc_hex_char(c) isc__hex_char[(uint8_t)(c)] + /*** *** Functions ***/ diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c index ff022a2b16..fd507ab918 100644 --- a/lib/isc/symtab.c +++ b/lib/isc/symtab.c @@ -13,9 +13,9 @@ /*! \file */ -#include #include +#include #include #include #include @@ -111,7 +111,6 @@ static unsigned int hash(const char *key, bool case_sensitive) { const char *s; unsigned int h = 0; - int c; /* * This hash function is similar to the one Ousterhout @@ -124,9 +123,7 @@ hash(const char *key, bool case_sensitive) { } } else { for (s = key; *s != '\0'; s++) { - c = *s; - c = tolower((unsigned char)c); - h += (h << 3) + c; + h += (h << 3) + isc_ascii_tolower(*s); } } diff --git a/lib/isc/tm.c b/lib/isc/tm.c index 19a7bee453..65694a0a62 100644 --- a/lib/isc/tm.c +++ b/lib/isc/tm.c @@ -96,11 +96,10 @@ conv_num(const char **buf, int *dest, int llim, int ulim) { } do { - result *= 10; - result += *(*buf)++ - '0'; + result = 10 * result + *(*buf)++ - '0'; rulim /= 10; - } while ((result * 10 <= ulim) && rulim && **buf >= '0' && - **buf <= '9'); + } while ((result * 10 <= ulim) && rulim && + isdigit((unsigned char)**buf)); if (result < llim || result > ulim) { return (0); diff --git a/lib/isccc/symtab.c b/lib/isccc/symtab.c index 9bd51187c1..a3185d1910 100644 --- a/lib/isccc/symtab.c +++ b/lib/isccc/symtab.c @@ -29,10 +29,10 @@ /*! \file */ -#include #include #include +#include #include #include #include @@ -134,7 +134,6 @@ hash(const char *key, bool case_sensitive) { const char *s; unsigned int h = 0; unsigned int g; - int c; /* * P. J. Weinberger's hash function, adapted from p. 436 of @@ -152,9 +151,7 @@ hash(const char *key, bool case_sensitive) { } } else { for (s = key; *s != '\0'; s++) { - c = *s; - c = tolower((unsigned char)c); - h = (h << 4) + c; + h = (h << 4) + isc_ascii_tolower(*s); if ((g = (h & 0xf0000000)) != 0) { h = h ^ (g >> 24); h = h ^ g;