summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-01 09:03:04 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-01 09:03:04 +0000
commitd026ceb087a6bf4d7616572ba1853c011ea34b42 (patch)
treede39e5cc7b04ff50dc0d7e00c0aa615c40b5adcf
parent697e7bf450581ae928eabd18fa93f6d4baefeb6d (diff)
automatic import of apropeneuler24.03_LTS
-rw-r--r--.gitignore1
-rw-r--r--apr-1.2.2-libdir.patch18
-rw-r--r--apr-1.2.7-pkgconf.patch56
-rw-r--r--apr-1.7.0-deepbind.patch60
-rw-r--r--apr-1.7.0-encoding.patch2839
-rw-r--r--apr-1.7.0-r1891269+.patch239
-rw-r--r--apr-1.7.0-r1894167.patch37
-rw-r--r--apr-wrapper.h22
-rw-r--r--apr.spec669
-rw-r--r--sources1
10 files changed, 3942 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..3204f19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/apr-1.7.0.tar.bz2
diff --git a/apr-1.2.2-libdir.patch b/apr-1.2.2-libdir.patch
new file mode 100644
index 0000000..aeb7ee1
--- /dev/null
+++ b/apr-1.2.2-libdir.patch
@@ -0,0 +1,18 @@
+
+- avoid adding %{_libdir} to --link-ld output
+
+--- apr-1.2.2/apr-config.in.libdir
++++ apr-1.2.2/apr-config.in
+@@ -181,8 +181,10 @@
+ ;;
+ --link-ld)
+ if test "$location" = "installed"; then
+- ### avoid using -L if libdir is a "standard" location like /usr/lib
+- flags="$flags -L$libdir -l${APR_LIBNAME}"
++ if test "$prefix" != "/usr"; then
++ flags="$flags -L$libdir"
++ fi
++ flags="$flags -l${APR_LIBNAME}"
+ else
+ ### this surely can't work since the library is in .libs?
+ flags="$flags -L$APR_BUILD_DIR -l${APR_LIBNAME}"
diff --git a/apr-1.2.7-pkgconf.patch b/apr-1.2.7-pkgconf.patch
new file mode 100644
index 0000000..bd6d65c
--- /dev/null
+++ b/apr-1.2.7-pkgconf.patch
@@ -0,0 +1,56 @@
+
+This is a fugly hack to make apr-1-config libdir-agnostic, by using
+pkg-config to determine the libdir setting. pkg-config will
+magically determine the appropriate libdir setting.
+
+This allows apr-devel.i386 and apr-devel.x86_64 to be
+installed in parallel.
+
+--- apr-1.2.7/Makefile.in.pkgconf
++++ apr-1.2.7/Makefile.in
+@@ -60,7 +60,7 @@
+
+ # Create apr-config script suitable for the install tree
+ apr-config.out: $(APR_CONFIG)
+- sed 's,^\(location=\).*$$,\1installed,' < $(APR_CONFIG) > $@
++ sed 's,^\(location=\).*$$,\1installed,;s,^\(APR_.*_DIR\)=.*,\1="$${libdir}/build",' < $(APR_CONFIG) > $@
+
+ # Create apr_rules.mk suitable for the install tree
+ build/apr_rules.out: build/apr_rules.mk
+--- apr-1.2.7/apr.pc.in.pkgconf
++++ apr-1.2.7/apr.pc.in
+@@ -3,9 +3,10 @@
+ libdir=@libdir@
+ APR_MAJOR_VERSION=@APR_MAJOR_VERSION@
+ includedir=@includedir@
++CPPFLAGS=@EXTRA_CPPFLAGS@
+
+ Name: APR
+ Description: The Apache Portable Runtime library
+ Version: @APR_DOTTED_VERSION@
+ Libs: -L${libdir} -l@APR_LIBNAME@ @EXTRA_LIBS@
+-Cflags: @EXTRA_CPPFLAGS@ @EXTRA_CFLAGS@ -I${includedir}
++Cflags: ${CPPFLAGS} @EXTRA_CFLAGS@ -I${includedir}
+--- apr-1.2.7/apr-config.in.pkgconf
++++ apr-1.2.7/apr-config.in
+@@ -24,16 +24,17 @@
+ prefix="@prefix@"
+ exec_prefix="@exec_prefix@"
+ bindir="@bindir@"
+-libdir="@libdir@"
+ datarootdir="@datadir@"
+ datadir="@datadir@"
+-installbuilddir="@installbuilddir@"
+ includedir="@includedir@"
+
++libdir=`pkg-config --variable=libdir apr-@APR_MAJOR_VERSION@`
++installbuilddir="${libdir}/apr-@APR_MAJOR_VERSION@/build"
++
+ CC="@CC@"
+ CPP="@CPP@"
+ SHELL="@SHELL@"
+-CPPFLAGS="@EXTRA_CPPFLAGS@"
++CPPFLAGS=`pkg-config --variable=CPPFLAGS apr-@APR_MAJOR_VERSION@`
+ CFLAGS="@EXTRA_CFLAGS@"
+ LDFLAGS="@EXTRA_LDFLAGS@"
+ LIBS="@EXTRA_LIBS@"
diff --git a/apr-1.7.0-deepbind.patch b/apr-1.7.0-deepbind.patch
new file mode 100644
index 0000000..3a40d22
--- /dev/null
+++ b/apr-1.7.0-deepbind.patch
@@ -0,0 +1,60 @@
+
+Add $APR_DEEPBIND to enable use of RTLD_DEEPBIND in apr_dso_open().
+
+--- apr-1.7.0/dso/unix/dso.c.deepbind
++++ apr-1.7.0/dso/unix/dso.c
+@@ -38,6 +38,8 @@
+ #define DYLD_LIBRARY_HANDLE (void *)-1
+ #endif
+
++static int use_deepbind; /* 0 = unset, 1 = use DEEPBIND, -1, don't use DEEPBIND */
++
+ APR_DECLARE(apr_status_t) apr_os_dso_handle_put(apr_dso_handle_t **aprdso,
+ apr_os_dso_handle_t osdso,
+ apr_pool_t *pool)
+@@ -125,6 +127,12 @@
+ #else
+ int flags = RTLD_NOW | RTLD_GLOBAL;
+ void *os_handle;
++
++ if (use_deepbind == 0)
++ use_deepbind = secure_getenv("APR_DEEPBIND") != NULL ? 1 : -1;
++ if (use_deepbind == 1)
++ flags |= RTLD_DEEPBIND;
++
+ #ifdef _AIX
+ if (strchr(path + 1, '(') && path[strlen(path) - 1] == ')')
+ {
+--- apr-1.7.0/README.deepbind.deepbind
++++ apr-1.7.0/README.deepbind
+@@ -0,0 +1,30 @@
++This distribution of APR contains a modification of the behaviour of
++the apr_dso_open() function which allows users enable the
++"RTLD_DEEPBIND" flag when dlopen() is called.
++
++If the "APR_DEEPBIND" environment variable is set at runtime, the
++RTLD_DEEPBIND flag is always added to the flags passed to dlopen().
++
++With normal use of dlopen(), dynamically loaded objects will use
++global symbols in preference to any symbols defined within the object.
++Using RTLD_DEEPBIND reverses this binding order. See the dlopen(3)
++man page for more information.
++
++This can be useful with Apache httpd, where two different modules are
++loaded like:
++
++1. mod_foo.so uses library "libfoo.so"
++ libfoo.so defines a function "SomeSym"
++2. mod_bar.so uses library "libbar.so"
++ libbar.so defines a different "SomeSym" function
++
++By default, mod_bar or mod_foo would use the "SomeSym" definition from
++the "wrong" library depending on the load order. If RTLD_DEEPBIND is
++used, the "SomeSym" definition will always be mapped to the definition
++from the corresponding dependent library. This can avoid symbol
++conflicts.
++
++There are some risks with using RTLD_DEEPBIND, in particular potential
++issues with modules written in C++. It is not recommended to enable
++$APR_DEEPBIND unless it solves a specific problem and after thorough
++testing of the configuration.
diff --git a/apr-1.7.0-encoding.patch b/apr-1.7.0-encoding.patch
new file mode 100644
index 0000000..f6c9dae
--- /dev/null
+++ b/apr-1.7.0-encoding.patch
@@ -0,0 +1,2839 @@
+
+https://svn.apache.org/viewvc?view=revision&revision=1877195
+https://svn.apache.org/viewvc?view=revision&revision=1883879
+https://svn.apache.org/viewvc?view=revision&revision=1883880
+https://svn.apache.org/viewvc?view=revision&revision=1904675
+
+--- apr-1.7.0/encoding/apr_encode.c.encoding
++++ apr-1.7.0/encoding/apr_encode.c
+@@ -211,19 +211,20 @@
+ APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ {
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+ const char *base;
+
+- if (!src) {
+- return APR_NOTFOUND;
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
+ }
+-
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+ if (dest) {
+- register char *bufout = dest;
+- int i;
++ char *bufout = dest;
++ apr_size_t i = 0;
+
+ if (0 == ((flags & APR_ENCODE_BASE64URL))) {
+ base = base64;
+@@ -232,60 +233,64 @@
+ base = base64url;
+ }
+
+- for (i = 0; i < slen - 2; i += 3) {
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i]) >> 2) & 0x3F)];
+- *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4)
+- | ((int)((src[i + 1]) & 0xF0) >> 4))];
+- *bufout++ = base[ENCODE_TO_ASCII((((src[i + 1]) & 0xF) << 2)
+- | ((int)(ENCODE_TO_ASCII(src[i + 2]) & 0xC0) >> 6))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 2]) & 0x3F)];
+- }
+- if (i < slen) {
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i]) >> 2) & 0x3F)];
+- if (i == (slen - 1)) {
+- *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4))];
++ if (count > 2) {
++ for (; i < count - 2; i += 3) {
++ *bufout++ = base[(TO_ASCII(src[i]) >> 2) & 0x3F];
++ *bufout++ = base[((TO_ASCII(src[i]) & 0x3) << 4 |
++ (TO_ASCII(src[i + 1]) & 0xF0) >> 4)];
++ *bufout++ = base[((TO_ASCII(src[i + 1]) & 0xF) << 2 |
++ (TO_ASCII(src[i + 2]) & 0xC0) >> 6)];
++ *bufout++ = base[TO_ASCII(src[i + 2]) & 0x3F];
++ }
++ }
++ if (i < count) {
++ *bufout++ = base[(TO_ASCII(src[i]) >> 2) & 0x3F];
++ if (i == (count - 1)) {
++ *bufout++ = base[(TO_ASCII(src[i]) & 0x3) << 4];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ }
+ }
+ else {
+- *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4)
+- | ((int)((src[i + 1]) & 0xF0) >> 4))];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1]) & 0xF) << 2)];
++ *bufout++ = base[((TO_ASCII(src[i]) & 0x3) << 4 |
++ (TO_ASCII(src[i + 1]) & 0xF0) >> 4)];
++ *bufout++ = base[(TO_ASCII(src[i + 1]) & 0xF) << 2];
+ }
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ }
+ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
++ dest[dlen] = '\0';
++ }
++ else {
++ dlen = ((count + 2u) / 3u) * 4u + 1u;
++ if (dlen <= count) {
++ status = APR_ENOSPC;
+ }
+-
+- *bufout++ = '\0';
+-
+- return APR_SUCCESS;
+ }
+
+ if (len) {
+- *len = ((slen + 2) / 3 * 4) + 1;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ {
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+ const char *base;
+
+- if (!src) {
+- return APR_NOTFOUND;
++ if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+ if (dest) {
+- register char *bufout = dest;
+- int i;
++ char *bufout = dest;
++ apr_size_t i = 0;
+
+ if (0 == ((flags & APR_ENCODE_BASE64URL))) {
+ base = base64;
+@@ -294,46 +299,48 @@
+ base = base64url;
+ }
+
+- for (i = 0; i < slen - 2; i += 3) {
+- *bufout++ = base[(src[i] >> 2) & 0x3F];
+- *bufout++ = base[((src[i] & 0x3) << 4)
+- | ((int)(src[i + 1] & 0xF0) >> 4)];
+- *bufout++ = base[((src[i + 1] & 0xF) << 2)
+- | ((int)(src[i + 2] & 0xC0) >> 6)];
+- *bufout++ = base[src[i + 2] & 0x3F];
++ if (count > 2) {
++ for (; i < count - 2; i += 3) {
++ *bufout++ = base[(src[i] >> 2) & 0x3F];
++ *bufout++ = base[((src[i] & 0x3) << 4 |
++ (src[i + 1] & 0xF0) >> 4)];
++ *bufout++ = base[((src[i + 1] & 0xF) << 2 |
++ (src[i + 2] & 0xC0) >> 6)];
++ *bufout++ = base[src[i + 2] & 0x3F];
++ }
+ }
+- if (i < slen) {
++ if (i < count) {
+ *bufout++ = base[(src[i] >> 2) & 0x3F];
+- if (i == (slen - 1)) {
++ if (i == (count - 1)) {
+ *bufout++ = base[((src[i] & 0x3) << 4)];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ }
+ }
+ else {
+- *bufout++ = base[((src[i] & 0x3) << 4)
+- | ((int)(src[i + 1] & 0xF0) >> 4)];
+- *bufout++ = base[((src[i + 1] & 0xF) << 2)];
++ *bufout++ = base[((src[i] & 0x3) << 4 |
++ (src[i + 1] & 0xF0) >> 4)];
++ *bufout++ = base[(src[i + 1] & 0xF) << 2];
+ }
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ }
+ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
++ dest[dlen] = '\0';
++ }
++ else {
++ dlen = ((count + 2u) / 3u) * 4u + 1u;
++ if (dlen <= count) {
++ status = APR_ENOSPC;
+ }
+-
+- *bufout++ = '\0';
+-
+- return APR_SUCCESS;
+ }
+
+ if (len) {
+- *len = ((slen + 2) / 3 * 4) + 1;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src,
+@@ -341,13 +348,19 @@
+ {
+ apr_size_t size;
+
++ if (!src) {
++ return NULL;
++ }
++
+ switch (apr_encode_base64(NULL, src, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ char *cmd = apr_palloc(p, size);
+- apr_encode_base64(cmd, src, slen, flags, len);
++ if (cmd) {
++ apr_encode_base64(cmd, src, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -360,13 +373,19 @@
+ {
+ apr_size_t size;
+
++ if (!src) {
++ return NULL;
++ }
++
+ switch (apr_encode_base64_binary(NULL, src, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ char *cmd = apr_palloc(p, size);
+- apr_encode_base64_binary(cmd, src, slen, flags, len);
++ if (cmd) {
++ apr_encode_base64_binary(cmd, src, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -377,149 +396,184 @@
+ APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- if (!src) {
+- return APR_NOTFOUND;
+- }
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
++ }
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+- if (dest) {
+- register const unsigned char *bufin;
+- register unsigned char *bufout;
+- register apr_size_t nprbytes;
+- register apr_size_t count = slen;
+-
+- apr_status_t status;
++ if (src) {
++ const unsigned char *bufin;
+
+ bufin = (const unsigned char *)src;
+- while (pr2six[*(bufin++)] < 64 && count)
+- count--;
+- nprbytes = (bufin - (const unsigned char *)src) - 1;
+- while (pr2six[*(bufin++)] > 64 && count)
++ while (count) {
++ if (pr2six[*bufin] >= 64) {
++ if (!(flags & APR_ENCODE_RELAXED)) {
++ if (count <= 2) {
++ do {
++ if (pr2six[bufin[count - 1]] <= 64)
++ break;
++ } while (--count);
++ }
++ if (count) {
++ status = APR_BADCH;
++ }
++ }
++ break;
++ }
+ count--;
++ bufin++;
++ }
++ count = bufin - (const unsigned char *)src;
+
+- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
+- count ? APR_BADCH : APR_SUCCESS;
++ if (dest) {
++ unsigned char *bufout;
+
+- bufout = (unsigned char *)dest;
+- bufin = (const unsigned char *)src;
++ bufout = (unsigned char *)dest;
++ bufin = (const unsigned char *)src;
+
+- while (nprbytes > 4) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2six[bufin[0]] << 2
+- | pr2six[bufin[1]] >> 4);
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
+- bufin += 4;
+- nprbytes -= 4;
+- }
++ while (count >= 4) {
++ *(bufout++) = TO_NATIVE(pr2six[bufin[0]] << 2 |
++ pr2six[bufin[1]] >> 4);
++ *(bufout++) = TO_NATIVE(pr2six[bufin[1]] << 4 |
++ pr2six[bufin[2]] >> 2);
++ *(bufout++) = TO_NATIVE(pr2six[bufin[2]] << 6 |
++ pr2six[bufin[3]]);
++ bufin += 4;
++ count -= 4;
++ }
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
+- }
+- if (nprbytes > 1) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
+- }
+- if (nprbytes > 2) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
+- }
+- if (nprbytes > 3) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
+- }
++ if (count == 1) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count > 1) {
++ *(bufout++) = TO_NATIVE(pr2six[bufin[0]] << 2 |
++ pr2six[bufin[1]] >> 4);
++ }
++ if (count > 2) {
++ *(bufout++) = TO_NATIVE(pr2six[bufin[1]] << 4 |
++ pr2six[bufin[2]] >> 2);
++ }
+
+- if (len) {
+- *len = bufout - (unsigned char *)dest;
++ dlen = bufout - (unsigned char *)dest;
++ dest[dlen] = '\0';
+ }
++ }
+
+- *(bufout++) = 0;
+-
+- return status;
++ if (!src || !dest) {
++ dlen = (count / 4u) * 3u + 1u;
++ switch (count % 4) {
++ case 3:
++ dlen += 2;
++ break;
++ case 2:
++ dlen++;
++ break;
++ case 1:
++ status = APR_EINCOMPLETE;
++ break;
++ }
+ }
+
+ if (len) {
+- *len = (((int)slen + 3) / 4) * 3 + 1;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- if (!src) {
+- return APR_NOTFOUND;
+- }
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
++ }
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+- if (dest) {
+- register const unsigned char *bufin;
+- register unsigned char *bufout;
+- register apr_size_t nprbytes;
+- register apr_size_t count = slen;
+-
+- apr_status_t status;
++ if (src) {
++ const unsigned char *bufin;
+
+ bufin = (const unsigned char *)src;
+- while (pr2six[*(bufin++)] < 64 && count)
+- count--;
+- nprbytes = (bufin - (const unsigned char *)src) - 1;
+- while (pr2six[*(bufin++)] > 64 && count)
++ while (count) {
++ if (pr2six[*bufin] >= 64) {
++ if (!(flags & APR_ENCODE_RELAXED)) {
++ if (count <= 2) {
++ do {
++ if (pr2six[bufin[count - 1]] <= 64)
++ break;
++ } while (--count);
++ }
++ if (count) {
++ status = APR_BADCH;
++ }
++ }
++ break;
++ }
+ count--;
++ bufin++;
++ }
++ count = bufin - (const unsigned char *)src;
+
+- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
+- count ? APR_BADCH : APR_SUCCESS;
++ if (dest) {
++ unsigned char *bufout;
+
+- bufout = (unsigned char *)dest;
+- bufin = (const unsigned char *)src;
++ bufout = (unsigned char *)dest;
++ bufin = (const unsigned char *)src;
+
+- while (nprbytes > 4) {
+- *(bufout++) = (unsigned char)(pr2six[bufin[0]] << 2
+- | pr2six[bufin[1]] >> 4);
+- *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4
+- | pr2six[bufin[2]] >> 2);
+- *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6
+- | pr2six[bufin[3]]);
+- bufin += 4;
+- nprbytes -= 4;
+- }
++ while (count >= 4) {
++ *(bufout++) = (pr2six[bufin[0]] << 2 |
++ pr2six[bufin[1]] >> 4);
++ *(bufout++) = (pr2six[bufin[1]] << 4 |
++ pr2six[bufin[2]] >> 2);
++ *(bufout++) = (pr2six[bufin[2]] << 6 |
++ pr2six[bufin[3]]);
++ bufin += 4;
++ count -= 4;
++ }
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
+- }
+- if (nprbytes > 1) {
+- *(bufout++) = (unsigned char)(pr2six[bufin[0]] << 2
+- | pr2six[bufin[1]] >> 4);
+- }
+- if (nprbytes > 2) {
+- *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4
+- | pr2six[bufin[2]] >> 2);
+- }
+- if (nprbytes > 3) {
+- *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6
+- | pr2six[bufin[3]]);
+- }
++ if (count == 1) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count > 1) {
++ *(bufout++) = (pr2six[bufin[0]] << 2 |
++ pr2six[bufin[1]] >> 4);
++ }
++ if (count > 2) {
++ *(bufout++) = (pr2six[bufin[1]] << 4 |
++ pr2six[bufin[2]] >> 2);
++ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
+ }
++ }
+
+- return status;
++ if (!src || !dest) {
++ dlen = (count / 4u) * 3u;
++ switch (count % 4) {
++ case 3:
++ dlen += 2;
++ break;
++ case 2:
++ dlen++;
++ break;
++ case 1:
++ status = APR_EINCOMPLETE;
++ break;
++ }
+ }
+
+ if (len) {
+- *len = (((int)slen + 3) / 4) * 3;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *str,
+@@ -527,14 +581,19 @@
+ {
+ apr_size_t size;
+
++ if (!str) {
++ return NULL;
++ }
++
+ switch (apr_decode_base64(NULL, str, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ void *cmd = apr_palloc(p, size);
+- apr_decode_base64(cmd, str, slen, flags, len);
++ if (cmd) {
++ apr_decode_base64(cmd, str, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_BADCH:
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -547,15 +606,20 @@
+ {
+ apr_size_t size;
+
++ if (!str) {
++ return NULL;
++ }
++
+ switch (apr_decode_base64_binary(NULL, str, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ unsigned char *cmd = apr_palloc(p, size + 1);
+- cmd[size] = 0;
+- apr_decode_base64_binary(cmd, str, slen, flags, len);
++ if (cmd) {
++ apr_decode_base64_binary(cmd, str, slen, flags, len);
++ cmd[size] = 0;
++ }
+ return cmd;
+ }
+- case APR_BADCH:
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -566,19 +630,20 @@
+ APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ {
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+ const char *base;
+
+- if (!src) {
+- return APR_NOTFOUND;
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
+ }
+-
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+ if (dest) {
+- register char *bufout = dest;
+- int i;
++ char *bufout = dest;
++ apr_size_t i = 0;
+
+ if (!((flags & APR_ENCODE_BASE32HEX))) {
+ base = base32;
+@@ -587,24 +652,26 @@
+ base = base32hex;
+ }
+
+- for (i = 0; i < slen - 4; i += 5) {
+- *bufout++ = base[ENCODE_TO_ASCII((src[i] >> 3) & 0x1F)];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
+- | ((src[i + 2] >> 4) & 0xF))];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i + 2] << 1) & 0x1E)
+- | ((src[i + 3] >> 7) & 0x1))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] >> 2) & 0x1F)];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i + 3] << 3) & 0x18)
+- | ((src[i + 4] >> 5) & 0x7))];
+- *bufout++ = base[ENCODE_TO_ASCII(src[i + 4] & 0x1F)];
+- }
+- if (i < slen) {
+- *bufout++ = base[ENCODE_TO_ASCII(src[i] >> 3) & 0x1F];
+- if (i == (slen - 1)) {
+- *bufout++ = base[ENCODE_TO_ASCII((src[i] << 2) & 0x1C)];
++ if (count > 4) {
++ for (; i < count - 4; i += 5) {
++ *bufout++ = base[(TO_ASCII(src[i]) >> 3) & 0x1F];
++ *bufout++ = base[(((TO_ASCII(src[i]) << 2) & 0x1C) |
++ ((TO_ASCII(src[i + 1]) >> 6) & 0x3))];
++ *bufout++ = base[(TO_ASCII(src[i + 1]) >> 1) & 0x1F];
++ *bufout++ = base[(((TO_ASCII(src[i + 1]) << 4) & 0x10) |
++ ((TO_ASCII(src[i + 2]) >> 4) & 0xF))];
++ *bufout++ = base[(((TO_ASCII(src[i + 2]) << 1) & 0x1E) |
++ ((TO_ASCII(src[i + 3]) >> 7) & 0x1))];
++ *bufout++ = base[(TO_ASCII(src[i + 3]) >> 2) & 0x1F];
++ *bufout++ = base[(((TO_ASCII(src[i + 3]) << 3) & 0x18) |
++ ((TO_ASCII(src[i + 4]) >> 5) & 0x7))];
++ *bufout++ = base[TO_ASCII(src[i + 4]) & 0x1F];
++ }
++ }
++ if (i < count) {
++ *bufout++ = base[(TO_ASCII(src[i]) >> 3) & 0x1F];
++ if (i == (count - 1)) {
++ *bufout++ = base[(TO_ASCII(src[i]) << 2) & 0x1C];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ *bufout++ = '=';
+@@ -614,11 +681,11 @@
+ *bufout++ = '=';
+ }
+ }
+- else if (i == (slen - 2)) {
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] << 4) & 0x10)];
++ else if (i == (count - 2)) {
++ *bufout++ = base[(((TO_ASCII(src[i]) << 2) & 0x1C) |
++ ((TO_ASCII(src[i + 1]) >> 6) & 0x3))];
++ *bufout++ = base[(TO_ASCII(src[i + 1]) >> 1) & 0x1F];
++ *bufout++ = base[(TO_ASCII(src[i + 1]) << 4) & 0x10];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ *bufout++ = '=';
+@@ -626,13 +693,13 @@
+ *bufout++ = '=';
+ }
+ }
+- else if (i == (slen - 3)) {
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
+- | ((src[i + 2] >> 4) & 0xF))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 2] << 1) & 0x1E)];
++ else if (i == (count - 3)) {
++ *bufout++ = base[(((TO_ASCII(src[i]) << 2) & 0x1C) |
++ ((TO_ASCII(src[i + 1]) >> 6) & 0x3))];
++ *bufout++ = base[(TO_ASCII(src[i + 1]) >> 1) & 0x1F];
++ *bufout++ = base[(((TO_ASCII(src[i + 1]) << 4) & 0x10) |
++ ((TO_ASCII(src[i + 2]) >> 4) & 0xF))];
++ *bufout++ = base[(TO_ASCII(src[i + 2]) << 1) & 0x1E];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ *bufout++ = '=';
+@@ -640,49 +707,51 @@
+ }
+ }
+ else {
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 1] >> 1) & 0x1F)];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i + 1] << 4) & 0x10)
+- | ((src[i + 2] >> 4) & 0xF))];
+- *bufout++ = base[ENCODE_TO_ASCII(((src[i + 2] << 1) & 0x1E)
+- | ((src[i + 3] >> 7) & 0x1))];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] >> 2) & 0x1F)];
+- *bufout++ = base[ENCODE_TO_ASCII((src[i + 3] << 3) & 0x18)];
++ *bufout++ = base[(((TO_ASCII(src[i]) << 2) & 0x1C) |
++ ((TO_ASCII(src[i + 1]) >> 6) & 0x3))];
++ *bufout++ = base[(TO_ASCII(src[i + 1]) >> 1) & 0x1F];
++ *bufout++ = base[(((TO_ASCII(src[i + 1]) << 4) & 0x10) |
++ ((TO_ASCII(src[i + 2]) >> 4) & 0xF))];
++ *bufout++ = base[(((TO_ASCII(src[i + 2]) << 1) & 0x1E) |
++ ((TO_ASCII(src[i + 3]) >> 7) & 0x1))];
++ *bufout++ = base[(TO_ASCII(src[i + 3]) >> 2) & 0x1F];
++ *bufout++ = base[(TO_ASCII(src[i + 3]) << 3) & 0x18];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+ }
+ }
+ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
++ dest[dlen] = '\0';
++ }
++ else {
++ dlen = ((count + 4u) / 5u) * 8u + 1u;
++ if (dlen <= count) {
++ status = APR_ENOSPC;
+ }
+-
+- *bufout++ = '\0';
+-
+- return APR_SUCCESS;
+ }
+
+ if (len) {
+- *len = ((slen + 2) / 3 * 4) + 1;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ {
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+ const char *base;
+
+- if (!src) {
+- return APR_NOTFOUND;
++ if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+ if (dest) {
+- register char *bufout = dest;
+- int i;
++ char *bufout = dest;
++ apr_size_t i = 0;
+
+ if (!((flags & APR_ENCODE_BASE32HEX))) {
+ base = base32;
+@@ -691,23 +760,25 @@
+ base = base32hex;
+ }
+
+- for (i = 0; i < slen - 4; i += 5) {
+- *bufout++ = base[((src[i] >> 3) & 0x1F)];
+- *bufout++ = base[(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
+- *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
+- *bufout++ = base[(((src[i + 1] << 4) & 0x10)
+- | ((src[i + 2] >> 4) & 0xF))];
+- *bufout++ = base[(((src[i + 2] << 1) & 0x1E)
+- | ((src[i + 3] >> 7) & 0x1))];
+- *bufout++ = base[((src[i + 3] >> 2) & 0x1F)];
+- *bufout++ = base[(((src[i + 3] << 3) & 0x18)
+- | ((src[i + 4] >> 5) & 0x7))];
+- *bufout++ = base[(src[i + 4] & 0x1F)];
++ if (count > 4) {
++ for (; i < count - 4; i += 5) {
++ *bufout++ = base[((src[i] >> 3) & 0x1F)];
++ *bufout++ = base[(((src[i] << 2) & 0x1C) |
++ ((src[i + 1] >> 6) & 0x3))];
++ *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
++ *bufout++ = base[(((src[i + 1] << 4) & 0x10) |
++ ((src[i + 2] >> 4) & 0xF))];
++ *bufout++ = base[(((src[i + 2] << 1) & 0x1E) |
++ ((src[i + 3] >> 7) & 0x1))];
++ *bufout++ = base[((src[i + 3] >> 2) & 0x1F)];
++ *bufout++ = base[(((src[i + 3] << 3) & 0x18) |
++ ((src[i + 4] >> 5) & 0x7))];
++ *bufout++ = base[(src[i + 4] & 0x1F)];
++ }
+ }
+- if (i < slen) {
++ if (i < count) {
+ *bufout++ = base[(src[i] >> 3) & 0x1F];
+- if (i == (slen - 1)) {
++ if (i == (count - 1)) {
+ *bufout++ = base[((src[i] << 2) & 0x1C)];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+@@ -718,9 +789,9 @@
+ *bufout++ = '=';
+ }
+ }
+- else if (i == (slen - 2)) {
+- *bufout++ = base[(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
++ else if (i == (count - 2)) {
++ *bufout++ = base[(((src[i] << 2) & 0x1C) |
++ ((src[i + 1] >> 6) & 0x3))];
+ *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
+ *bufout++ = base[((src[i + 1] << 4) & 0x10)];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+@@ -730,12 +801,12 @@
+ *bufout++ = '=';
+ }
+ }
+- else if (i == (slen - 3)) {
+- *bufout++ = base[(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
++ else if (i == (count - 3)) {
++ *bufout++ = base[(((src[i] << 2) & 0x1C) |
++ ((src[i + 1] >> 6) & 0x3))];
+ *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
+- *bufout++ = base[(((src[i + 1] << 4) & 0x10)
+- | ((int)(src[i + 2] >> 4) & 0xF))];
++ *bufout++ = base[(((src[i + 1] << 4) & 0x10) |
++ ((src[i + 2] >> 4) & 0xF))];
+ *bufout++ = base[((src[i + 2] << 1) & 0x1E)];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+ *bufout++ = '=';
+@@ -744,13 +815,13 @@
+ }
+ }
+ else {
+- *bufout++ = base[(((src[i] << 2) & 0x1C)
+- | ((src[i + 1] >> 6) & 0x3))];
++ *bufout++ = base[(((src[i] << 2) & 0x1C) |
++ ((src[i + 1] >> 6) & 0x3))];
+ *bufout++ = base[((src[i + 1] >> 1) & 0x1F)];
+- *bufout++ = base[(((src[i + 1] << 4) & 0x10)
+- | ((src[i + 2] >> 4) & 0xF))];
+- *bufout++ = base[(((src[i + 2] << 1) & 0x1E)
+- | ((src[i + 3] >> 7) & 0x1))];
++ *bufout++ = base[(((src[i + 1] << 4) & 0x10) |
++ ((src[i + 2] >> 4) & 0xF))];
++ *bufout++ = base[(((src[i + 2] << 1) & 0x1E) |
++ ((src[i + 3] >> 7) & 0x1))];
+ *bufout++ = base[((src[i + 3] >> 2) & 0x1F)];
+ *bufout++ = base[((src[i + 3] << 3) & 0x18)];
+ if (!(flags & APR_ENCODE_NOPADDING)) {
+@@ -759,20 +830,20 @@
+ }
+ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
++ dest[dlen] = '\0';
++ }
++ else {
++ dlen = ((count + 4u) / 5u) * 8u + 1u;
++ if (dlen <= count) {
++ status = APR_ENOSPC;
+ }
+-
+- *bufout++ = '\0';
+-
+- return APR_SUCCESS;
+ }
+
+ if (len) {
+- *len = ((slen + 4) / 5 * 8) + 1;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src,
+@@ -780,13 +851,19 @@
+ {
+ apr_size_t size;
+
++ if (!src) {
++ return NULL;
++ }
++
+ switch (apr_encode_base32(NULL, src, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ char *cmd = apr_palloc(p, size);
+- apr_encode_base32(cmd, src, slen, flags, len);
++ if (cmd) {
++ apr_encode_base32(cmd, src, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -799,13 +876,19 @@
+ {
+ apr_size_t size;
+
++ if (!src) {
++ return NULL;
++ }
++
+ switch (apr_encode_base32_binary(NULL, src, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ char *cmd = apr_palloc(p, size);
+- apr_encode_base32_binary(cmd, src, slen, flags, len);
++ if (cmd) {
++ apr_encode_base32_binary(cmd, src, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -816,24 +899,20 @@
+ APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- if (!src) {
+- return APR_NOTFOUND;
+- }
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
++ }
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+- if (dest) {
+- register const unsigned char *bufin;
+- register unsigned char *bufout;
+- register apr_size_t nprbytes;
+- register apr_size_t count = slen;
+-
++ if (src) {
++ const unsigned char *bufin;
+ const unsigned char *pr2;
+
+- apr_status_t status;
+-
+ if ((flags & APR_ENCODE_BASE32HEX)) {
+ pr2 = pr2fivehex;
+ }
+@@ -842,101 +921,130 @@
+ }
+
+ bufin = (const unsigned char *)src;
+- while (pr2[*(bufin++)] < 32 && count)
+- count--;
+- nprbytes = (bufin - (const unsigned char *)src) - 1;
+- while (pr2[*(bufin++)] > 32 && count)
++ while (count) {
++ if (pr2[*bufin] >= 32) {
++ if (!(flags & APR_ENCODE_RELAXED)) {
++ if (count <= 6) {
++ do {
++ if (pr2[bufin[count - 1]] <= 32)
++ break;
++ } while (--count);
++ }
++ if (count) {
++ status = APR_BADCH;
++ }
++ }
++ break;
++ }
+ count--;
++ bufin++;
++ }
++ count = bufin - (const unsigned char *)src;
+
+- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
+- count ? APR_BADCH : APR_SUCCESS;
++ if (dest) {
++ unsigned char *bufout;
+
+- bufout = (unsigned char *)dest;
+- bufin = (const unsigned char *)src;
++ bufout = (unsigned char *)dest;
++ bufin = (const unsigned char *)src;
+
+- while (nprbytes > 8) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[0]] << 3
+- | pr2[bufin[1]] >> 2);
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[1]] << 6
+- | pr2[bufin[2]] << 1 | pr2[bufin[3]] >> 4);
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[3]] << 4
+- | pr2[bufin[4]] >> 1);
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[4]] << 7
+- | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[6]] << 5
+- | pr2[bufin[7]]);
+- bufin += 8;
+- nprbytes -= 8;
+- }
++ while (count >= 8) {
++ *(bufout++) = TO_NATIVE(pr2[bufin[0]] << 3 |
++ pr2[bufin[1]] >> 2);
++ *(bufout++) = TO_NATIVE(pr2[bufin[1]] << 6 |
++ pr2[bufin[2]] << 1 |
++ pr2[bufin[3]] >> 4);
++ *(bufout++) = TO_NATIVE(pr2[bufin[3]] << 4 |
++ pr2[bufin[4]] >> 1);
++ *(bufout++) = TO_NATIVE(pr2[bufin[4]] << 7 |
++ pr2[bufin[5]] << 2 |
++ pr2[bufin[6]] >> 3);
++ *(bufout++) = TO_NATIVE(pr2[bufin[6]] << 5 |
++ pr2[bufin[7]]);
++ bufin += 8;
++ count -= 8;
++ }
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
+- }
+- if (nprbytes >= 2) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2[bufin[0]] << 3 | pr2[bufin[1]] >> 2);
+- }
+- if (nprbytes == 3) {
+- status = APR_BADCH;
+- }
+- if (nprbytes >= 4) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2[bufin[1]] << 6 | pr2[bufin[2]] << 1
+- | pr2[bufin[3]] >> 4);
+- }
+- if (nprbytes >= 5) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[3]] << 4
+- | pr2[bufin[4]] >> 1);
+- }
+- if (nprbytes == 6) {
+- status = APR_BADCH;
+- }
+- if (nprbytes >= 7) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[4]] << 7
+- | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
+- }
+- if (nprbytes == 8) {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(pr2[bufin[6]] << 5
+- | pr2[bufin[7]]);
+- }
++ if (count == 1) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count >= 2) {
++ *(bufout++) = TO_NATIVE(pr2[bufin[0]] << 3 |
++ pr2[bufin[1]] >> 2);
++ }
++ if (count == 3) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count >= 4) {
++ *(bufout++) = TO_NATIVE(pr2[bufin[1]] << 6 |
++ pr2[bufin[2]] << 1 |
++ pr2[bufin[3]] >> 4);
++ }
++ if (count >= 5) {
++ *(bufout++) = TO_NATIVE(pr2[bufin[3]] << 4 |
++ pr2[bufin[4]] >> 1);
++ }
++ if (count == 6) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count >= 7) {
++ *(bufout++) = TO_NATIVE(pr2[bufin[4]] << 7 |
++ pr2[bufin[5]] << 2 |
++ pr2[bufin[6]] >> 3);
++ }
+
+- if (len) {
+- *len = bufout - (unsigned char *)dest;
++ dlen = bufout - (unsigned char *)dest;
++ dest[dlen] = '\0';
+ }
++ }
+
+- *(bufout++) = 0;
+-
+- return status;
++ if (!src || !dest) {
++ dlen = (count / 8u) * 5u + 1u;
++ switch (count % 8) {
++ case 7:
++ dlen += 4;
++ break;
++ case 6:
++ status = APR_EINCOMPLETE;
++ case 5:
++ dlen += 3;
++ break;
++ case 4:
++ dlen += 2;
++ break;
++ case 3:
++ status = APR_EINCOMPLETE;
++ case 2:
++ dlen++;
++ break;
++ case 1:
++ status = APR_EINCOMPLETE;
++ break;
++ }
+ }
+
+ if (len) {
+- *len = (((int)slen + 7) / 8) * 5 + 1;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- if (!src) {
+- return APR_NOTFOUND;
+- }
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
++ }
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+- if (dest) {
+- register const unsigned char *bufin;
+- register unsigned char *bufout;
+- register apr_size_t nprbytes;
+- register apr_size_t count = slen;
+-
++ if (src) {
++ const unsigned char *bufin;
+ const unsigned char *pr2;
+
+- apr_status_t status;
+-
+ if ((flags & APR_ENCODE_BASE32HEX)) {
+ pr2 = pr2fivehex;
+ }
+@@ -945,76 +1053,110 @@
+ }
+
+ bufin = (const unsigned char *)src;
+- while (pr2[*(bufin++)] < 32 && count)
+- count--;
+- nprbytes = (bufin - (const unsigned char *)src) - 1;
+- while (pr2[*(bufin++)] > 32 && count)
++ while (count) {
++ if (pr2[*bufin] >= 32) {
++ if (!(flags & APR_ENCODE_RELAXED)) {
++ if (count <= 6) {
++ do {
++ if (pr2[bufin[count - 1]] <= 32)
++ break;
++ } while (--count);
++ }
++ if (count) {
++ status = APR_BADCH;
++ }
++ }
++ break;
++ }
+ count--;
++ bufin++;
++ }
++ count = bufin - (const unsigned char *)src;
+
+- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
+- count ? APR_BADCH : APR_SUCCESS;
++ if (dest) {
++ unsigned char *bufout;
+
+- bufout = (unsigned char *)dest;
+- bufin = (const unsigned char *)src;
++ bufout = (unsigned char *)dest;
++ bufin = (const unsigned char *)src;
+
+- while (nprbytes > 8) {
+- *(bufout++) = (unsigned char)(pr2[bufin[0]] << 3
+- | pr2[bufin[1]] >> 2);
+- *(bufout++) = (unsigned char)(pr2[bufin[1]] << 6
+- | pr2[bufin[2]] << 1 | pr2[bufin[3]] >> 4);
+- *(bufout++) = (unsigned char)(pr2[bufin[3]] << 4
+- | pr2[bufin[4]] >> 1);
+- *(bufout++) = (unsigned char)(pr2[bufin[4]] << 7
+- | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
+- *(bufout++) = (unsigned char)(pr2[bufin[6]] << 5
+- | pr2[bufin[7]]);
+- bufin += 8;
+- nprbytes -= 8;
+- }
++ while (count >= 8) {
++ *(bufout++) = (pr2[bufin[0]] << 3 |
++ pr2[bufin[1]] >> 2);
++ *(bufout++) = (pr2[bufin[1]] << 6 |
++ pr2[bufin[2]] << 1 |
++ pr2[bufin[3]] >> 4);
++ *(bufout++) = (pr2[bufin[3]] << 4 |
++ pr2[bufin[4]] >> 1);
++ *(bufout++) = (pr2[bufin[4]] << 7 |
++ pr2[bufin[5]] << 2 |
++ pr2[bufin[6]] >> 3);
++ *(bufout++) = (pr2[bufin[6]] << 5 |
++ pr2[bufin[7]]);
++ bufin += 8;
++ count -= 8;
++ }
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
+- }
+- if (nprbytes >= 2) {
+- *(bufout++) = (unsigned char)(
+- pr2[bufin[0]] << 3 | pr2[bufin[1]] >> 2);
+- }
+- if (nprbytes == 3) {
+- status = APR_BADCH;
+- }
+- if (nprbytes >= 4) {
+- *(bufout++) = (unsigned char)(
+- pr2[bufin[1]] << 6 | pr2[bufin[2]] << 1
+- | pr2[bufin[3]] >> 4);
+- }
+- if (nprbytes >= 5) {
+- *(bufout++) = (unsigned char)(pr2[bufin[3]] << 4
+- | pr2[bufin[4]] >> 1);
+- }
+- if (nprbytes == 6) {
+- status = APR_BADCH;
+- }
+- if (nprbytes >= 7) {
+- *(bufout++) = (unsigned char)(pr2[bufin[4]] << 7
+- | pr2[bufin[5]] << 2 | pr2[bufin[6]] >> 3);
+- }
+- if (nprbytes == 8) {
+- *(bufout++) = (unsigned char)(pr2[bufin[6]] << 5
+- | pr2[bufin[7]]);
+- }
++ if (count == 1) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count >= 2) {
++ *(bufout++) = (pr2[bufin[0]] << 3 |
++ pr2[bufin[1]] >> 2);
++ }
++ if (count == 3) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count >= 4) {
++ *(bufout++) = (pr2[bufin[1]] << 6 |
++ pr2[bufin[2]] << 1 |
++ pr2[bufin[3]] >> 4);
++ }
++ if (count >= 5) {
++ *(bufout++) = (pr2[bufin[3]] << 4 |
++ pr2[bufin[4]] >> 1);
++ }
++ if (count == 6) {
++ status = APR_EINCOMPLETE;
++ }
++ if (count >= 7) {
++ *(bufout++) = (pr2[bufin[4]] << 7 |
++ pr2[bufin[5]] << 2 |
++ pr2[bufin[6]] >> 3);
++ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
+ }
++ }
+
+- return status;
++ if (!src || !dest) {
++ dlen = (count / 8u) * 5u;
++ switch (count % 8) {
++ case 7:
++ dlen += 4;
++ break;
++ case 6:
++ status = APR_EINCOMPLETE;
++ case 5:
++ dlen += 3;
++ break;
++ case 4:
++ dlen += 2;
++ break;
++ case 3:
++ status = APR_EINCOMPLETE;
++ case 2:
++ dlen++;
++ break;
++ case 1:
++ status = APR_EINCOMPLETE;
++ break;
++ }
+ }
+
+ if (len) {
+- *len = (((int)slen + 7) / 8) * 5;
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *str,
+@@ -1022,14 +1164,19 @@
+ {
+ apr_size_t size;
+
++ if (!str) {
++ return NULL;
++ }
++
+ switch (apr_decode_base32(NULL, str, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ void *cmd = apr_palloc(p, size);
+- apr_decode_base32(cmd, str, slen, flags, len);
++ if (cmd) {
++ apr_decode_base32(cmd, str, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_BADCH:
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -1042,15 +1189,20 @@
+ {
+ apr_size_t size;
+
++ if (!str) {
++ return NULL;
++ }
++
+ switch (apr_decode_base32_binary(NULL, str, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ unsigned char *cmd = apr_palloc(p, size + 1);
+- cmd[size] = 0;
+- apr_decode_base32_binary(cmd, str, slen, flags, len);
++ if (cmd) {
++ apr_decode_base32_binary(cmd, str, slen, flags, len);
++ cmd[size] = 0;
++ }
+ return cmd;
+ }
+- case APR_BADCH:
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -1061,16 +1213,20 @@
+ APR_DECLARE(apr_status_t) apr_encode_base16(char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- const char *in = src;
+- apr_size_t size;
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- if (!src) {
+- return APR_NOTFOUND;
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
++ }
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+ if (dest) {
+- register char *bufout = dest;
++ char *bufout = dest;
+ const char *base;
++ apr_size_t i;
+
+ if ((flags & APR_ENCODE_LOWER)) {
+ base = base16lower;
+@@ -1079,51 +1235,51 @@
+ base = base16;
+ }
+
+- for (size = 0; (APR_ENCODE_STRING == slen) ? in[size] : size < slen; size++) {
+- if ((flags & APR_ENCODE_COLON) && size) {
++ for (i = 0; i < count; i++) {
++ if ((flags & APR_ENCODE_COLON) && i) {
+ *(bufout++) = ':';
+ }
+- *(bufout++) = base[(const unsigned char)(ENCODE_TO_ASCII(in[size])) >> 4];
+- *(bufout++) = base[(const unsigned char)(ENCODE_TO_ASCII(in[size])) & 0xf];
++ *(bufout++) = base[TO_ASCII(src[i]) >> 4];
++ *(bufout++) = base[TO_ASCII(src[i]) & 0xf];
+ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
++ dest[dlen] = '\0';
++ }
++ else {
++ dlen = count * 2u + 1u;
++ if (dlen <= count) {
++ status = APR_ENOSPC;
++ }
++ if ((flags & APR_ENCODE_COLON) && count > 1) {
++ apr_size_t more = dlen + count - 1;
++ if (more <= dlen) {
++ status = APR_ENOSPC;
++ }
++ dlen = more;
+ }
+-
+- *bufout = '\0';
+-
+- return APR_SUCCESS;
+ }
+
+ if (len) {
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
+- }
+- if ((flags & APR_ENCODE_COLON) && slen) {
+- *len = slen * 3;
+- }
+- else {
+- *len = slen * 2 + 1;
+- }
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest,
+ const unsigned char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- const unsigned char *in = src;
+- apr_size_t size;
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- if (!src) {
+- return APR_NOTFOUND;
++ if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+ if (dest) {
+- register char *bufout = dest;
++ char *bufout = dest;
+ const char *base;
++ apr_size_t i;
+
+ if ((flags & APR_ENCODE_LOWER)) {
+ base = base16lower;
+@@ -1132,33 +1288,35 @@
+ base = base16;
+ }
+
+- for (size = 0; size < slen; size++) {
+- if ((flags & APR_ENCODE_COLON) && size) {
++ for (i = 0; i < count; i++) {
++ if ((flags & APR_ENCODE_COLON) && i) {
+ *(bufout++) = ':';
+ }
+- *(bufout++) = base[in[size] >> 4];
+- *(bufout++) = base[in[size] & 0xf];
++ *(bufout++) = base[src[i] >> 4];
++ *(bufout++) = base[src[i] & 0xf];
+ }
+
+- if (len) {
+- *len = bufout - dest;
++ dlen = bufout - dest;
++ dest[dlen] = '\0';
++ }
++ else {
++ dlen = count * 2u + 1u;
++ if (dlen <= count) {
++ status = APR_ENOSPC;
++ }
++ if ((flags & APR_ENCODE_COLON) && count > 1) {
++ apr_size_t more = dlen + count - 1;
++ if (more <= dlen) {
++ status = APR_ENOSPC;
++ }
++ dlen = more;
+ }
+-
+- *bufout = 0;
+-
+- return APR_SUCCESS;
+ }
+
+ if (len) {
+- if ((flags & APR_ENCODE_COLON) && slen) {
+- *len = slen * 3;
+- }
+- else {
+- *len = slen * 2 + 1;
+- }
++ *len = dlen;
+ }
+-
+- return APR_SUCCESS;
++ return status;
+ }
+
+ APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p,
+@@ -1166,13 +1324,19 @@
+ {
+ apr_size_t size;
+
++ if (!src) {
++ return NULL;
++ }
++
+ switch (apr_encode_base16(NULL, src, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ char *cmd = apr_palloc(p, size);
+- apr_encode_base16(cmd, src, slen, flags, len);
++ if (cmd) {
++ apr_encode_base16(cmd, src, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -1186,13 +1350,19 @@
+ {
+ apr_size_t size;
+
++ if (!src) {
++ return NULL;
++ }
++
+ switch (apr_encode_base16_binary(NULL, src, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ char *cmd = apr_palloc(p, size);
+- apr_encode_base16_binary(cmd, src, slen, flags, len);
++ if (cmd) {
++ apr_encode_base16_binary(cmd, src, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -1203,178 +1373,156 @@
+ APR_DECLARE(apr_status_t) apr_decode_base16(char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- register const unsigned char *bufin;
+- register unsigned char *bufout;
+- register apr_size_t nprbytes;
+- register apr_size_t count;
+-
+- apr_status_t status;
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- if (!src) {
+- return APR_NOTFOUND;
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
+ }
+-
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+- count = slen;
+- bufin = (const unsigned char *)src;
+- while (pr2two[*(bufin++)] != 16 && count)
+- count--;
+- nprbytes = (bufin - (const unsigned char *)src) - 1;
+- while (pr2two[*(bufin++)] > 16 && count)
+- count--;
+-
+- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
+- count ? APR_BADCH : APR_SUCCESS;
+-
+- if (dest) {
++ if (src) {
++ const unsigned char *bufin;
+
+- bufout = (unsigned char *)dest;
+ bufin = (const unsigned char *)src;
+-
+- while (nprbytes >= 2) {
+- if (pr2two[bufin[0]] > 16) {
+- bufin += 1;
+- nprbytes -= 1;
+- }
+- else {
+- *(bufout++) = (unsigned char)ENCODE_TO_NATIVE(
+- pr2two[bufin[0]] << 4 | pr2two[bufin[1]]);
+- bufin += 2;
+- nprbytes -= 2;
++ while (count) {
++ if (pr2two[*bufin] >= 16
++ && (!(flags & APR_ENCODE_COLON)
++ || pr2two[*bufin] != 32 /* ':' */)) {
++ if (!(flags & APR_ENCODE_RELAXED)) {
++ status = APR_BADCH;
++ }
++ break;
+ }
++ count--;
++ bufin++;
+ }
++ count = bufin - (const unsigned char *)src;
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
+- }
+-
+- if (len) {
+- *len = bufout - (unsigned char *)dest;
+- }
+-
+- *(bufout++) = 0;
++ if (dest) {
++ unsigned char *bufout;
+
+- return status;
+- }
++ bufout = (unsigned char *)dest;
++ bufin = (const unsigned char *)src;
+
+- else {
+-
+- count = 0;
+- bufin = (const unsigned char *)src;
+-
+- while (nprbytes >= 2) {
+- if (pr2two[bufin[0]] > 16) {
+- bufin += 1;
+- nprbytes -= 1;
++ while (count >= 2) {
++ if (pr2two[bufin[0]] == 32 /* ':' */) {
++ bufin += 1;
++ count -= 1;
++ }
++ else {
++ *(bufout++) = TO_NATIVE(pr2two[bufin[0]] << 4 |
++ pr2two[bufin[1]]);
++ bufin += 2;
++ count -= 2;
++ }
+ }
+- else {
+- count++;
+- bufin += 2;
+- nprbytes -= 2;
++
++ if (count == 1) {
++ status = APR_EINCOMPLETE;
+ }
+- }
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
++ dlen = bufout - (unsigned char *)dest;
++ dest[dlen] = '\0';
+ }
++ }
+
+- if (len) {
+- *len = count + 1;
++ if (!src || !dest) {
++ if (flags & APR_ENCODE_COLON) {
++ if (count && (count + 1u) % 3u) {
++ status = APR_EINCOMPLETE;
++ }
++ count -= count / 3u;
+ }
+-
+- return status;
++ if (count % 2u) {
++ status = APR_EINCOMPLETE;
++ }
++ dlen = count / 2u + 1u;
+ }
+
++ if (len) {
++ *len = dlen;
++ }
++ return status;
+ }
+
+ APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+ {
+- register const unsigned char *bufin;
+- register unsigned char *bufout;
+- register apr_size_t nprbytes;
+- register apr_size_t count;
++ apr_status_t status = APR_SUCCESS;
++ apr_size_t count = slen, dlen = 0;
+
+- apr_status_t status;
+-
+- if (!src) {
+- return APR_NOTFOUND;
++ if (src && slen == APR_ENCODE_STRING) {
++ count = strlen(src);
+ }
+-
+- if (APR_ENCODE_STRING == slen) {
+- slen = strlen(src);
++ else if (slen < 0 || (dest && !src)) {
++ return (src) ? APR_EINVAL : APR_NOTFOUND;
+ }
+
+- count = slen;
+- bufin = (const unsigned char *)src;
+- while (pr2two[*(bufin++)] != 16 && count)
+- count--;
+- nprbytes = (bufin - (const unsigned char *)src) - 1;
+- while (pr2two[*(bufin++)] > 16 && count)
+- count--;
++ if (src) {
++ const unsigned char *bufin;
+
+- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS :
+- count ? APR_BADCH : APR_SUCCESS;
+-
+- if (dest) {
+-
+- bufout = (unsigned char *)dest;
+ bufin = (const unsigned char *)src;
+-
+- while (nprbytes >= 2) {
+- if (pr2two[bufin[0]] > 16) {
+- bufin += 1;
+- nprbytes -= 1;
+- }
+- else {
+- *(bufout++) = (unsigned char)(
+- pr2two[bufin[0]] << 4 | pr2two[bufin[1]]);
+- bufin += 2;
+- nprbytes -= 2;
++ while (count) {
++ if (pr2two[*bufin] >= 16
++ && (!(flags & APR_ENCODE_COLON)
++ || pr2two[*bufin] != 32 /* ':' */)) {
++ if (!(flags & APR_ENCODE_RELAXED)) {
++ status = APR_BADCH;
++ }
++ break;
+ }
++ count--;
++ bufin++;
+ }
++ count = bufin - (const unsigned char *)src;
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
+- }
+-
+- if (len) {
+- *len = bufout - (unsigned char *)dest;
+- }
+-
+- return status;
+- }
++ if (dest) {
++ unsigned char *bufout;
+
+- else {
++ bufout = (unsigned char *)dest;
++ bufin = (const unsigned char *)src;
+
+- count = 0;
+- bufin = (const unsigned char *)src;
+-
+- while (nprbytes >= 2) {
+- if (pr2two[bufin[0]] > 16) {
+- bufin += 1;
+- nprbytes -= 1;
++ while (count >= 2) {
++ if (pr2two[bufin[0]] == 32 /* ':' */) {
++ bufin += 1;
++ count -= 1;
++ }
++ else {
++ *(bufout++) = (pr2two[bufin[0]] << 4 |
++ pr2two[bufin[1]]);
++ bufin += 2;
++ count -= 2;
++ }
+ }
+- else {
+- count++;
+- bufin += 2;
+- nprbytes -= 2;
++
++ if (count == 1) {
++ status = APR_EINCOMPLETE;
+ }
+- }
+
+- if (nprbytes == 1) {
+- status = APR_BADCH;
++ dlen = bufout - (unsigned char *)dest;
+ }
++ }
+
+- if (len) {
+- *len = count;
++ if (!src || !dest) {
++ if (flags & APR_ENCODE_COLON) {
++ if (count && (count + 1u) % 3u) {
++ status = APR_EINCOMPLETE;
++ }
++ count -= count / 3u;
++ }
++ if (count % 2u) {
++ status = APR_EINCOMPLETE;
+ }
++ dlen = count / 2u;
++ }
+
+- return status;
++ if (len) {
++ *len = dlen;
+ }
++ return status;
+ }
+
+ APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p,
+@@ -1382,14 +1530,19 @@
+ {
+ apr_size_t size;
+
++ if (!str) {
++ return NULL;
++ }
++
+ switch (apr_decode_base16(NULL, str, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ void *cmd = apr_palloc(p, size);
+- apr_decode_base16(cmd, str, slen, flags, len);
++ if (cmd) {
++ apr_decode_base16(cmd, str, slen, flags, len);
++ }
+ return cmd;
+ }
+- case APR_BADCH:
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+@@ -1402,15 +1555,20 @@
+ {
+ apr_size_t size;
+
++ if (!str) {
++ return NULL;
++ }
++
+ switch (apr_decode_base16_binary(NULL, str, slen, flags, &size)) {
+ case APR_SUCCESS:{
+ unsigned char *cmd = apr_palloc(p, size + 1);
+- cmd[size] = 0;
+- apr_decode_base16_binary(cmd, str, slen, flags, len);
++ if (cmd) {
++ apr_decode_base16_binary(cmd, str, slen, flags, len);
++ cmd[size] = 0;
++ }
+ return cmd;
+ }
+- case APR_BADCH:
+- case APR_NOTFOUND:{
++ default:{
+ break;
+ }
+ }
+--- apr-1.7.0/encoding/apr_escape.c.encoding
++++ apr-1.7.0/encoding/apr_escape.c
+@@ -131,7 +131,7 @@
+ xstr[2]=what[0];
+ xstr[3]=what[1];
+ xstr[4]='\0';
+- digit = ENCODE_TO_NATIVE[0xFF & strtol(xstr, NULL, 16)];
++ digit = TO_NATIVE(strtol(xstr, NULL, 16));
+ #endif /*APR_CHARSET_EBCDIC*/
+ return (digit);
+ }
+@@ -716,7 +716,7 @@
+ size--;
+ }
+ else {
+- *d = ENCODE_TO_ASCII(val);
++ *d = TO_ASCII(val);
+ found = 1;
+ }
+ }
+@@ -737,7 +737,7 @@
+ *d = '&'; /* unknown */
+ }
+ else {
+- *d = ENCODE_TO_ASCII(((const unsigned char *) ents)[j]);
++ *d = TO_ASCII(ents[j]);
+ s += i;
+ slen -= i;
+ found = 1;
+--- apr-1.7.0/include/apr_encode.h.encoding
++++ apr-1.7.0/include/apr_encode.h
+@@ -146,35 +146,44 @@
+
+ /**
+ * Convert text data to base64.
+- * @param dest The destination string, can be NULL.
+- * @param src The original string.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for encoding.
++ * @param src The original string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+- * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination string, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
++ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
++ * @param len If not NULL, outputs the length of the buffer needed for encoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to encode.
+ */
+ APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+ /**
+ * Convert binary data to base64.
+- * @param dest The destination string, can be NULL.
+- * @param src The original buffer.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for encoding.
++ * @param src The original buffer, can be NULL if \c dest is NULL.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+- * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination string, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
++ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
++ * @param len If not NULL, outputs the length of the buffer needed for encoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
++ * if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
++ * and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
++ * encode.
+ */
+ APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+@@ -184,15 +193,16 @@
+ * @param p Pool to allocate from.
+ * @param src The original string.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+- * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+- * @param len If present, returns the number of characters written excluding
+- * the zero pad.
+- * @return A zero padded string allocated from the pool on success, or
+- * NULL if src was NULL.
++ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the encoding is not
++ * possible (see apr_encode_base64 errors).
+ */
+ APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));
+@@ -205,47 +215,62 @@
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 64 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_URL,
+ * use RFC4648 Base 64 Encoding with URL and Filename Safe Alphabet.
+- * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
+- * @param len If present, returns the number of characters written excluding
+- * the zero pad.
+- * @return A zero padded string allocated from the pool on success, or
+- * NULL if src was NULL.
++ * If APR_ENCODE_BASE64URL, use RFC7515 base64url Encoding.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the encoding is not
++ * possible (see apr_encode_base64_binary errors).
+ */
+ APR_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)__attribute__((nonnull(1)));
+
+ /**
+ * Convert base64 or base64url with or without padding to text data.
+- * @param dest The destination string, can be NULL.
+- * @param src The original string.
+- * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
+- * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for decoding.
++ * @param src The base64 string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
++ * @param slen The length of the base64 string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
++ * @param flags If APR_ENCODE_NONE, attempt to decode the full base64 string,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination string, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
+- * if a non hex character is present.
++ * @param len If not NULL, outputs the length of the buffer needed for decoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
++ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base64
++ * encoding, or APR_BADCH if a non base64 character is present and
++ * APR_ENCODE_RELAXED is not specified.
+ */
+ APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+ /**
+ * Convert base64 or base64url with or without padding to binary data.
+- * @param dest The destination buffer, can be NULL.
+- * @param src The original string.
+- * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
+- * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for decoding.
++ * @param src The base64 string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
++ * @param slen The length of the base64 string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
++ * @param flags If APR_ENCODE_NONE, attempt to decode the full base64 string,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination buffer, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the src was NULL, or APR_BADCH
+- * if a non base64 character is present.
++ * @param len If not NULL, outputs the length of the buffer needed for decoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
++ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base64
++ * encoding, or APR_BADCH if a non base64 character is present and
++ * APR_ENCODE_RELAXED is not specified.
+ */
+ APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
+@@ -255,15 +280,16 @@
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base64 string to decode.
+- * @param slen The length of the base64 string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * @param slen The length of the original string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A string allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the decoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the decoding is not
++ * possible (see apr_decode_base64_binary errors).
+ */
+ APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -273,16 +299,17 @@
+ * Convert base64 or base64url with or without padding to binary data, and
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+- * @param src The original string.
++ * @param src The base64 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, attempt to decode the full original buffer,
+ * and return NULL if any bad character is detected. If APR_ENCODE_RELAXED,
+ * decode until the first non base64/base64url character.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A buffer allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the decoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the decoding is not
++ * possible (see apr_decode_base64_binary errors).
+ */
+ APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -290,33 +317,42 @@
+
+ /**
+ * Convert text data to base32.
+- * @param dest The destination string, can be NULL.
+- * @param src The original string.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for encoding.
++ * @param src The original string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+ * use RFC4648 base32hex Encoding.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination string, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
++ * @param len If not NULL, outputs the length of the buffer needed for encoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to encode.
+ */
+ APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+ /**
+ * Convert binary data to base32.
+- * @param dest The destination string, can be NULL.
+- * @param src The original buffer.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for encoding.
++ * @param src The original buffer, can be NULL if \c dest is NULL.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+ * use RFC4648 base32hex Encoding.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination string, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
++ * @param len If not NULL, outputs the length of the buffer needed for encoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
++ * if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
++ * and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
++ * encode.
+ */
+ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+@@ -326,14 +362,15 @@
+ * @param p Pool to allocate from.
+ * @param src The original string.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+ * use RFC4648 base32hex Encoding.
+- * @param len If present, returns the number of characters written excluding
+- * the zero pad.
+- * @return A zero padded string allocated from the pool on success, or
+- * NULL if src was NULL.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the encoding is not
++ * possible (see apr_encode_base32 errors).
+ */
+ APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -346,11 +383,12 @@
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_NOPADDING, omit the = padding character. If APR_ENCODE_BASE32HEX,
+- * use RFC7515 base32hex Encoding.
+- * @param len If present, returns the number of characters written excluding
+- * the zero pad.
+- * @return A zero padded string allocated from the pool on success, or
+- * NULL if src was NULL.
++ * use RFC4648 base32hex Encoding.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the encoding is not
++ * possible (see apr_encode_base32_binary errors).
+ */
+ APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigned char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -358,34 +396,48 @@
+
+ /**
+ * Convert base32 or base32hex with or without padding to text data.
+- * @param dest The destination string, can be NULL.
+- * @param src The original string.
+- * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for decoding.
++ * @param src The base32 string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
++ * @param slen The length of the base32 string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination buffer, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
+- * if a non base32 character is present.
++ * @param len If not NULL, outputs the length of the buffer needed for decoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
++ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base32
++ * encoding, or APR_BADCH if a non base32 character is present and
++ * APR_ENCODE_RELAXED is not specified.
+ */
+ APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+ /**
+ * Convert base32 or base32hex with or without padding to binary data.
+- * @param dest The destination buffer, can be NULL.
+- * @param src The original string.
+- * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for decoding.
++ * @param src The base32 string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
++ * @param slen The length of the base32 string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination buffer, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the src was NULL, or APR_BADCH
+- * if a non base32 character is present.
++ * @param len If not NULL, outputs the length of the buffer needed for decoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
++ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base32
++ * encoding, or APR_BADCH if a non base32 character is present and
++ * APR_ENCODE_RELAXED is not specified.
+ */
+ APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
+@@ -395,14 +447,15 @@
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+ * @param src The base32 string to decode.
+- * @param slen The length of the base32 string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * @param slen The length of the original string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A string allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the decoding is not
++ * possible (see apr_decode_base32 errors).
+ */
+ APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -412,15 +465,16 @@
+ * Convert base32 or base32hex with or without padding to binary data, and
+ * return the results from a pool.
+ * @param p Pool to allocate from.
+- * @param src The original string.
++ * @param src The base32 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 32 Encoding. If
+ * APR_ENCODE_BASE32HEX, use RFC4648 base32hex Encoding.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A buffer allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the decoding is not
++ * possible (see apr_decode_base32_binary errors).
+ */
+ APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -428,31 +482,40 @@
+
+ /**
+ * Convert text data to base16 (hex).
+- * @param dest The destination string, can be NULL.
+- * @param src The original string.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for encoding.
++ * @param src The original string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination buffer, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
++ * @param len If not NULL, outputs the length of the buffer needed for encoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to encode.
+ */
+ APR_DECLARE(apr_status_t) apr_encode_base16(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+ /**
+ * Convert binary data to base16 (hex).
+- * @param dest The destination string, can be NULL.
+- * @param src The original buffer.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for encoding.
++ * @param src The original buffer, can be NULL if \c dest is NULL.
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination buffer, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL.
++ * @param len If not NULL, outputs the length of the buffer needed for encoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the encoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is negative, or APR_NOTFOUND
++ * if \c dest is not NULL and \c src is NULL, or APR_ENOSPC if \c dest is NULL
++ * and the source length (based on \c slen or APR_ENCODE_STRING) is too big to
++ * encode.
+ */
+ APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest,
+ const unsigned char *src, apr_ssize_t slen, int flags,
+@@ -464,13 +527,14 @@
+ * @param p Pool to allocate from.
+ * @param src The original string.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A string allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the encoding is not
++ * possible (see apr_encode_base16 errors).
+ */
+ APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -484,10 +548,11 @@
+ * @param slen The length of the original buffer.
+ * @param flags If APR_ENCODE_NONE, emit RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, separate each token with a colon.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A string allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the encoding is not
++ * possible (see apr_encode_base16_binary errors).
+ */
+ APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p,
+ const unsigned char *src, apr_ssize_t slen,
+@@ -495,34 +560,48 @@
+
+ /**
+ * Convert base16 (hex) to text data.
+- * @param dest The destination string, can be NULL.
+- * @param src The original string.
+- * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for decoding.
++ * @param src The base16 string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
++ * @param slen The length of the base16 string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination buffer, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
+- * if a non hex character is present. A zero pad is appended to the buffer.
++ * @param len If not NULL, outputs the length of the buffer needed for decoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
++ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base16
++ * encoding, or APR_BADCH if a non base16 character is present and
++ * APR_ENCODE_RELAXED is not specified.
+ */
+ APR_DECLARE(apr_status_t) apr_decode_base16(char *dest, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len);
+
+ /**
+ * Convert base16 (hex) to binary data.
+- * @param dest The destination buffer, can be NULL.
+- * @param src The original string.
+- * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * @param dest The destination string, can be NULL to output in \c len the
++ * needed buffer length for decoding.
++ * @param src The base16 string, can be NULL if \c dest is NULL and \c slen
++ * is positive or nul.
++ * @param slen The length of the base16 string, or APR_ENCODE_STRING if
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+- * @param len If present and src is NULL, returns the maximum possible length
+- * of the destination buffer, including a zero pad. If present and src is
+- * not NULL, returns the number of characters actually written.
+- * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL, or APR_BADCH
+- * if a non hex character is present. No zero pad is written to the buffer.
++ * @param len If not NULL, outputs the length of the buffer needed for decoding
++ * (including the trailing NUL) if \c dest is NULL, or the actual length of
++ * the decoding (excluding the trailing NUL) if \c dest is not NULL.
++ * @return APR_SUCCESS, or APR_EINVAL if \c slen is not APR_ENCODE_STRING and
++ * negative, or APR_NOTFOUND if \c dest is not NULL and \c src is NULL, or
++ * APR_ENOSPC if \c dest is NULL and the source length (based on \c slen or
++ * APR_ENCODE_STRING) is too big to decode, or APR_EINCOMPLETE if the source
++ * length (based on \c slen or APR_ENCODE_STRING) is invalid for a base16
++ * encoding, or APR_BADCH if a non base16 character is present and
++ * APR_ENCODE_RELAXED is not specified.
+ */
+ APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len);
+@@ -530,15 +609,16 @@
+ /**
+ * Convert base16 (hex) and return the results from a pool.
+ * @param p Pool to allocate from.
+- * @param src The original string.
++ * @param src The base16 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A buffer allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the decoding is not
++ * possible (see apr_decode_base16 errors).
+ */
+ APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p, const char *src,
+ apr_ssize_t slen, int flags, apr_size_t * len)
+@@ -547,15 +627,16 @@
+ /**
+ * Convert base16 (hex) to binary data, and return the results from a pool.
+ * @param p Pool to allocate from.
+- * @param src The original string.
++ * @param src The base16 string to decode.
+ * @param slen The length of the original string, or APR_ENCODE_STRING if
+- * NUL terminated.
++ * the actual length should be computed based on NUL termination.
+ * @param flags If APR_ENCODE_NONE, parse RFC4648 Base 16 Encoding. If
+ * APR_ENCODE_COLON, allow tokens to be separated with a colon.
+- * @param len If present, returns the number of characters written, excluding
+- * the zero padding.
+- * @return A buffer allocated from the pool containing the result with a zero
+- * pad. If src was NULL, or an error occurred, NULL is returned.
++ * @param len If not NULL, outputs the length of the encoding (excluding the
++ * trailing NUL).
++ * @return A NUL terminated string allocated from the pool on success,
++ * or NULL if src is NULL or allocation failed or the decoding is not
++ * possible (see apr_decode_base16_binary errors).
+ */
+ APR_DECLARE(const unsigned char *)apr_pdecode_base16_binary(apr_pool_t * p,
+ const char *src, apr_ssize_t slen, int flags, apr_size_t * len)
+--- apr-1.7.0/include/private/apr_encode_private.h.encoding
++++ apr-1.7.0/include/private/apr_encode_private.h
+@@ -34,7 +34,8 @@
+ */
+
+ #if APR_CHARSET_EBCDIC
+- static int convert_a2e[256] = {
++
++static unsigned char convert_a2e[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+@@ -52,7 +53,7 @@
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
+ 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF};
+
+- static int convert_e2a[256] = {
++static unsigned char convert_e2a[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07,
+@@ -69,12 +70,16 @@
+ 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF,
+ 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F};
+-#define decode ENCODE_TO_ASCII(ch) convert_e2a[(unsigned char)ch]
+-#define decode ENCODE_TO_NATIVE(ch) convert_a2e[(unsigned char)ch]
+-#else /* APR_CHARSET_EBCDIC */
+-#define ENCODE_TO_ASCII(ch) (ch)
+-#define ENCODE_TO_NATIVE(ch) (ch)
+-#endif /* !APR_CHARSET_EBCDIC */
++
++#define TO_ASCII(ch) (convert_e2a[(unsigned char)(ch)])
++#define TO_NATIVE(ch) (convert_a2e[(unsigned char)(ch)])
++
++#else /* APR_CHARSET_EBCDIC */
++
++#define TO_ASCII(ch) ((unsigned char)(ch))
++#define TO_NATIVE(ch) ((unsigned char)(ch))
++
++#endif /* !APR_CHARSET_EBCDIC */
+
+ /** @} */
+ #ifdef __cplusplus
+--- apr-1.7.0/test/testencode.c.encoding
++++ apr-1.7.0/test/testencode.c
+@@ -905,6 +905,202 @@
+ apr_pool_destroy(pool);
+ }
+
++static void test_encode_errors(abts_case * tc, void *data)
++{
++ char dest[64];
++ apr_size_t len;
++ apr_status_t rv;
++
++ /* Can't test APR_ENOSPC without a NUL terminated buffer of
++ * length APR_SIZE_MAX / 4 * 3 and passing APR_ENCODE_STRING,
++ * which we won't even think about :)
++ */
++
++ /* base64 */
++ rv = apr_encode_base64(dest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_encode_base64(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++
++ /* base64_binary */
++ rv = apr_encode_base64_binary(dest, (const unsigned char *)"", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_encode_base64_binary(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++
++ /* base32 */
++ rv = apr_encode_base32(dest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_encode_base32(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++
++ /* base32_binary */
++ rv = apr_encode_base32_binary(dest, (const unsigned char *)"", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_encode_base32_binary(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++
++ /* base16 */
++ rv = apr_encode_base16(dest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_encode_base16(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++
++ /* base16_binary */
++ rv = apr_encode_base16_binary(dest, (const unsigned char *)"", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_encode_base16_binary(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++}
++
++static void test_decode_errors(abts_case * tc, void *data)
++{
++ char dest[64];
++ apr_size_t len;
++ apr_status_t rv;
++ unsigned char *udest = (unsigned char *)dest;
++
++ /* base64 */
++ rv = apr_decode_base64(dest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_decode_base64(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++ rv = apr_decode_base64(NULL, NULL, 5, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base64(dest, "ABCDE", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base64(dest, "ABCD*EF", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base64(dest, "ABCD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 3, len);
++
++ /* base64_binary */
++ rv = apr_decode_base64_binary(udest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_decode_base64_binary(udest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++ rv = apr_decode_base64_binary(NULL, NULL, 5, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base64_binary(udest, "ABCDE", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base64_binary(udest, "ABCD*EF", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base64_binary(udest, "ABCD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 3, len);
++
++ /* base32 */
++ rv = apr_decode_base32(dest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_decode_base32(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++ rv = apr_decode_base32(NULL, NULL, 9, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32(NULL, NULL, 11, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32(NULL, NULL, 14, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32(dest, "ABCDEFGHI", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32(dest, "ABCDEFGHIJK", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32(dest, "ABCDEFGHIJKLMN", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32(dest, "ABCDEFGH*IJ", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base32(dest, "ABCEEFGH*IJ", APR_ENCODE_STRING,
++ APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 5, len);
++
++ /* base32_binary */
++ rv = apr_decode_base32_binary(udest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_decode_base32_binary(udest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++ rv = apr_decode_base32_binary(NULL, NULL, 9, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32_binary(NULL, NULL, 11, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32_binary(NULL, NULL, 14, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32_binary(udest, "ABCDEFGHI", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32_binary(udest, "ABCDEFGHIJK", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32_binary(udest, "ABCDEFGHIJKLMN", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base32_binary(udest, "ABCDEFGH*IJ", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base32_binary(udest, "ABCEEFGH*IJ", APR_ENCODE_STRING,
++ APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 5, len);
++
++ /* base16 */
++ rv = apr_decode_base16(dest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_decode_base16(dest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++ rv = apr_decode_base16(NULL, NULL, 3, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16(dest, "ABC", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16(dest, "ABCD*EF", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base16(dest, "ABCD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 2, len);
++ /* base16 with colon */
++ rv = apr_decode_base16(dest, "AB:", APR_ENCODE_STRING,
++ APR_ENCODE_COLON, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16(dest, "AB:C", APR_ENCODE_STRING,
++ APR_ENCODE_COLON, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16(dest, "AB:CD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_COLON, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base16(dest, "AB:CD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_COLON|APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 2, len);
++
++ /* base16_binary */
++ rv = apr_decode_base16_binary(udest, "", -2, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINVAL, rv);
++ rv = apr_decode_base16_binary(udest, NULL, APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv);
++ rv = apr_decode_base16_binary(NULL, NULL, 3, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16_binary(udest, "ABC", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16_binary(udest, "ABCD*EF", APR_ENCODE_STRING, 0, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base16_binary(udest, "ABCD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 2, len);
++ /* base16_binary with colon */
++ rv = apr_decode_base16_binary(udest, "AB:", APR_ENCODE_STRING,
++ APR_ENCODE_COLON, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16_binary(udest, "AB:C", APR_ENCODE_STRING,
++ APR_ENCODE_COLON, &len);
++ ABTS_INT_EQUAL(tc, APR_EINCOMPLETE, rv);
++ rv = apr_decode_base16_binary(udest, "AB:CD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_COLON, &len);
++ ABTS_INT_EQUAL(tc, APR_BADCH, rv);
++ rv = apr_decode_base16_binary(udest, "AB:CD*EF", APR_ENCODE_STRING,
++ APR_ENCODE_COLON|APR_ENCODE_RELAXED, &len);
++ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
++ ABTS_SIZE_EQUAL(tc, 2, len);
++}
++
+ abts_suite *testencode(abts_suite * suite)
+ {
+ suite = ADD_SUITE(suite);
+@@ -921,6 +1117,8 @@
+ abts_run_test(suite, test_encode_base16_binary, NULL);
+ abts_run_test(suite, test_decode_base16, NULL);
+ abts_run_test(suite, test_decode_base16_binary, NULL);
++ abts_run_test(suite, test_encode_errors, NULL);
++ abts_run_test(suite, test_decode_errors, NULL);
+
+ return suite;
+ }
diff --git a/apr-1.7.0-r1891269+.patch b/apr-1.7.0-r1891269+.patch
new file mode 100644
index 0000000..1949d1a
--- /dev/null
+++ b/apr-1.7.0-r1891269+.patch
@@ -0,0 +1,239 @@
+# ./pullrev.sh 1891269 1891198 1891196
+http://svn.apache.org/viewvc?view=revision&revision=1891269
+http://svn.apache.org/viewvc?view=revision&revision=1891198
+http://svn.apache.org/viewvc?view=revision&revision=1891196
+
+--- apr-1.7.0/include/arch/unix/apr_arch_thread_mutex.h
++++ apr-1.7.0/include/arch/unix/apr_arch_thread_mutex.h
+@@ -33,8 +33,10 @@
+ struct apr_thread_mutex_t {
+ apr_pool_t *pool;
+ pthread_mutex_t mutex;
++#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+ apr_thread_cond_t *cond;
+ int locked, num_waiters;
++#endif
+ };
+ #endif
+
+--- apr-1.7.0/locks/unix/thread_mutex.c
++++ apr-1.7.0/locks/unix/thread_mutex.c
+@@ -102,6 +102,7 @@
+ {
+ apr_status_t rv;
+
++#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+ if (mutex->cond) {
+ apr_status_t rv2;
+
+@@ -133,6 +134,7 @@
+
+ return rv;
+ }
++#endif
+
+ rv = pthread_mutex_lock(&mutex->mutex);
+ #ifdef HAVE_ZOS_PTHREADS
+@@ -148,6 +150,7 @@
+ {
+ apr_status_t rv;
+
++#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+ if (mutex->cond) {
+ apr_status_t rv2;
+
+@@ -177,6 +180,7 @@
+
+ return rv;
+ }
++#endif
+
+ rv = pthread_mutex_trylock(&mutex->mutex);
+ if (rv) {
+@@ -281,6 +285,7 @@
+ {
+ apr_status_t status;
+
++#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+ if (mutex->cond) {
+ status = pthread_mutex_lock(&mutex->mutex);
+ if (status) {
+@@ -303,6 +308,7 @@
+
+ mutex->locked = 0;
+ }
++#endif
+
+ status = pthread_mutex_unlock(&mutex->mutex);
+ #ifdef HAVE_ZOS_PTHREADS
+@@ -318,9 +324,12 @@
+ {
+ apr_status_t rv, rv2 = APR_SUCCESS;
+
++#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+ if (mutex->cond) {
+ rv2 = apr_thread_cond_destroy(mutex->cond);
+ }
++#endif
++
+ rv = apr_pool_cleanup_run(mutex->pool, mutex, thread_mutex_cleanup);
+ if (rv == APR_SUCCESS) {
+ rv = rv2;
+--- apr-1.7.0/random/unix/sha2.c
++++ apr-1.7.0/random/unix/sha2.c
+@@ -425,7 +425,7 @@
+ usedspace = freespace = 0;
+ }
+
+-void apr__SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
++void apr__SHA256_Final(sha2_byte digest[SHA256_DIGEST_LENGTH], SHA256_CTX* context) {
+ sha2_word32 *d = (sha2_word32*)digest;
+ unsigned int usedspace;
+
+@@ -496,7 +496,7 @@
+ usedspace = 0;
+ }
+
+-char *apr__SHA256_End(SHA256_CTX* context, char buffer[]) {
++char *apr__SHA256_End(SHA256_CTX* context, char buffer[SHA256_DIGEST_STRING_LENGTH]) {
+ sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
+ int i;
+
+--- apr-1.7.0/time/unix/time.c
++++ apr-1.7.0/time/unix/time.c
+@@ -142,6 +142,9 @@
+ static const int dayoffset[12] =
+ {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
+
++ if (xt->tm_mon < 0 || xt->tm_mon >= 12)
++ return APR_EBADDATE;
++
+ /* shift new year to 1st March in order to make leap year calc easy */
+
+ if (xt->tm_mon < 2)
+--- apr-1.7.0/time/win32/time.c
++++ apr-1.7.0/time/win32/time.c
+@@ -54,6 +54,9 @@
+ static const int dayoffset[12] =
+ {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+
++ if (tm->wMonth < 1 || tm->wMonth > 12)
++ return APR_EBADDATE;
++
+ /* Note; the caller is responsible for filling in detailed tm_usec,
+ * tm_gmtoff and tm_isdst data when applicable.
+ */
+@@ -228,6 +231,9 @@
+ static const int dayoffset[12] =
+ {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275};
+
++ if (xt->tm_mon < 0 || xt->tm_mon >= 12)
++ return APR_EBADDATE;
++
+ /* shift new year to 1st March in order to make leap year calc easy */
+
+ if (xt->tm_mon < 2)
+--- apr-1.7.0/file_io/unix/readwrite.c
++++ apr-1.7.0/file_io/unix/readwrite.c
+@@ -146,7 +146,7 @@
+
+ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_size_t *nbytes)
+ {
+- apr_size_t rv;
++ apr_size_t rv = APR_SUCCESS;
+
+ if (thefile->buffered) {
+ char *pos = (char *)buf;
+@@ -160,13 +160,14 @@
+ * logically reading from
+ */
+ apr_int64_t offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
+- if (offset != thefile->filePtr)
+- lseek(thefile->filedes, offset, SEEK_SET);
++ if (offset != thefile->filePtr) {
++ thefile->filePtr = lseek(thefile->filedes, offset, SEEK_SET);
++ if (thefile->filePtr == -1) rv = errno;
++ }
+ thefile->bufpos = thefile->dataRead = 0;
+ thefile->direction = 1;
+ }
+
+- rv = 0;
+ while (rv == 0 && size > 0) {
+ if (thefile->bufpos == thefile->bufsize) /* write buffer is full*/
+ rv = apr_file_flush_locked(thefile);
+@@ -244,12 +245,15 @@
+ */
+ apr_int64_t offset = thefile->filePtr - thefile->dataRead +
+ thefile->bufpos;
+- if (offset != thefile->filePtr)
+- lseek(thefile->filedes, offset, SEEK_SET);
++ if (offset != thefile->filePtr) {
++ thefile->filePtr = lseek(thefile->filedes, offset, SEEK_SET);
++ if (thefile->filePtr == -1) rv = errno;
++ }
+ thefile->bufpos = thefile->dataRead = 0;
+ }
+
+ file_unlock(thefile);
++ if (rv) return rv;
+ }
+
+ if ((bytes = writev(thefile->filedes, vec, nvec)) < 0) {
+--- apr-1.7.0/locks/unix/proc_mutex.c
++++ apr-1.7.0/locks/unix/proc_mutex.c
+@@ -1518,11 +1518,10 @@
+
+ APR_DECLARE(const char *) apr_proc_mutex_defname(void)
+ {
+- apr_status_t rv;
+ apr_proc_mutex_t mutex;
+
+- if ((rv = proc_mutex_choose_method(&mutex, APR_LOCK_DEFAULT,
+- NULL)) != APR_SUCCESS) {
++ if (proc_mutex_choose_method(&mutex, APR_LOCK_DEFAULT,
++ NULL) != APR_SUCCESS) {
+ return "unknown";
+ }
+
+--- apr-1.7.0/memory/unix/apr_pools.c
++++ apr-1.7.0/memory/unix/apr_pools.c
+@@ -1338,7 +1338,7 @@
+ apr_size_t free_index;
+
+ pool_concurrency_set_used(pool);
+- ps.node = active = pool->active;
++ ps.node = pool->active;
+ ps.pool = pool;
+ ps.vbuff.curpos = ps.node->first_avail;
+
+--- apr-1.7.0/test/teststr.c
++++ apr-1.7.0/test/teststr.c
+@@ -394,6 +394,19 @@
+ ABTS_STR_EQUAL(tc, apr_cstr_skip_prefix("", "12"), NULL);
+ }
+
++static void pstrcat(abts_case *tc, void *data)
++{
++ ABTS_STR_EQUAL(tc, apr_pstrcat(p, "a", "bc", "def", NULL),
++ "abcdef");
++ ABTS_STR_EQUAL(tc, apr_pstrcat(p, NULL), "");
++ ABTS_STR_EQUAL(tc, apr_pstrcat(p,
++ "a", "b", "c", "d", "e",
++ "f", "g", "h", "i", "j",
++ "1", "2", "3", "4", "5",
++ NULL),
++ "abcdefghij12345");
++}
++
+ abts_suite *teststr(abts_suite *suite)
+ {
+ suite = ADD_SUITE(suite)
+@@ -412,6 +425,7 @@
+ abts_run_test(suite, string_cpystrn, NULL);
+ abts_run_test(suite, snprintf_overflow, NULL);
+ abts_run_test(suite, skip_prefix, NULL);
++ abts_run_test(suite, pstrcat, NULL);
+
+ return suite;
+ }
diff --git a/apr-1.7.0-r1894167.patch b/apr-1.7.0-r1894167.patch
new file mode 100644
index 0000000..02a73de
--- /dev/null
+++ b/apr-1.7.0-r1894167.patch
@@ -0,0 +1,37 @@
+# ./pullrev.sh 1894167
+http://svn.apache.org/viewvc?view=revision&revision=1894167
+
+--- apr-1.7.0/build/apr_network.m4
++++ apr-1.7.0/build/apr_network.m4
+@@ -906,8 +906,16 @@
+ dnl
+ AC_DEFUN([APR_CHECK_SCTP],
+ [
+- AC_CACHE_CHECK([whether SCTP is supported], [apr_cv_sctp], [
+- AC_TRY_RUN([
++AC_ARG_ENABLE([sctp],
++ APR_HELP_STRING([--disable-sctp], [disable SCTP protocol support]),
++ [apr_wants_sctp=$enableval],
++ [apr_wants_sctp=any])
++
++if test "$apr_wants_sctp" = no; then
++ apr_cv_sctp=no
++else
++ AC_CACHE_CHECK([whether SCTP is supported], [apr_cv_sctp], [
++ AC_TRY_RUN([
+ #ifdef HAVE_SYS_TYPES_H
+ #include <sys/types.h>
+ #endif
+@@ -932,7 +940,12 @@
+ exit(2);
+ exit(0);
+ }], [apr_cv_sctp=yes], [apr_cv_sctp=no], [apr_cv_sctp=no])])
++fi
+
++if test "${apr_wants_sctp}X${apr_cv_sctp}" = yesXno; then
++ AC_MSG_ERROR([SCTP support requested but not available])
++fi
++
+ if test "$apr_cv_sctp" = "yes"; then
+ have_sctp=1
+ else
diff --git a/apr-wrapper.h b/apr-wrapper.h
new file mode 100644
index 0000000..2641f76
--- /dev/null
+++ b/apr-wrapper.h
@@ -0,0 +1,22 @@
+/* This file is here to prevent a file conflict on multiarch systems. A
+ * conflict will occur because apr.h has arch-specific definitions.
+ *
+ * DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */
+
+#if defined(__i386__)
+#include "apr-i386.h"
+#elif defined(__ia64__)
+#include "apr-ia64.h"
+#elif defined(__powerpc64__)
+#include "apr-ppc64.h"
+#elif defined(__powerpc__)
+#include "apr-ppc.h"
+#elif defined(__s390x__)
+#include "apr-s390x.h"
+#elif defined(__s390__)
+#include "apr-s390.h"
+#elif defined(__x86_64__)
+#include "apr-x86_64.h"
+#else
+#error "This apr-devel package does not work your architecture?"
+#endif
diff --git a/apr.spec b/apr.spec
new file mode 100644
index 0000000..6d34524
--- /dev/null
+++ b/apr.spec
@@ -0,0 +1,669 @@
+%define aprver 1
+
+# Arches on which the multilib apr.h hack is needed:
+%define multilib_arches %{ix86} ia64 ppc ppc64 s390 s390x x86_64
+
+Summary: Apache Portable Runtime library
+Name: apr
+Version: 1.7.0
+Release: 12%{?dist}
+# ASL 2.0: everything
+# ISC: network_io/apr-1.4.6/network_io/unix/inet_?to?.c
+# BSD with advertising: strings/apr_snprintf.c, strings/apr_fnmatch.c,
+# include/apr_fnmatch.h, misc/unix/getopt.c,
+# file_io/unix/mktemp.c, strings/apr_strings.c
+# BSD (3-clause): strings/apr_strnatcmp.c, include/apr_strings.h
+License: ASL 2.0 and BSD with advertising and ISC and BSD
+URL: https://apr.apache.org/
+Source0: https://www.apache.org/dist/apr/%{name}-%{version}.tar.bz2
+Source1: apr-wrapper.h
+Patch1: apr-1.2.2-libdir.patch
+Patch2: apr-1.2.7-pkgconf.patch
+Patch3: apr-1.7.0-deepbind.patch
+Patch4: apr-1.7.0-r1891269+.patch
+Patch5: apr-1.7.0-r1894167.patch
+Patch6: apr-1.7.0-encoding.patch
+BuildRequires: gcc, autoconf, libtool, libuuid-devel, python3
+BuildRequires: make
+
+%description
+The mission of the Apache Portable Runtime (APR) is to provide a
+free library of C data structures and routines, forming a system
+portability layer to as many operating systems as possible,
+including Unices, MS Win32, BeOS and OS/2.
+
+%package devel
+Summary: APR library development kit
+Conflicts: subversion-devel < 0.20.1-2
+Requires: apr = %{version}-%{release}, pkgconfig
+
+%description devel
+This package provides the support files which can be used to
+build applications using the APR library. The mission of the
+Apache Portable Runtime (APR) is to provide a free library of
+C data structures and routines.
+
+%prep
+%setup -q
+%patch1 -p1 -b .libdir
+%patch2 -p1 -b .pkgconf
+%patch3 -p1 -b .deepbind
+%patch4 -p1 -b .r1891269+
+%patch5 -p1 -b .r1894167
+%patch6 -p1 -b .encoding
+
+%build
+# regenerate configure script etc.
+./buildconf
+
+# Forcibly prevent detection of shm_open (which then picks up but
+# does not use -lrt).
+export ac_cv_search_shm_open=no
+
+%configure \
+ --includedir=%{_includedir}/apr-%{aprver} \
+ --with-installbuilddir=%{_libdir}/apr-%{aprver}/build \
+ --with-devrandom=/dev/urandom \
+ --disable-static \
+ --disable-sctp
+%{make_build}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+%{make_install}
+
+mkdir -p $RPM_BUILD_ROOT/%{_datadir}/aclocal
+for f in find_apr.m4 apr_common.m4; do
+ install -p -m 644 build/$f $RPM_BUILD_ROOT/%{_datadir}/aclocal
+done
+
+# Trim exported dependecies
+sed -ri '/^dependency_libs/{s,-l(uuid|crypt) ,,g}' \
+ $RPM_BUILD_ROOT%{_libdir}/libapr*.la
+sed -ri '/^LIBS=/{s,-l(uuid|crypt) ,,g;s/ */ /g}' \
+ $RPM_BUILD_ROOT%{_bindir}/apr-%{aprver}-config
+sed -ri '/^Libs/{s,-l(uuid|crypt) ,,g}' \
+ $RPM_BUILD_ROOT%{_libdir}/pkgconfig/apr-%{aprver}.pc
+
+%ifarch %{multilib_arches}
+# Ugly hack to allow parallel installation of 32-bit and 64-bit apr-devel
+# packages:
+mv $RPM_BUILD_ROOT%{_includedir}/apr-%{aprver}/apr.h \
+ $RPM_BUILD_ROOT%{_includedir}/apr-%{aprver}/apr-%{_arch}.h
+install -c -m644 %{SOURCE1} $RPM_BUILD_ROOT%{_includedir}/apr-%{aprver}/apr.h
+%endif
+
+# Unpackaged files:
+rm -f $RPM_BUILD_ROOT%{_libdir}/apr.exp \
+ $RPM_BUILD_ROOT%{_libdir}/libapr-*.a
+
+# Additionally packaged (see https://bugzilla.redhat.com/1669589) --
+sed -i '1s,/.*,/usr/bin/python3,' build/gen-build.py
+for f in build/gen-build.py build/install.sh build/config.*; do
+ install -c -m755 $f $RPM_BUILD_ROOT%{_libdir}/apr-%{aprver}/build
+done
+
+%check
+# Fail if LFS support isn't present in a 32-bit build, since this
+# breaks ABI and the soname doesn't change: see #254241
+if grep 'define SIZEOF_VOIDP 4' include/apr.h \
+ && ! grep off64_t include/apr.h; then
+ cat config.log
+ : LFS support not present in 32-bit build
+ exit 1
+fi
+pushd test
+ make %{?_smp_mflags}
+ ./testall -v -q
+popd
+
+%ldconfig_scriptlets
+
+%files
+%doc CHANGES LICENSE NOTICE README*
+%{_libdir}/libapr-%{aprver}.so.*
+
+%files devel
+%doc docs/APRDesign.html docs/canonical_filenames.html
+%doc docs/incomplete_types docs/non_apr_programs
+%{_bindir}/apr-%{aprver}-config
+%{_libdir}/libapr-%{aprver}.*a
+%{_libdir}/libapr-%{aprver}.so
+%{_libdir}/pkgconfig/*.pc
+%dir %{_libdir}/apr-%{aprver}
+%dir %{_libdir}/apr-%{aprver}/build
+%{_libdir}/apr-%{aprver}/build/*
+%dir %{_includedir}/apr-%{aprver}
+%{_includedir}/apr-%{aprver}/*.h
+%{_datadir}/aclocal/*.m4
+
+%changelog
+* Thu Dec 7 2023 Joe Orton <jorton@redhat.com> - 1.7.0-12
+- fix integer bounds checking in apr_encode_*
+ Resolves: RHEL-17123
+
+* Mon Dec 6 2021 Joe Orton <jorton@redhat.com> - 1.7.0-11
+- always disable SCTP support at build time (#1997107)
+
+* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.7.0-10.5
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+ Related: rhbz#1991688
+
+* Fri Aug 6 2021 Florian Weimer <fweimer@redhat.com> - 1.7.0-9.5
+- Rebuild to pick up new build flags from redhat-rpm-config (#1984652)
+
+* Wed Aug 4 2021 Joe Orton <jorton@redhat.com> - 1.7.0-9.4
+- add apr_common.m4 to -devel as well (#1986937)
+
+* Wed Jul 7 2021 Joe Orton <jorton@redhat.com> - 1.7.0-9.3
+- add various Coverity/Clang cleanups (#1977418)
+
+* Fri Jun 18 2021 Joe Orton <jorton@redhat.com> - 1.7.0-9.2
+- package additional build/* files in apr-devel (#1945078)
+
+* Fri Jun 18 2021 Joe Orton <jorton@redhat.com> - 1.7.0-9.1
+- document APR_DEEPBIND and use secure_getenv() (thanks to mturk)
+
+* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 1.7.0-9
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.0-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Fri Nov 6 2020 Joe Orton <jorton@redhat.com> - 1.7.0-7
+- disable static build in libtool
+
+* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.0-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Tue Jun 16 2020 Joe Orton <jorton@redhat.com> - 1.7.0-5
+- only enable RTLD_DEEPBIND if $APR_DEEPBIND is set
+
+* Wed Mar 4 2020 Joe Orton <jorton@redhat.com> - 1.7.0-4
+- re-enable RTLD_DEEPBIND (#1739287)
+
+* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Tue Apr 16 2019 Lubos Uhliarik <luhliari@redhat.com> - 1.7.0-1
+- update to 1.7.0 (#1696401)
+
+* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.6.5-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Mon Jan 14 2019 Björn Esser <besser82@fedoraproject.org> - 1.6.5-2
+- Rebuilt for libcrypt.so.2 (#1666033)
+
+* Mon Sep 17 2018 Joe Orton <jorton@redhat.com> - 1.6.5-1
+- update to 1.6.5 (#1628934)
+
+* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.6.3-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Wed Jun 27 2018 Joe Orton <jorton@redhat.com> - 1.6.3-8
+- update to use Python 3 at build time
+
+* Wed Mar 14 2018 Iryna Shcherbina <ishcherb@redhat.com> - 1.6.3-7
+- Update Python 2 dependency declarations to new packaging standards
+ (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3)
+
+* Wed Feb 21 2018 Joe Orton <jorton@redhat.com> - 1.6.3-6
+- BuildRequires: gcc
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.6.3-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Mon Jan 29 2018 Florian Weimer <fweimer@redhat.com> - 1.6.3-4
+- Fix FTBFS in test/teststr.c with GCC 8 (#1539844)
+
+* Mon Jan 29 2018 Florian Weimer <fweimer@redhat.com> - 1.6.3-3
+- Rebuild with new redhat-rpm-config build flags
+
+* Sat Jan 20 2018 Björn Esser <besser82@fedoraproject.org> - 1.6.3-2
+- Rebuilt for switch to libxcrypt
+
+* Wed Oct 25 2017 Luboš Uhliarik <luhliari@redhat.com> - 1.6.3-1
+- new version 1.6.3
+
+* Tue Sep 19 2017 Joe Orton <jorton@redhat.com> - 1.6.2-4
+- re-enable test suite
+
+* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.6.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Sat Jul 29 2017 Florian Weimer <fweimer@redhat.com> - 1.6.2-2
+- Rebuild with binutils fix for ppc64le (#1475636)
+
+* Wed Jul 26 2017 Joe Orton <jorton@redhat.com> - 1.6.2-1
+- update to 1.6.2 (#1460830)
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.2-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.2-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Fri Apr 15 2016 David Tardon <dtardon@redhat.com> - 1.5.2-4
+- rebuild for ICU 57.1
+
+* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.5.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.5.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Wed Apr 29 2015 Jan Kaluza <jkaluza@redhat.com> - 1.5.2-1
+- update to 1.5.2 (#1217012)
+
+* Fri Aug 15 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.5.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.5.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Wed Apr 23 2014 Jan Kaluza <jkaluza@redhat.com> - 1.5.1-1
+- update to 1.5.1 (#1089917)
+
+* Tue Nov 26 2013 Joe Orton <jorton@redhat.com> - 1.5.0-2
+- update to 1.5.0
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.4.8-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Mon Jun 24 2013 Joe Orton <jorton@redhat.com> - 1.4.8-1
+- update to 1.4.8 (#976972)
+
+* Wed May 29 2013 Joe Orton <jorton@redhat.com> - 1.4.6-7
+- update config.* for aarch64 (#925009)
+
+* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.4.6-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Wed Dec 12 2012 Jan Kaluza <jkaluza@redhat.com> - 1.4.6-5
+- fix strict-aliasing gcc warning
+- remove unused SHA384 and SHA512 code
+
+* Thu Nov 22 2012 Joe Orton <jorton@redhat.com> - 1.4.6-4
+- update license
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.4.6-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Fri Jul 6 2012 Joe Orton <jorton@redhat.com> - 1.4.6-2
+- pull fix for apr_mcast_hops from upstream
+
+* Tue Feb 14 2012 Bojan Smojver <bojan@rexursive.com> - 1.4.6-1
+- bump up to 1.4.6
+
+* Thu Jan 12 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.4.5-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Thu Oct 13 2011 Joe Orton <jorton@redhat.com> - 1.4.5-2
+- remove deepbind patch, should no longer be necessary
+
+* Fri May 20 2011 Bojan Smojver <bojan@rexursive.com> - 1.4.5-1
+- bump up to 1.4.5
+
+* Tue May 10 2011 Bojan Smojver <bojan@rexursive.com> - 1.4.4-2
+- fix top_builddir in apr_rules.mk
+
+* Mon May 9 2011 Bojan Smojver <bojan@rexursive.com> - 1.4.4-1
+- bump up to 1.4.4
+- CVE-2011-0419
+
+* Wed Mar 2 2011 Joe Orton <jorton@redhat.com> - 1.4.2-3
+- work around alising issue in ring macros (upstream PR 50190)
+- fix buildconf with newer libtool (#670621)
+
+* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.4.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Sat Dec 4 2010 Joe Orton <jorton@redhat.com> - 1.4.2-1
+- update to 1.4.2
+- always enable SCTP support (#659815)
+
+* Sun Oct 25 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.9-3
+- remove uuid/crypt libs from pkg-config file (#511522)
+
+* Mon Sep 28 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.9-2
+- revert use of accept4(), dup3() and epoll_create1()
+
+* Fri Sep 25 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.9-1
+- bump up to 1.3.9
+
+* Thu Aug 6 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.8-1
+- bump up to 1.3.8
+- CVE-2009-2412
+- allocator alignment fixes
+
+* Sun Jul 26 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.7-2
+- include apr_cv_sock_cloexec too
+
+* Sun Jul 26 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.7-1
+- bump up to 1.3.7
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3.6-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Wed Jul 15 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.6-1
+- bump up to 1.3.6
+
+* Tue Jun 30 2009 Joe Orton <jorton@redhat.com> 1.3.5-5
+- BR libuuid-devel instead of e2fsprogs-devel
+
+* Mon Jun 8 2009 Bojan Smojver <bojan@rexursive.com> - 1.3.5-4
+- bump up to 1.3.5
+
+* Mon Feb 23 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3.3-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Wed Feb 4 2009 Joe Orton <jorton@redhat.com> 1.3.3
+- fix build with libtool 2.2
+
+* Fri Jan 2 2009 Joe Orton <jorton@redhat.com> 1.3.3
+- rebuild
+
+* Sat Aug 16 2008 Bojan Smojver <bojan@rexursive.com> - 1.3.3-1
+- bump up to 1.3.3
+
+* Wed Jul 16 2008 Bojan Smojver <bojan@rexursive.com> - 1.3.2-2
+- ship find_apr.m4, fix bug #455189
+
+* Thu Jun 19 2008 Bojan Smojver <bojan@rexursive.com> - 1.3.2-1
+- bump up to 1.3.2
+
+* Sun Jun 1 2008 Bojan Smojver <bojan@rexursive.com> - 1.3.0-1
+- bump up to 1.3.0
+
+* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 1.2.12-2
+- Autorebuild for GCC 4.3
+
+* Mon Nov 26 2007 Bojan Smojver <bojan@rexursive.com> 1.2.12-1
+- bump up to 1.2.12
+- add dist
+- remove a comment from apr-1.2.7-psprintfpi.patch (applied upstream)
+
+* Tue Sep 18 2007 Joe Orton <jorton@redhat.com> 1.2.11-2
+- fix %%check for non-multilib 64-bit platforms
+
+* Sun Sep 9 2007 Bojan Smojver <bojan@rexursive.com> 1.2.11-1
+- bump up to 1.2.11
+- drop openlfs patch (fixed upstream)
+
+* Sun Sep 2 2007 Joe Orton <jorton@redhat.com> 1.2.9-4
+- fix API/ABI of 32-bit builds (#254241)
+
+* Tue Aug 21 2007 Joe Orton <jorton@redhat.com> 1.2.9-2
+- fix License
+
+* Mon Jun 25 2007 Bojan Smojver <bojan@rexursive.com> 1.2.9-1
+- bump up to 1.2.9
+
+* Mon Jun 4 2007 Joe Orton <jorton@redhat.com> 1.2.8-7
+- drop %%check section entirely; inappropriate to run in build env.
+
+* Fri Mar 30 2007 Joe Orton <jorton@redhat.com> 1.2.8-6
+- merge review (#225253): drop .a archive; drop use of CC/CXX,
+ use BuildRequires; drop old Conflicts; URL reference for Source
+
+* Thu Mar 22 2007 Joe Orton <jorton@redhat.com> 1.2.8-5
+- drop the doxygen documentation (which causes multilib conflicts)
+
+* Thu Feb 15 2007 Joe Orton <jorton@redhat.com> 1.2.8-4
+- add BR for python
+
+* Thu Feb 15 2007 Joe Orton <jorton@redhat.com> 1.2.8-3
+- update to pick up new libtool, drop specific gcc requirement
+
+* Mon Dec 4 2006 Joe Orton <jorton@redhat.com> 1.2.8-2
+- update to 1.2.8
+
+* Wed Jul 19 2006 Joe Orton <jorton@redhat.com> 1.2.7-10
+- fix buildconf with autoconf 2.60 (#199067)
+
+* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> 1.2.7-9.1
+- rebuild
+
+* Mon Jun 19 2006 Joe Orton <jorton@redhat.com> 1.2.7-9
+- add fix for use of %%pI with psprintf
+
+* Fri May 26 2006 Jakub Jelinek <jakub@redhat.com> 1.2.7-8
+- rebuilt with GCC 4.1.0
+
+* Tue May 23 2006 Joe Orton <jorton@redhat.com> 1.2.7-7
+- fix another multilib conflict (#192659)
+
+* Tue May 16 2006 Joe Orton <jorton@redhat.com> 1.2.7-6
+- BR e2fsprogs-devel for libuuid
+
+* Mon May 8 2006 Joe Orton <jorton@redhat.com> 1.2.7-4
+- use multilib parallel-installation wrapper hack for apr.h
+
+* Tue May 2 2006 Joe Orton <jorton@redhat.com> 1.2.7-3
+- fix installbuilddir in apr-1-config
+
+* Tue May 2 2006 Joe Orton <jorton@redhat.com> 1.2.7-2
+- update to 1.2.7
+- use pkg-config in apr-1-config to make it libdir-agnostic
+
+* Thu Apr 6 2006 Joe Orton <jorton@redhat.com> 1.2.6-2
+- update to 1.2.6
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 1.2.2-7.2
+- bump again for double-long bug on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 1.2.2-7.1
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Wed Jan 4 2006 Joe Orton <jorton@redhat.com> 1.2.2-7
+- fix namespace pollution (r354824, r355464)
+
+* Wed Jan 4 2006 Joe Orton <jorton@redhat.com> 1.2.2-6
+- fix build with recent glibc (#176911)
+
+* Tue Jan 3 2006 Jesse Keating <jkeating@redhat.com> 1.2.2-5.2
+- rebuilt again
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Fri Dec 9 2005 Joe Orton <jorton@redhat.com> 1.2.2-5
+- rebuild for new gcc
+
+* Thu Dec 8 2005 Joe Orton <jorton@redhat.com> 1.2.2-4
+- add apr_file_seek() fixes from upstream (r326593, r326597)
+
+* Wed Dec 7 2005 Joe Orton <jorton@redhat.com> 1.2.2-3
+- apr-1-config: strip more exports (#175124)
+
+* Tue Dec 6 2005 Joe Orton <jorton@redhat.com> 1.2.2-2
+- avoid linking against -lrt
+- don't print -L${libdir} in --libs output
+- don't export -lcrypt/-luuid in .la file
+
+* Fri Dec 2 2005 Joe Orton <jorton@redhat.com> 1.2.2-1
+- update to 1.2.2
+
+* Thu Nov 24 2005 Joe Orton <jorton@redhat.com> 0.9.7-3
+- use RTLD_DEEPBIND in apr_dso_open by default
+
+* Thu Oct 20 2005 Joe Orton <jorton@redhat.com> 0.9.7-2
+- update to 0.9.7
+
+* Fri Sep 30 2005 Florian La Roche <laroche@redhat.com>
+- rebuild for new gcc
+
+* Thu Sep 15 2005 Joe Orton <jorton@redhat.com> 0.9.6-6
+- don't override CFLAGS at build time
+- allow setting TCP_NODELAY and TCP_CORK concurrently
+- use _exit() not exit() in child if exec*() fails (upstream #30913)
+
+* Fri Sep 9 2005 Joe Orton <jorton@redhat.com> 0.9.6-5
+- add from 0.9.x branch:
+ * fix for apr_{uid,gid}_* error handling (r239592)
+ * fix for apr_file_ write flushing (r267192)
+- add backport for use of readdir64_r (r265032, r265681, r265684)
+
+* Mon Jul 11 2005 Florian La Roche <laroche@redhat.com>
+- rebuild
+
+* Tue May 17 2005 Joe Orton <jorton@redhat.com> 0.9.6-3
+- fix apr_procattr_child_*_set error handling
+
+* Tue Mar 1 2005 Joe Orton <jorton@redhat.com> 0.9.6-2
+- have apr-devel depend on specific version of gcc
+- add NOTICE to docdir
+
+* Wed Feb 9 2005 Joe Orton <jorton@redhat.com> 0.9.6-1
+- update to 0.9.6
+
+* Wed Feb 2 2005 Joe Orton <jorton@redhat.com> 0.9.5-4
+- don't disable sendfile on s390 (IBM LTC, #146891)
+
+* Mon Nov 22 2004 Joe Orton <jorton@redhat.com> 0.9.5-3
+- really fix apr-config --srcdir
+
+* Mon Nov 22 2004 Joe Orton <jorton@redhat.com> 0.9.5-2
+- fix apr-config --srcdir again
+
+* Sun Nov 21 2004 Joe Orton <jorton@redhat.com> 0.9.5-1
+- update to 0.9.5
+
+* Mon Sep 27 2004 Joe Orton <jorton@redhat.com> 0.9.4-24
+- rebuild
+
+* Wed Sep 1 2004 Joe Orton <jorton@redhat.com> 0.9.4-23
+- have -devel require apr of same V-R
+
+* Tue Aug 31 2004 Joe Orton <jorton@redhat.com> 0.9.4-22
+- backport fixes from HEAD:
+ * correct implementation of nested mutexes
+ * support for POSIX semaphores on LP64 platforms
+
+* Thu Jul 15 2004 Joe Orton <jorton@redhat.com> 0.9.4-21
+- rebuild for another attempt at using sem_open
+
+* Tue Jul 13 2004 Joe Orton <jorton@redhat.com> 0.9.4-20
+- move sticky/suid bits outside APR_OS_DEFAULT bitmask (Greg Hudson)
+
+* Thu Jul 1 2004 Joe Orton <jorton@redhat.com> 0.9.4-19
+- rebuild
+
+* Wed Jun 30 2004 Joe Orton <jorton@redhat.com> 0.9.4-18
+- rebuild now /dev/shm is mounted
+
+* Thu Jun 17 2004 Joe Orton <jorton@redhat.com> 0.9.4-17
+- add fix for cleanup structure reuse (part of upstream #23567)
+
+* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Thu Jun 10 2004 Joe Orton <jorton@redhat.com> 0.9.4-15
+- add support for setuid/setgid/sticky bits (André Malo)
+- add apr_threadattr_{guardsize,stacksize}_set() (latter by Jeff Trawick)
+
+* Mon Jun 7 2004 Joe Orton <jorton@redhat.com> 0.9.4-14
+- enable posixsem and process-shared pthread mutex support, but
+ ensure that sysvsem remains the default mechanism
+
+* Mon May 24 2004 Joe Orton <jorton@redhat.com> 0.9.4-13
+- entirely remove 2Gb file size limit from apr_file_copy();
+ fixes "svnadmin hotcopy" on repos with >2Gb strings table
+- work around getnameinfo bugs with v4-mapped addresses
+- fix apr_time_exp_get() for dates in 2038 (Philip Martin)
+
+* Thu May 13 2004 Joe Orton <jorton@redhat.com> 0.9.4-12
+- use APR_LARGEFILE in apr_file_{copy,append}
+
+* Wed Mar 24 2004 Joe Orton <jorton@redhat.com> 0.9.4-11
+- add APR_LARGEFILE flag
+
+* Mon Mar 15 2004 Joe Orton <jorton@redhat.com> 0.9.4-10
+- fix configure check for mmap of /dev/zero
+- just put -D_GNU_SOURCE in CPPFLAGS not _{BSD,SVID,XOPEN}_SOURCE
+
+* Tue Mar 02 2004 Elliot Lee <sopwith@redhat.com> 0.9.4-9.1
+- rebuilt
+
+* Thu Feb 19 2004 Joe Orton <jorton@redhat.com> 0.9.4-9
+- undocument apr_dir_read() ordering constraint and fix tests
+
+* Sun Feb 15 2004 Joe Orton <jorton@redhat.com> 0.9.4-8
+- rebuilt without -Wall -Werror
+
+* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com> 0.9.4-7
+- rebuilt
+
+* Tue Feb 3 2004 Joe Orton <jorton@redhat.com> 0.9.4-6
+- define apr_off_t as int/long/... to prevent it changing
+ with _FILE_OFFSET_BITS on 32-bit platforms
+
+* Mon Jan 12 2004 Joe Orton <jorton@redhat.com> 0.9.4-5
+- add apr_temp_dir_get fixes from HEAD
+
+* Thu Jan 8 2004 Joe Orton <jorton@redhat.com> 0.9.4-4
+- ensure that libapr is linked against libpthread
+- don't link libapr against -lnsl
+
+* Thu Nov 13 2003 Joe Orton <jorton@redhat.com> 0.9.4-3
+- -devel package no longer requires libtool
+
+* Fri Oct 3 2003 Joe Orton <jorton@redhat.com> 0.9.4-2
+- disable tests on x86_64 (#97611)
+
+* Fri Oct 3 2003 Joe Orton <jorton@redhat.com> 0.9.4-1
+- update to 0.9.4, enable tests
+- ensure that libresolv is not used
+
+* Sun Sep 7 2003 Joe Orton <jorton@redhat.com> 0.9.3-14
+- use /dev/urandom (#103049)
+
+* Thu Jul 24 2003 Joe Orton <jorton@redhat.com> 0.9.3-13
+- add back CC=gcc, CXX=g++
+
+* Tue Jul 22 2003 Nalin Dahyabhai <nalin@redhat.com> 0.9.3-12
+- rebuild
+
+* Mon Jul 14 2003 Joe Orton <jorton@redhat.com> 0.9.3-11
+- work round useless autoconf 2.57 AC_DECL_SYS_SIGLIST
+
+* Thu Jul 10 2003 Joe Orton <jorton@redhat.com> 0.9.3-10
+- support --cc and --cpp arguments in apr-config
+
+* Thu Jul 3 2003 Joe Orton <jorton@redhat.com> 0.9.3-9
+- force libtool to use CC=gcc, CXX=g++
+
+* Thu Jul 3 2003 Joe Orton <jorton@redhat.com> 0.9.3-8
+- fix libtool location in apr_rules.mk
+
+* Mon Jun 30 2003 Joe Orton <jorton@redhat.com> 0.9.3-7
+- use AI_ADDRCONFIG in getaddrinfo() support (#73350)
+- include a working libtool script rather than relying on
+ /usr/bin/libtool (#97695)
+
+* Wed Jun 18 2003 Joe Orton <jorton@redhat.com> 0.9.3-6
+- don't use /usr/bin/libtool
+
+* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Tue May 20 2003 Joe Orton <jorton@redhat.com> 0.9.3-5
+- add fix for psprintf memory corruption (CAN-2003-0245)
+- remove executable bit from apr_poll.h
+
+* Thu May 1 2003 Joe Orton <jorton@redhat.com> 0.9.3-4
+- link libapr against libpthread
+- make apr-devel conflict with old subversion-devel
+- fix License
+
+* Tue Apr 29 2003 Joe Orton <jorton@redhat.com> 0.9.3-3
+- run ldconfig in post/postun
+
+* Tue Apr 29 2003 Joe Orton <jorton@redhat.com> 0.9.3-2
+- patch test suite to not care if IPv6 is disabled
+
+* Mon Apr 28 2003 Joe Orton <jorton@redhat.com> 0.9.3-1
+- initial build
diff --git a/sources b/sources
new file mode 100644
index 0000000..451c099
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+7a14a83d664e87599ea25ff4432e48a7 apr-1.7.0.tar.bz2