]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Consolidate some ASCII tables in `isc/ascii` and `isc/hex`
authorTony Finch <fanf@isc.org>
Fri, 24 Jun 2022 21:11:02 +0000 (22:11 +0100)
committerTony Finch <fanf@isc.org>
Mon, 12 Sep 2022 11:18:57 +0000 (12:18 +0100)
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.

18 files changed:
lib/dns/compress.c
lib/dns/name.c
lib/dns/rbtdb.c
lib/dns/rcode.c
lib/dns/rdata.c
lib/dns/rdata/any_255/tsig_250.c
lib/dns/rdata/in_1/wks_11.c
lib/dns/sdlz.c
lib/dns/ttl.c
lib/isc/Makefile.am
lib/isc/ascii.c [new file with mode: 0644]
lib/isc/hash.c
lib/isc/hex.c
lib/isc/include/isc/ascii.h [new file with mode: 0644]
lib/isc/include/isc/hex.h
lib/isc/symtab.c
lib/isc/tm.c
lib/isccc/symtab.c

index 607c7c273a836a8d30ce23b4887889237554d356..08699c6e3c9cdebc587142d027086aeab787b743 100644 (file)
@@ -18,6 +18,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <isc/ascii.h>
 #include <isc/mem.h>
 #include <isc/result.h>
 #include <isc/string.h>
 #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;
                                                }
                                        }
index 0407c3b085812cf712e9ee40838babb62ea9f119..10075a8582890e126a94fa45ac2583237e021312 100644 (file)
 #include <stdbool.h>
 #include <stdlib.h>
 
+#include <isc/ascii.h>
 #include <isc/buffer.h>
 #include <isc/hash.h>
+#include <isc/hex.h>
 #include <isc/mem.h>
 #include <isc/once.h>
 #include <isc/print.h>
@@ -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);
                }
index f131902d3673941720d0df06126096a19b8796c5..38220271ff49d339afb5ad5faf529628dac4ee85 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdbool.h>
 #include <sys/mman.h>
 
+#include <isc/ascii.h>
 #include <isc/atomic.h>
 #include <isc/crc64.h>
 #include <isc/event.h>
@@ -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]);
                }
        }
 
index 2af0a8faa7e6cff5ca5daf367a206c613d3af888..4954612d156cdaf89db3c7b616b107bb4881662d 100644 (file)
@@ -16,6 +16,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 
+#include <isc/ascii.h>
 #include <isc/buffer.h>
 #include <isc/parseint.h>
 #include <isc/print.h>
@@ -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;
index 23c863edbb6a49f9fc2ad244d8171d5f04fbe185..ccc79b1e4642a7d78944a4d6a43d30c36ef77d78 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <openssl/objects.h>
 
+#include <isc/ascii.h>
 #include <isc/base64.h>
 #include <isc/hex.h>
 #include <isc/lex.h>
@@ -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)) {
-               return (-1);
-       }
-       if (isupper(c)) {
-               c = tolower(c);
-       }
-       if ((s = strchr(hexdigits, c)) == NULL) {
+       int hexval = isc_hex_char(value);
+       if (hexval == 0) {
                return (-1);
+       } else {
+               return (value - hexval);
        }
-       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)) {
-               return (-1);
-       }
-       if ((s = strchr(decdigits, value)) == NULL) {
+       if (isdigit((unsigned char)value)) {
+               return (value - '0');
+       } else {
                return (-1);
        }
-       return ((int)(s - decdigits));
 }
 
 static void
index 3dbd73349bb146962ad71fddd200c29c5337e04c..081622864f56c64580f94f93de03e60f64537d9f 100644 (file)
@@ -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++;
index 0f026f6c714cacb70b5f310308abad9fea626b61..3c31b4a02de3884b7bfd626bfb9207bdd33881c3 100644 (file)
@@ -17,6 +17,7 @@
 #include <limits.h>
 #include <stdlib.h>
 
+#include <isc/ascii.h>
 #include <isc/net.h>
 #include <isc/netdb.h>
 #include <isc/once.h>
@@ -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) &&
index c99f63cb5fe6958699cbe383c03c5b62fd3c2884..28ee82fb6fe7c22f0b8c142d7c06c1c03f670c62 100644 (file)
@@ -52,6 +52,7 @@
 #include <stdbool.h>
 #include <string.h>
 
+#include <isc/ascii.h>
 #include <isc/buffer.h>
 #include <isc/lex.h>
 #include <isc/log.h>
@@ -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);
index 9c6a8aebec9df1545d096cf2b08e257bc523b4d8..0f6b5a5b7c6a056595a0515dca4b472f723c6f7f 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <isc/ascii.h>
 #include <isc/buffer.h>
 #include <isc/parseint.h>
 #include <isc/print.h>
@@ -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, &region);
                region.base[region.length - 1] =
-                       toupper(region.base[region.length - 1]);
+                       isc_ascii_toupper(region.base[region.length - 1]);
        }
        return (ISC_R_SUCCESS);
 }
index 5e4f7db42fa5d2b3a72851790f935c8f39ecc74e..adc147b96835fc3a31102e243adbd8abeb7a05a9 100644 (file)
@@ -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 (file)
index 0000000..71d1366
--- /dev/null
@@ -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 <stdint.h>
+#include <string.h>
+
+#include <isc/ascii.h>
+
+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
+};
index 522e140f8568e71fa5467dd1511347c485cd069c..7e2b17c2df6dd5be35c3194bdc8c4fd52e9f1a46 100644 (file)
@@ -16,6 +16,7 @@
 #include <stddef.h>
 
 #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);
        }
 
index be67f035bb2a624908af1a713e2b4d5c018809b7..a2aa07c4667ec345520d7d3a098faf0703d7fb8d 100644 (file)
@@ -13,7 +13,6 @@
 
 /*! \file */
 
-#include <ctype.h>
 #include <stdbool.h>
 
 #include <isc/buffer.h>
 #include <isc/string.h>
 #include <isc/util.h>
 
+#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 (file)
index 0000000..486e1c5
--- /dev/null
@@ -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 <stdint.h>
+
+/*
+ * 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 <ctype.h>
+ */
+#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);
+       }
+}
index d5f714e9862bce90016384be04f76f4ff1fcae0a..4599bfc893e0aeed0b38550a7dd8d5c9248e5042 100644 (file)
 
 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 <ctype.h>
+ * 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 <ctype.h>
+ */
+#define isc_hex_char(c) isc__hex_char[(uint8_t)(c)]
+
 /***
  *** Functions
  ***/
index ff022a2b16a97c7b6171dd7868048b62a84907a9..fd507ab9188e2a40b111286f806e699470b9f86d 100644 (file)
@@ -13,9 +13,9 @@
 
 /*! \file */
 
-#include <ctype.h>
 #include <stdbool.h>
 
+#include <isc/ascii.h>
 #include <isc/magic.h>
 #include <isc/mem.h>
 #include <isc/string.h>
@@ -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);
                }
        }
 
index 19a7bee453e81bd5132960abc6f1ba1d6cc6357d..65694a0a623b15c5b04e44cba1b1534d17ed276c 100644 (file)
@@ -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);
index 9bd51187c1f7b7af05c0255901d437b353ac95c6..a3185d191096b541c560252d956d02e07047949c 100644 (file)
 
 /*! \file */
 
-#include <ctype.h>
 #include <stdbool.h>
 #include <stdlib.h>
 
+#include <isc/ascii.h>
 #include <isc/assertions.h>
 #include <isc/magic.h>
 #include <isc/result.h>
@@ -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;