Browse Source

[core] light_isupper(), light_islower()

more efficient char checks
(replace one comparision and one branch with one subtraction)
master
Glenn Strauss 1 year ago
parent
commit
c58b95f297
  1. 4
      src/array.c
  2. 16
      src/buffer.c
  3. 9
      src/buffer.h
  4. 4
      src/burl.c
  5. 4
      src/h2.c
  6. 10
      src/http_auth.c
  7. 2
      src/http_header.c
  8. 13
      src/mod_secdownload.c
  9. 2
      src/mod_userdir.c
  10. 4
      src/request.c

4
src/array.c

@ -101,8 +101,8 @@ static int array_caseless_compare(const char * const a, const char * const b, co
if (ca == cb) continue;
/* always lowercase for transitive results */
if (ca >= 'A' && ca <= 'Z') ca |= 32;
if (cb >= 'A' && cb <= 'Z') cb |= 32;
if (light_isupper(ca)) ca |= 0x20;
if (light_isupper(cb)) cb |= 0x20;
if (ca == cb) continue;
return (int)(ca - cb);

16
src/buffer.c

@ -327,9 +327,9 @@ int buffer_eq_icase_ssn(const char * const a, const char * const b, const size_t
if (ca != cb) {
ca |= 0x20;
cb |= 0x20;
if (ca != cb) return 0;
if (ca < 'a' || 'z' < ca) return 0;
if (cb < 'a' || 'z' < cb) return 0;
if (ca != cb) return 0;
if (!light_islower(ca)) return 0;
if (!light_islower(cb)) return 0;
}
}
return 1;
@ -921,19 +921,17 @@ void buffer_path_simplify(buffer *dest, buffer *src)
}
void buffer_to_lower(buffer * const b) {
char * const s = b->ptr;
unsigned char * const restrict s = (unsigned char *)b->ptr;
for (uint32_t i = 0; i < b->used; ++i) {
char c = s[i];
if (c >= 'A' && c <= 'Z') s[i] |= 0x20;
if (light_isupper(s[i])) s[i] |= 0x20;
}
}
void buffer_to_upper(buffer * const b) {
char * const s = b->ptr;
unsigned char * const restrict s = (unsigned char *)b->ptr;
for (uint32_t i = 0; i < b->used; ++i) {
char c = s[i];
if (c >= 'a' && c <= 'z') s[i] &= ~0x20;
if (light_islower(s[i])) s[i] &= 0xdf;
}
}

9
src/buffer.h

@ -193,19 +193,19 @@ char int2hex(char i);
__attribute_pure__
static inline int light_isdigit(int c);
static inline int light_isdigit(int c) {
return (c >= '0' && c <= '9');
return ((uint32_t)c-'0' <= '9'-'0');
}
__attribute_pure__
static inline int light_isxdigit(int c);
static inline int light_isxdigit(int c) {
return light_isdigit(c) || (c |= 32, c >= 'a' && c <= 'f');
return light_isdigit(c) || (((uint32_t)c | 0x20)-'a' <= 'f'-'a');
}
__attribute_pure__
static inline int light_isalpha(int c);
static inline int light_isalpha(int c) {
return (c |= 32, c >= 'a' && c <= 'z');
return (((uint32_t)c | 0x20)-'a' <= 'z'-'a');
}
__attribute_pure__
@ -214,6 +214,9 @@ static inline int light_isalnum(int c) {
return light_isdigit(c) || light_isalpha(c);
}
#define light_isupper(c) ((uint32_t)(c)-'A' <= 'Z'-'A')
#define light_islower(c) ((uint32_t)(c)-'a' <= 'z'-'a')
__attribute_pure__
static inline uint32_t buffer_string_length(const buffer *b); /* buffer string length without terminating 0 */

4
src/burl.c

@ -463,7 +463,7 @@ static void burl_offset_tolower (buffer * const b, const size_t off)
{
/*(skips over all percent-encodings, including encoding of alpha chars)*/
for (char *p = b->ptr+off; p[0]; ++p) {
if (p[0] >= 'A' && p[0] <= 'Z') p[0] |= 0x20;
if (light_isupper(p[0])) p[0] |= 0x20;
else if (p[0]=='%' && light_isxdigit(p[1]) && light_isxdigit(p[2]))
p+=2;
}
@ -474,7 +474,7 @@ static void burl_offset_toupper (buffer * const b, const size_t off)
{
/*(skips over all percent-encodings, including encoding of alpha chars)*/
for (char *p = b->ptr+off; p[0]; ++p) {
if (p[0] >= 'a' && p[0] <= 'z') p[0] &= 0xdf;
if (light_islower(p[0])) p[0] &= 0xdf;
else if (p[0]=='%' && light_isxdigit(p[1]) && light_isxdigit(p[2]))
p+=2;
}

4
src/h2.c

@ -1644,7 +1644,7 @@ h2_send_headers (request_st * const r, connection * const con)
* end of value buffer */
char * const v = buffer_string_prepare_append(&ds->value, klen);
for (uint32_t j = 0; j < klen; ++j)
v[j] = (k[j] < 'A' || k[j] > 'Z') ? k[j] : (k[j] | 0x20);
v[j] = !light_isupper(k[j]) ? k[j] : (k[j] | 0x20);
/*buffer_commit(&ds->value, klen);*//*(not necessary; truncated below)*/
uint32_t voff = 0;
@ -1908,7 +1908,7 @@ h2_send_end_stream_trailers (request_st * const r, connection * const con, const
const char * const colon = memchr(k, ':', ptr+hoff[i+1]-k);
if (NULL == colon) continue;
do {
if (*k >= 'A' && *k <= 'Z') *k |= 0x20;
if (light_isupper(*k)) *k |= 0x20;
} while (++k != colon);
}

10
src/http_auth.c

@ -192,10 +192,10 @@ int http_auth_digest_hex2bin (const char *hexstr, size_t len, unsigned char *bin
int hi = hexstr[i];
int lo = hexstr[i+1];
if ('0' <= hi && hi <= '9') hi -= '0';
else if ((hi |= 0x20), 'a' <= hi && hi <= 'f') hi += -'a' + 10;
else if ((uint32_t)(hi |= 0x20)-'a' <= 'f'-'a')hi += -'a' + 10;
else return -1;
if ('0' <= lo && lo <= '9') lo -= '0';
else if ((lo |= 0x20), 'a' <= lo && lo <= 'f') lo += -'a' + 10;
else if ((uint32_t)(lo |= 0x20)-'a' <= 'f'-'a')lo += -'a' + 10;
else return -1;
bin[(i >> 1)] = (unsigned char)((hi << 4) | lo);
}
@ -209,9 +209,9 @@ int http_auth_md5_hex2lc (char *md5hex)
int i;
for (i = 0; md5hex[i]; ++i) {
int c = md5hex[i];
if ('0' <= c && c <= '9') continue;
else if ((c |= 0x20), 'a' <= c && c <= 'f') md5hex[i] = c;
else return -1;
if ('0' <= c && c <= '9') continue;
else if ((uint32_t)(c |= 0x20)-'a' <= 'f'-'a') md5hex[i] = c;
else return -1;
}
return (32 == i) ? 0 : -1; /*(Note: char *md5hex must be a 32-char string)*/
}

2
src/http_header.c

@ -195,7 +195,7 @@ void http_header_response_insert(request_st * const r, enum http_header_e id, co
r->resp_header_repeated = 1;
char * const h = buffer_string_prepare_append(vb, klen + vlen + 2);
for (uint32_t i = 0; i < klen; ++i)
h[i] = (k[i] < 'A' || k[i] > 'Z') ? k[i] : (k[i] | 0x20);
h[i] = !light_isupper(k[i]) ? k[i] : (k[i] | 0x20);
buffer_commit(vb, klen);
}
else

13
src/mod_secdownload.c

@ -477,12 +477,8 @@ static int is_hex_len(const char *str, size_t len) {
for (i = 0; i < len && *str; i++, str++) {
/* illegal characters */
if (!((*str >= '0' && *str <= '9') ||
(*str >= 'a' && *str <= 'f') ||
(*str >= 'A' && *str <= 'F'))
) {
if (!light_isxdigit(*str))
return 0;
}
}
return i == len;
@ -502,13 +498,8 @@ static int is_base64_len(const char *str, size_t len) {
for (i = 0; i < len && *str; i++, str++) {
/* illegal characters */
if (!((*str >= '0' && *str <= '9') ||
(*str >= 'a' && *str <= 'z') ||
(*str >= 'A' && *str <= 'Z') ||
(*str == '-') || (*str == '_'))
) {
if (!(light_isalnum(*str) || *str == '-' || *str == '_'))
return 0;
}
}
return i == len;

2
src/mod_userdir.c

@ -179,7 +179,7 @@ static handler_t mod_userdir_docroot_construct(request_st * const r, plugin_data
if (r->conf.force_lowercase_filenames) {
for (size_t i = 0; i < ulen; ++i) {
if (u[i] >= 'A' && u[i] <= 'Z') u[i] |= 0x20;
if (light_isupper(u[i])) u[i] |= 0x20;
}
}

4
src/request.c

@ -784,9 +784,9 @@ http_request_parse_header (request_st * const restrict r, http_header_parse_ctx
(hpctx->http_parseopts & HTTP_PARSEOPT_HEADER_STRICT);
for (uint32_t j = 0; j < klen; ++j) {
if ((k[j] >= 'a' && k[j] <= 'z') || k[j] == '-')
if (light_islower(k[j]) || k[j] == '-')
continue; /*(common cases)*/
if (k[j] >= 'A' && k[j] <= 'Z')
if (light_isupper(k[j]))
return 400;
if (0 != http_request_parse_header_other(r, k+j, klen-j,
http_header_strict))

Loading…
Cancel
Save