diff options
author | Joe Orton <joe@manyfish.uk> | 2022-09-03 16:52:34 +0100 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2022-09-03 17:17:34 +0100 |
commit | 740dd9a85f4813a012a6f1583d705e42c7174302 (patch) | |
tree | d56da1dd88c3b33f3b500194222c09696820b4af | |
parent | fc27f8542c08d09ffe89c006366ea797b49e9929 (diff) | |
download | neon-git-740dd9a85f4813a012a6f1583d705e42c7174302.tar.gz |
Add character lookup table generator utility, and fix a extparam
encoding issue.
* src/mktable.c: New file.
* src/ne_string.c: Use generated character lookup tables.
Use lookup tables for base64 validity tests.
Fix extparam encoding for numerals.
* test/string-tests.c (strparam): Add test for numerals.
-rw-r--r-- | src/.gitignore | 2 | ||||
-rw-r--r-- | src/Makefile.in | 3 | ||||
-rw-r--r-- | src/mktable.c | 142 | ||||
-rw-r--r-- | src/ne_string.c | 310 | ||||
-rw-r--r-- | test/string-tests.c | 4 |
5 files changed, 325 insertions, 136 deletions
diff --git a/src/.gitignore b/src/.gitignore index c57df1c..f71228a 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -15,4 +15,4 @@ checkincl.c *.bbg *.[is] *.gc* - +mktable diff --git a/src/Makefile.in b/src/Makefile.in index 8e88f73..588419e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -82,6 +82,9 @@ clean: rm -f $(NEON_TARGET) *.o *.lo *.bbg *.bb *.gc* rm -rf .libs +mktable: mktable.lo + $(LINK) -o $@ mktable.lo + c++.c: find . -name ne_\*.h -print | sed 's/.*/#include "&"/;/ne_priv/d' > $@ echo "int main(void) {}" >> $@ diff --git a/src/mktable.c b/src/mktable.c new file mode 100644 index 0000000..c51ee72 --- /dev/null +++ b/src/mktable.c @@ -0,0 +1,142 @@ +/* + Character lookup table generator + Copyright (C) 2022, Joe Orton <joe@manyfish.co.uk> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +*/ + +#include <string.h> +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +typedef unsigned char (*generator)(unsigned char ch); + +static unsigned char gen_clean(unsigned char ch) +{ + return isprint(ch) ? ch : 0x20; +} + +static unsigned char gen_lower(unsigned char ch) +{ + return tolower(ch); +} + +static unsigned char gen_quote(unsigned char ch) +{ + return !isascii(ch) || !isprint(ch) ? 4 : 1; +} + +/* VALID_B64: fail if 'ch' is not a valid base64 character */ +#define VALID_B64(ch) (((ch) >= 'A' && (ch) <= 'Z') || \ + ((ch) >= 'a' && (ch) <= 'z') || \ + ((ch) >= '0' && (ch) <= '9') || \ + (ch) == '/' || (ch) == '+' || (ch) == '=') + +/* DECODE_B64: decodes a valid base64 character. */ +#define DECODE_B64(ch) ((ch) >= 'a' ? ((ch) + 26 - 'a') : \ + ((ch) >= 'A' ? ((ch) - 'A') : \ + ((ch) >= '0' ? ((ch) + 52 - '0') : \ + ((ch) == '+' ? 62 : 63)))) + +static unsigned char valid_b64(unsigned char ch) +{ + return VALID_B64(ch) ? 1 : 0; +} + +static unsigned char decode_b64(unsigned char ch) +{ + return DECODE_B64(ch); +} + +#define QT 3 +#define NQ 1 + +static unsigned char gen_extparam(unsigned char ch) +{ + switch (ch) { + case '!': case '#': case '$': case '&': case '+': case '-': case '.': + case '^': case '_': case '`': case '|': case '~': + return NQ; + default: + return isalnum(ch) ? NQ : QT; + } +} + +#define FLAG_DECIMAL (0x01) +#define FLAG_SHORT (0x02) + +static const struct { + const char *name; + generator fn; + unsigned flags; +} generators[] = { + { "strclean", gen_clean, 0 }, + { "tolower", gen_lower, 0 }, + { "validb64", valid_b64, FLAG_DECIMAL | FLAG_SHORT }, + { "decodeb64", decode_b64, 0 }, + { "quote", gen_quote, FLAG_DECIMAL | FLAG_SHORT }, + { "extparam", gen_extparam, FLAG_DECIMAL | FLAG_SHORT }, +}; + +static void fail(const char *err, const char *arg) +{ + printf("mktable: %s (%s)\n", err, arg); + exit(1); +} + +int main(int argc, const char **argv) +{ + generator fn = NULL; + unsigned n, wrap, flags = 0; + + if (argc != 2) { + fail("No generator given", "missing argument"); + } + + for (n = 0; n < sizeof(generators) / sizeof(generators[0]); n++) { + if (strcmp(generators[n].name, argv[1]) == 0) { + fn = generators[n].fn; + flags = generators[n].flags; + break; + } + } + + if (fn == NULL) { + fail("Unrecognized generator name", argv[1]); + } + + wrap = (flags & FLAG_SHORT) ? 16 : 8; + + printf("/* Generated with 'mktable %s', do not alter here -- */\n", argv[1]); + printf("static const unsigned char table_%s[256] = {", argv[1]); + for (n = 0; n < 256; n++) { + unsigned ch = fn(n); + if (n % wrap == 0) + printf("%s\n/* x%02X */ ", n > 0 ? "," : "", n); + else + printf(", "); + if (flags & FLAG_DECIMAL) + printf("%u", ch); + else + printf("0x%02x", ch); + } + + printf("\n}; /* -- Generated code from 'mktable %s' ends. */\n", argv[1]); + + return 0; +} diff --git a/src/ne_string.c b/src/ne_string.c index 4793a07..d423d1b 100644 --- a/src/ne_string.c +++ b/src/ne_string.c @@ -259,27 +259,27 @@ void ne_buffer_altered(ne_buffer *buf) buf->used = strlen(buf->data) + 1; } - /* ascii_quote[n] gives the number of bytes needed by * ne_buffer_qappend() to append character 'n'. */ -static const unsigned char ascii_quote[256] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 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, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -}; +/* Generated with 'mktable quote', do not alter here -- */ +static const unsigned char table_quote[256] = { +/* x00 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* x10 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* x20 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, +/* x80 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* x90 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* xA0 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* xB0 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* xC0 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* xD0 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* xE0 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +/* xF0 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; /* -- Generated code ends. */ static const char hex_chars[16] = "0123456789abcdef"; @@ -292,7 +292,7 @@ static size_t qappend_count(const unsigned char *s, const unsigned char *send) size_t ret; for (p = s, ret = 0; p < send; p++) { - ret += ascii_quote[*p]; + ret += table_quote[*p]; } return ret; @@ -307,7 +307,7 @@ static char *quoted_append(char *dest, const unsigned char *s, char *q = dest; for (p = s; p < send; p++) { - if (ascii_quote[*p] == 1) { + if (table_quote[*p] == 1) { *q++ = *p; } else { @@ -398,17 +398,64 @@ char *ne_base64(const unsigned char *text, size_t inlen) return buffer; } -/* VALID_B64: fail if 'ch' is not a valid base64 character */ -#define VALID_B64(ch) (((ch) >= 'A' && (ch) <= 'Z') || \ - ((ch) >= 'a' && (ch) <= 'z') || \ - ((ch) >= '0' && (ch) <= '9') || \ - (ch) == '/' || (ch) == '+' || (ch) == '=') - -/* DECODE_B64: decodes a valid base64 character. */ -#define DECODE_B64(ch) ((ch) >= 'a' ? ((ch) + 26 - 'a') : \ - ((ch) >= 'A' ? ((ch) - 'A') : \ - ((ch) >= '0' ? ((ch) + 52 - '0') : \ - ((ch) == '+' ? 62 : 63)))) +/* Generated with 'mktable validb64', do not alter here -- */ +static const unsigned char table_validb64[256] = { +/* x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, +/* x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, +/* x40 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, +/* x60 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, +/* x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* xA0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* xB0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* xC0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* xD0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* xE0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* xF0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; /* -- Generated code ends. */ + +/* Generated with 'mktable decodeb64', do not alter here -- */ +static const unsigned char table_decodeb64[256] = { +/* x00 */ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +/* x08 */ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +/* x10 */ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +/* x18 */ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +/* x20 */ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +/* x28 */ 0x3f, 0x3f, 0x3f, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, +/* x30 */ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, +/* x38 */ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, +/* x40 */ 0x44, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, +/* x48 */ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, +/* x50 */ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, +/* x58 */ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, +/* x60 */ 0x1f, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, +/* x68 */ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, +/* x70 */ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, +/* x78 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, +/* x80 */ 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, +/* x88 */ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, +/* x90 */ 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, +/* x98 */ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, +/* xA0 */ 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, +/* xA8 */ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, +/* xB0 */ 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, +/* xB8 */ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, +/* xC0 */ 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, +/* xC8 */ 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, +/* xD0 */ 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, +/* xD8 */ 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, +/* xE0 */ 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, +/* xE8 */ 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, +/* xF0 */ 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, +/* xF8 */ 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8 +}; /* -- Generated code ends. */ + +#define DECODE_B64(ch) table_decodeb64[ch] +#define VALID_B64(ch) table_validb64[ch] size_t ne_unbase64(const char *data, unsigned char **out) { @@ -444,49 +491,50 @@ size_t ne_unbase64(const char *data, unsigned char **out) return outp - *out; } -/* Character map array; ascii_clean[n] = isprint(n) ? n : 0x20. Used +/* Character map array; table_strclean[n] = isprint(n) ? n : 0x20. Used * by ne_strclean as a locale-independent isprint(). */ -static const unsigned char ascii_clean[256] = { - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 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, 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, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 -}; +/* Generated with 'mktable strclean', do not alter here -- */ +static const unsigned char table_strclean[256] = { +/* x00 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* x08 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* x10 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* x18 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* x20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, +/* x28 */ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, +/* x30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +/* x38 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, +/* x40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, +/* x48 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +/* x50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, +/* x58 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, +/* x60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +/* x68 */ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, +/* x70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, +/* x78 */ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x20, +/* x80 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* x88 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* x90 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* x98 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xA0 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xA8 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xB0 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xB8 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xC0 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xC8 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xD0 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xD8 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xE0 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xE8 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xF0 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +/* xF8 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 +}; /* -- Generated code ends. */ char *ne_strclean(char *str) { unsigned char *pnt; for (pnt = (unsigned char *)str; *pnt; pnt++) - *pnt = (char)ascii_clean[*pnt]; + *pnt = (char)table_strclean[*pnt]; return str; } @@ -541,47 +589,47 @@ size_t ne_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) return strlen(str); } -/* Locale-independent strcasecmp implementations. */ -static const unsigned char 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 -}; - -#define TOLOWER(ch) ascii_tolower[ch] +/* Generated with 'mktable tolower', do not alter here -- */ +static const unsigned char table_tolower[256] = { +/* x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +/* x08 */ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, +/* x10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, +/* x18 */ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, +/* x20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, +/* x28 */ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, +/* x30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +/* x38 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, +/* x40 */ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +/* x48 */ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, +/* x50 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, +/* x58 */ 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, +/* x60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +/* x68 */ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, +/* x70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, +/* x78 */ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, +/* x80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, +/* x88 */ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, +/* x90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, +/* x98 */ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, +/* xa0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, +/* xa8 */ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, +/* xb0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, +/* xb8 */ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, +/* xc0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, +/* xc8 */ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, +/* xd0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, +/* xd8 */ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, +/* xe0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, +/* xe8 */ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, +/* xf0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, +/* xf8 */ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; /* -- Generated code ends. */ + +#define TOLOWER(ch) table_tolower[ch] const unsigned char *ne_tolower_array(void) { - return ascii_tolower; + return table_tolower; } int ne_strcasecmp(const char *s1, const char *s2) @@ -691,32 +739,26 @@ char *ne__strhash2hex(const unsigned char *digest, size_t len, return rv; } -/* Determines whether a character is valid in a regular parameter (NQ) - * not (QT). Per https://tools.ietf.org/html/rfc5987#section-3.2.1 - * every character in attr-char is NQ, everything else is QT. */ -#define QT 3 -#define NQ 1 -static const unsigned char ext_notation[256] = { -/* 0xXX x0 x2 x4 x6 x8 xA xC xE */ -/* 0x */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* 1x */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* 2x */ QT, NQ, QT, NQ, NQ, QT, NQ, QT, QT, QT, QT, NQ, QT, NQ, NQ, QT, -/* 3x */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* 4x */ QT, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, -/* 5x */ NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, QT, QT, QT, NQ, NQ, -/* 6x */ NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, -/* 7x */ NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, NQ, QT, NQ, QT, NQ, QT, -/* 8x */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* 9x */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* Ax */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* Bx */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* Cx */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* Dx */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* Ex */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, -/* Fx */ QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT, QT -}; -#undef QT -#undef NQ + +/* Generated with 'mktable extparam', do not alter here -- */ +static const unsigned char table_extparam[256] = { +/* x00 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* x10 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* x20 */ 3, 1, 3, 1, 1, 3, 1, 3, 3, 3, 3, 1, 3, 1, 1, 3, +/* x30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, +/* x40 */ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, +/* x60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x70 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 3, +/* x80 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* x90 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* xA0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* xB0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* xC0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* xD0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* xE0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +/* xF0 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +}; /* -- Generated code from 'mktable extparam' ends. */ char *ne_strparam(const char *charset, const char *lang, const unsigned char *value) @@ -727,7 +769,7 @@ char *ne_strparam(const char *charset, const char *lang, /* Determine length required for the value. */ for (p = value; *p; p++) - count += ext_notation[*p]; + count += table_extparam[*p]; /* If length == input length, no encoding is required, return * NULL. */ @@ -745,7 +787,7 @@ char *ne_strparam(const char *charset, const char *lang, *rp++ = '\''; for (p = value; *p; p++) { - if (ext_notation[*p] == 1) { + if (table_extparam[*p] == 1) { *rp++ = *p; } else { diff --git a/test/string-tests.c b/test/string-tests.c index 2bfd911..512fd8a 100644 --- a/test/string-tests.c +++ b/test/string-tests.c @@ -758,6 +758,7 @@ static int strparam(void) const char *expect; } ts[] = { { "UTF-8", NULL, "foobar", NULL }, + { "UTF-8", NULL, "foo12345bar", NULL }, { "UTF-8", NULL, "foo@bar", "UTF-8''foo%40bar" }, { "UTF-8", NULL, "foo bar", "UTF-8''foo%20bar" }, { "iso-8859-1", "en", "\xA3 rates", "iso-8859-1'en'%a3%20rates" }, @@ -770,7 +771,8 @@ static int strparam(void) char *act = ne_strparam(ts[n].charset, ts[n].lang, (const unsigned char *)ts[n].value); if (ts[n].expect == NULL) { - ONV(act != NULL, ("expected NULL output for '%s'", ts[n].value)); + ONV(act != NULL, ("expected NULL output for '%s', got '%s'", + ts[n].value, act)); } else { ONCMP(act, ts[n].expect); |