summaryrefslogtreecommitdiff
path: root/usr.sbin/nsd/compat
diff options
context:
space:
mode:
authorJakob Schlyter <jakob@cvs.openbsd.org>2010-04-15 20:57:17 +0000
committerJakob Schlyter <jakob@cvs.openbsd.org>2010-04-15 20:57:17 +0000
commit182fa5a050d9cc4f382dd7d1d799f90fa711345a (patch)
tree214e2fe99408ac2d41fb23dad42cc2cc94850e81 /usr.sbin/nsd/compat
parentea33ab4b0ef2e0a4e072a0a3ada4bcbe9d1eea71 (diff)
NSD v3.2.5
Diffstat (limited to 'usr.sbin/nsd/compat')
-rw-r--r--usr.sbin/nsd/compat/b64_pton.c222
-rw-r--r--usr.sbin/nsd/compat/memcmp.c25
-rw-r--r--usr.sbin/nsd/compat/snprintf.c6
-rw-r--r--usr.sbin/nsd/compat/strlcat.c73
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 */