2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

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.
This commit is contained in:
Tony Finch
2022-06-24 22:11:02 +01:00
parent db3590e0b7
commit 27a561273e
18 changed files with 251 additions and 274 deletions

View 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 \

67
lib/isc/ascii.c Normal file
View File

@@ -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
};

View 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);
}

View File

@@ -13,7 +13,6 @@
/*! \file */
#include <ctype.h>
#include <stdbool.h>
#include <isc/buffer.h>
@@ -22,6 +21,23 @@
#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;

View File

@@ -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);
}
}

View File

@@ -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 <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
***/

View 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);
}
}

View 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);