diff options
author | Jakob Schlyter <jakob@cvs.openbsd.org> | 2010-04-15 20:57:17 +0000 |
---|---|---|
committer | Jakob Schlyter <jakob@cvs.openbsd.org> | 2010-04-15 20:57:17 +0000 |
commit | 182fa5a050d9cc4f382dd7d1d799f90fa711345a (patch) | |
tree | 214e2fe99408ac2d41fb23dad42cc2cc94850e81 /usr.sbin/nsd/compat | |
parent | ea33ab4b0ef2e0a4e072a0a3ada4bcbe9d1eea71 (diff) |
NSD v3.2.5
Diffstat (limited to 'usr.sbin/nsd/compat')
-rw-r--r-- | usr.sbin/nsd/compat/b64_pton.c | 222 | ||||
-rw-r--r-- | usr.sbin/nsd/compat/memcmp.c | 25 | ||||
-rw-r--r-- | usr.sbin/nsd/compat/snprintf.c | 6 | ||||
-rw-r--r-- | usr.sbin/nsd/compat/strlcat.c | 73 |
4 files changed, 283 insertions, 43 deletions
diff --git a/usr.sbin/nsd/compat/b64_pton.c b/usr.sbin/nsd/compat/b64_pton.c index b69bb21bfe3..08506040b64 100644 --- a/usr.sbin/nsd/compat/b64_pton.c +++ b/usr.sbin/nsd/compat/b64_pton.c @@ -107,9 +107,9 @@ static const char Pad64 = '='; end of the data is performed using the '=' character. Since all base64 input is an integral number of octets, only the - ------------------------------------------------- + ------------------------------------------------- following cases can arise: - + (1) the final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters @@ -128,65 +128,101 @@ static const char Pad64 = '='; it returns the number of data bytes stored at the target, or -1 on error. */ -int -b64_pton(char const *src, uint8_t *target, size_t targsize) +static int b64rmap_initialized = 0; +static uint8_t b64rmap[256]; + +static const uint8_t b64rmap_special = 0xf0; +static const uint8_t b64rmap_end = 0xfd; +static const uint8_t b64rmap_space = 0xfe; +static const uint8_t b64rmap_invalid = 0xff; + +/** + * Initializing the reverse map is not thread safe. + * Which is fine for NSD. For now... + **/ +static void +b64_initialize_rmap () +{ + int i; + char ch; + + /* Null: end of string, stop parsing */ + b64rmap[0] = b64rmap_end; + + for (i = 1; i < 256; ++i) { + ch = (char)i; + /* Whitespaces */ + if (isspace(ch)) + b64rmap[i] = b64rmap_space; + /* Padding: stop parsing */ + else if (ch == Pad64) + b64rmap[i] = b64rmap_end; + /* Non-base64 char */ + else + b64rmap[i] = b64rmap_invalid; + } + + /* Fill reverse mapping for base64 chars */ + for (i = 0; Base64[i] != '\0'; ++i) + b64rmap[(uint8_t)Base64[i]] = i; + + b64rmap_initialized = 1; +} + +static int +b64_pton_do(char const *src, uint8_t *target, size_t targsize) { int tarindex, state, ch; - char *pos; + uint8_t ofs; state = 0; tarindex = 0; - while ((ch = *src++) != '\0') { - if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */ - continue; + while (1) + { + ch = *src++; + ofs = b64rmap[ch]; - if (ch == Pad64) - break; - - pos = strchr(Base64, ch); - if (pos == 0) { + if (ofs >= b64rmap_special) { + /* Ignore whitespaces */ + if (ofs == b64rmap_space) + continue; + /* End of base64 characters */ + if (ofs == b64rmap_end) + break; /* A non-base64 character. */ return (-1); } switch (state) { case 0: - if (target) { - if ((size_t)tarindex >= targsize) - return (-1); - target[tarindex] = (pos - Base64) << 2; - } + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] = ofs << 2; state = 1; break; case 1: - if (target) { - if ((size_t)tarindex + 1 >= targsize) - return (-1); - target[tarindex] |= (pos - Base64) >> 4; - target[tarindex+1] = ((pos - Base64) & 0x0f) - << 4 ; - } + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= ofs >> 4; + target[tarindex+1] = (ofs & 0x0f) + << 4 ; tarindex++; state = 2; break; case 2: - if (target) { - if ((size_t)tarindex + 1 >= targsize) - return (-1); - target[tarindex] |= (pos - Base64) >> 2; - target[tarindex+1] = ((pos - Base64) & 0x03) - << 6; - } + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= ofs >> 2; + target[tarindex+1] = (ofs & 0x03) + << 6; tarindex++; state = 3; break; case 3: - if (target) { - if ((size_t)tarindex >= targsize) - return (-1); - target[tarindex] |= (pos - Base64); - } + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] |= ofs; tarindex++; state = 0; break; @@ -210,7 +246,7 @@ b64_pton(char const *src, uint8_t *target, size_t targsize) case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ for ((void)NULL; ch != '\0'; ch = *src++) - if (!isspace((unsigned char)ch)) + if (b64rmap[ch] != b64rmap_space) break; /* Make sure there is another trailing = sign. */ if (ch != Pad64) @@ -225,7 +261,7 @@ b64_pton(char const *src, uint8_t *target, size_t targsize) * whitespace after it? */ for ((void)NULL; ch != '\0'; ch = *src++) - if (!isspace((unsigned char)ch)) + if (b64rmap[ch] != b64rmap_space) return (-1); /* @@ -234,7 +270,7 @@ b64_pton(char const *src, uint8_t *target, size_t targsize) * zeros. If we don't check them, they become a * subliminal channel. */ - if (target && target[tarindex] != 0) + if (target[tarindex] != 0) return (-1); } } else { @@ -248,3 +284,109 @@ b64_pton(char const *src, uint8_t *target, size_t targsize) return (tarindex); } + + +static int +b64_pton_len(char const *src) +{ + int tarindex, state, ch; + uint8_t ofs; + + state = 0; + tarindex = 0; + + while (1) + { + ch = *src++; + ofs = b64rmap[ch]; + + if (ofs >= b64rmap_special) { + /* Ignore whitespaces */ + if (ofs == b64rmap_space) + continue; + /* End of base64 characters */ + if (ofs == b64rmap_end) + break; + /* A non-base64 character. */ + return (-1); + } + + switch (state) { + case 0: + state = 1; + break; + case 1: + tarindex++; + state = 2; + break; + case 2: + tarindex++; + state = 3; + break; + case 3: + tarindex++; + state = 0; + break; + default: + abort(); + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (b64rmap[ch] != b64rmap_space) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (b64rmap[ch] != b64rmap_space) + return (-1); + + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + + +int +b64_pton(char const *src, uint8_t *target, size_t targsize) +{ + if (!b64rmap_initialized) + b64_initialize_rmap (); + + if (target) + return b64_pton_do (src, target, targsize); + else + return b64_pton_len (src); +} diff --git a/usr.sbin/nsd/compat/memcmp.c b/usr.sbin/nsd/compat/memcmp.c new file mode 100644 index 00000000000..9446276f410 --- /dev/null +++ b/usr.sbin/nsd/compat/memcmp.c @@ -0,0 +1,25 @@ +/* + * memcmp.c: memcmp compat implementation. + * + * Copyright (c) 2010, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. +*/ + +#include <config.h> + +int memcmp(const void *x, const void *y, size_t n); + +int memcmp(const void *x, const void *y, size_t n) +{ + const uint8_t* x8 = (const uint8_t*)x; + const uint8_t* y8 = (const uint8_t*)y; + size_t i; + for(i=0; i<n; i++) { + if(x8[i] < y8[i]) + return -1; + else if(x8[i] > y8[i]) + return 1; + } + return 0; +} diff --git a/usr.sbin/nsd/compat/snprintf.c b/usr.sbin/nsd/compat/snprintf.c index 674cc09c81d..52429edf06d 100644 --- a/usr.sbin/nsd/compat/snprintf.c +++ b/usr.sbin/nsd/compat/snprintf.c @@ -671,15 +671,15 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, */ dopr_outch (buffer, currlen, maxlen, '.'); - while (fplace > 0) - dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); - while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + while (padlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); diff --git a/usr.sbin/nsd/compat/strlcat.c b/usr.sbin/nsd/compat/strlcat.c new file mode 100644 index 00000000000..cc5a5918d2e --- /dev/null +++ b/usr.sbin/nsd/compat/strlcat.c @@ -0,0 +1,73 @@ +/* compat/strlcat.c */ + +/*- + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */ + +#include <config.h> +#ifndef HAVE_STRLCAT + +#include <sys/types.h> +#include <string.h> + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCAT */ |