From ca65db90881b9e911560b3d75a97c3b35bafc2fc Mon Sep 17 00:00:00 2001 From: Toshaan Bharvani Date: Thu, 30 May 2024 09:47:18 +0200 Subject: [PATCH] initial package creation Signed-off-by: Toshaan Bharvani --- SOURCES/apr-1.2.2-libdir.patch | 18 + SOURCES/apr-1.2.7-pkgconf.patch | 56 + SOURCES/apr-1.7.0-deepbind.patch | 60 + SOURCES/apr-1.7.0-encoding.patch | 2839 +++++++++++++++++++++++++++++ SOURCES/apr-1.7.0-r1891269+.patch | 239 +++ SOURCES/apr-1.7.0-r1894167.patch | 37 + SOURCES/apr-wrapper.h | 22 + SPECS/apr.spec | 669 +++++++ 8 files changed, 3940 insertions(+) create mode 100644 SOURCES/apr-1.2.2-libdir.patch create mode 100644 SOURCES/apr-1.2.7-pkgconf.patch create mode 100644 SOURCES/apr-1.7.0-deepbind.patch create mode 100644 SOURCES/apr-1.7.0-encoding.patch create mode 100644 SOURCES/apr-1.7.0-r1891269+.patch create mode 100644 SOURCES/apr-1.7.0-r1894167.patch create mode 100644 SOURCES/apr-wrapper.h create mode 100644 SPECS/apr.spec diff --git a/SOURCES/apr-1.2.2-libdir.patch b/SOURCES/apr-1.2.2-libdir.patch new file mode 100644 index 0000000..aeb7ee1 --- /dev/null +++ b/SOURCES/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/SOURCES/apr-1.2.7-pkgconf.patch b/SOURCES/apr-1.2.7-pkgconf.patch new file mode 100644 index 0000000..bd6d65c --- /dev/null +++ b/SOURCES/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/SOURCES/apr-1.7.0-deepbind.patch b/SOURCES/apr-1.7.0-deepbind.patch new file mode 100644 index 0000000..3a40d22 --- /dev/null +++ b/SOURCES/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/SOURCES/apr-1.7.0-encoding.patch b/SOURCES/apr-1.7.0-encoding.patch new file mode 100644 index 0000000..f6c9dae --- /dev/null +++ b/SOURCES/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/SOURCES/apr-1.7.0-r1891269+.patch b/SOURCES/apr-1.7.0-r1891269+.patch new file mode 100644 index 0000000..1949d1a --- /dev/null +++ b/SOURCES/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/SOURCES/apr-1.7.0-r1894167.patch b/SOURCES/apr-1.7.0-r1894167.patch new file mode 100644 index 0000000..02a73de --- /dev/null +++ b/SOURCES/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 + #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/SOURCES/apr-wrapper.h b/SOURCES/apr-wrapper.h new file mode 100644 index 0000000..2641f76 --- /dev/null +++ b/SOURCES/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/SPECS/apr.spec b/SPECS/apr.spec new file mode 100644 index 0000000..6d34524 --- /dev/null +++ b/SPECS/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 - 1.7.0-12 +- fix integer bounds checking in apr_encode_* + Resolves: RHEL-17123 + +* Mon Dec 6 2021 Joe Orton - 1.7.0-11 +- always disable SCTP support at build time (#1997107) + +* Mon Aug 09 2021 Mohan Boddu - 1.7.0-10.5 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Fri Aug 6 2021 Florian Weimer - 1.7.0-9.5 +- Rebuild to pick up new build flags from redhat-rpm-config (#1984652) + +* Wed Aug 4 2021 Joe Orton - 1.7.0-9.4 +- add apr_common.m4 to -devel as well (#1986937) + +* Wed Jul 7 2021 Joe Orton - 1.7.0-9.3 +- add various Coverity/Clang cleanups (#1977418) + +* Fri Jun 18 2021 Joe Orton - 1.7.0-9.2 +- package additional build/* files in apr-devel (#1945078) + +* Fri Jun 18 2021 Joe Orton - 1.7.0-9.1 +- document APR_DEEPBIND and use secure_getenv() (thanks to mturk) + +* Thu Apr 15 2021 Mohan Boddu - 1.7.0-9 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Tue Jan 26 2021 Fedora Release Engineering - 1.7.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Fri Nov 6 2020 Joe Orton - 1.7.0-7 +- disable static build in libtool + +* Mon Jul 27 2020 Fedora Release Engineering - 1.7.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jun 16 2020 Joe Orton - 1.7.0-5 +- only enable RTLD_DEEPBIND if $APR_DEEPBIND is set + +* Wed Mar 4 2020 Joe Orton - 1.7.0-4 +- re-enable RTLD_DEEPBIND (#1739287) + +* Tue Jan 28 2020 Fedora Release Engineering - 1.7.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Jul 24 2019 Fedora Release Engineering - 1.7.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Tue Apr 16 2019 Lubos Uhliarik - 1.7.0-1 +- update to 1.7.0 (#1696401) + +* Thu Jan 31 2019 Fedora Release Engineering - 1.6.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Jan 14 2019 Björn Esser - 1.6.5-2 +- Rebuilt for libcrypt.so.2 (#1666033) + +* Mon Sep 17 2018 Joe Orton - 1.6.5-1 +- update to 1.6.5 (#1628934) + +* Thu Jul 12 2018 Fedora Release Engineering - 1.6.3-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Wed Jun 27 2018 Joe Orton - 1.6.3-8 +- update to use Python 3 at build time + +* Wed Mar 14 2018 Iryna Shcherbina - 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 - 1.6.3-6 +- BuildRequires: gcc + +* Wed Feb 07 2018 Fedora Release Engineering - 1.6.3-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Jan 29 2018 Florian Weimer - 1.6.3-4 +- Fix FTBFS in test/teststr.c with GCC 8 (#1539844) + +* Mon Jan 29 2018 Florian Weimer - 1.6.3-3 +- Rebuild with new redhat-rpm-config build flags + +* Sat Jan 20 2018 Björn Esser - 1.6.3-2 +- Rebuilt for switch to libxcrypt + +* Wed Oct 25 2017 Luboš Uhliarik - 1.6.3-1 +- new version 1.6.3 + +* Tue Sep 19 2017 Joe Orton - 1.6.2-4 +- re-enable test suite + +* Wed Aug 02 2017 Fedora Release Engineering - 1.6.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Sat Jul 29 2017 Florian Weimer - 1.6.2-2 +- Rebuild with binutils fix for ppc64le (#1475636) + +* Wed Jul 26 2017 Joe Orton - 1.6.2-1 +- update to 1.6.2 (#1460830) + +* Wed Jul 26 2017 Fedora Release Engineering - 1.5.2-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 1.5.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Apr 15 2016 David Tardon - 1.5.2-4 +- rebuild for ICU 57.1 + +* Wed Feb 03 2016 Fedora Release Engineering - 1.5.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 1.5.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Apr 29 2015 Jan Kaluza - 1.5.2-1 +- update to 1.5.2 (#1217012) + +* Fri Aug 15 2014 Fedora Release Engineering - 1.5.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 1.5.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed Apr 23 2014 Jan Kaluza - 1.5.1-1 +- update to 1.5.1 (#1089917) + +* Tue Nov 26 2013 Joe Orton - 1.5.0-2 +- update to 1.5.0 + +* Sat Aug 03 2013 Fedora Release Engineering - 1.4.8-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Jun 24 2013 Joe Orton - 1.4.8-1 +- update to 1.4.8 (#976972) + +* Wed May 29 2013 Joe Orton - 1.4.6-7 +- update config.* for aarch64 (#925009) + +* Wed Feb 13 2013 Fedora Release Engineering - 1.4.6-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Dec 12 2012 Jan Kaluza - 1.4.6-5 +- fix strict-aliasing gcc warning +- remove unused SHA384 and SHA512 code + +* Thu Nov 22 2012 Joe Orton - 1.4.6-4 +- update license + +* Wed Jul 18 2012 Fedora Release Engineering - 1.4.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jul 6 2012 Joe Orton - 1.4.6-2 +- pull fix for apr_mcast_hops from upstream + +* Tue Feb 14 2012 Bojan Smojver - 1.4.6-1 +- bump up to 1.4.6 + +* Thu Jan 12 2012 Fedora Release Engineering - 1.4.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Oct 13 2011 Joe Orton - 1.4.5-2 +- remove deepbind patch, should no longer be necessary + +* Fri May 20 2011 Bojan Smojver - 1.4.5-1 +- bump up to 1.4.5 + +* Tue May 10 2011 Bojan Smojver - 1.4.4-2 +- fix top_builddir in apr_rules.mk + +* Mon May 9 2011 Bojan Smojver - 1.4.4-1 +- bump up to 1.4.4 +- CVE-2011-0419 + +* Wed Mar 2 2011 Joe Orton - 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 - 1.4.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Sat Dec 4 2010 Joe Orton - 1.4.2-1 +- update to 1.4.2 +- always enable SCTP support (#659815) + +* Sun Oct 25 2009 Bojan Smojver - 1.3.9-3 +- remove uuid/crypt libs from pkg-config file (#511522) + +* Mon Sep 28 2009 Bojan Smojver - 1.3.9-2 +- revert use of accept4(), dup3() and epoll_create1() + +* Fri Sep 25 2009 Bojan Smojver - 1.3.9-1 +- bump up to 1.3.9 + +* Thu Aug 6 2009 Bojan Smojver - 1.3.8-1 +- bump up to 1.3.8 +- CVE-2009-2412 +- allocator alignment fixes + +* Sun Jul 26 2009 Bojan Smojver - 1.3.7-2 +- include apr_cv_sock_cloexec too + +* Sun Jul 26 2009 Bojan Smojver - 1.3.7-1 +- bump up to 1.3.7 + +* Fri Jul 24 2009 Fedora Release Engineering - 1.3.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 15 2009 Bojan Smojver - 1.3.6-1 +- bump up to 1.3.6 + +* Tue Jun 30 2009 Joe Orton 1.3.5-5 +- BR libuuid-devel instead of e2fsprogs-devel + +* Mon Jun 8 2009 Bojan Smojver - 1.3.5-4 +- bump up to 1.3.5 + +* Mon Feb 23 2009 Fedora Release Engineering - 1.3.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Feb 4 2009 Joe Orton 1.3.3 +- fix build with libtool 2.2 + +* Fri Jan 2 2009 Joe Orton 1.3.3 +- rebuild + +* Sat Aug 16 2008 Bojan Smojver - 1.3.3-1 +- bump up to 1.3.3 + +* Wed Jul 16 2008 Bojan Smojver - 1.3.2-2 +- ship find_apr.m4, fix bug #455189 + +* Thu Jun 19 2008 Bojan Smojver - 1.3.2-1 +- bump up to 1.3.2 + +* Sun Jun 1 2008 Bojan Smojver - 1.3.0-1 +- bump up to 1.3.0 + +* Tue Feb 19 2008 Fedora Release Engineering - 1.2.12-2 +- Autorebuild for GCC 4.3 + +* Mon Nov 26 2007 Bojan Smojver 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 1.2.11-2 +- fix %%check for non-multilib 64-bit platforms + +* Sun Sep 9 2007 Bojan Smojver 1.2.11-1 +- bump up to 1.2.11 +- drop openlfs patch (fixed upstream) + +* Sun Sep 2 2007 Joe Orton 1.2.9-4 +- fix API/ABI of 32-bit builds (#254241) + +* Tue Aug 21 2007 Joe Orton 1.2.9-2 +- fix License + +* Mon Jun 25 2007 Bojan Smojver 1.2.9-1 +- bump up to 1.2.9 + +* Mon Jun 4 2007 Joe Orton 1.2.8-7 +- drop %%check section entirely; inappropriate to run in build env. + +* Fri Mar 30 2007 Joe Orton 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 1.2.8-5 +- drop the doxygen documentation (which causes multilib conflicts) + +* Thu Feb 15 2007 Joe Orton 1.2.8-4 +- add BR for python + +* Thu Feb 15 2007 Joe Orton 1.2.8-3 +- update to pick up new libtool, drop specific gcc requirement + +* Mon Dec 4 2006 Joe Orton 1.2.8-2 +- update to 1.2.8 + +* Wed Jul 19 2006 Joe Orton 1.2.7-10 +- fix buildconf with autoconf 2.60 (#199067) + +* Wed Jul 12 2006 Jesse Keating 1.2.7-9.1 +- rebuild + +* Mon Jun 19 2006 Joe Orton 1.2.7-9 +- add fix for use of %%pI with psprintf + +* Fri May 26 2006 Jakub Jelinek 1.2.7-8 +- rebuilt with GCC 4.1.0 + +* Tue May 23 2006 Joe Orton 1.2.7-7 +- fix another multilib conflict (#192659) + +* Tue May 16 2006 Joe Orton 1.2.7-6 +- BR e2fsprogs-devel for libuuid + +* Mon May 8 2006 Joe Orton 1.2.7-4 +- use multilib parallel-installation wrapper hack for apr.h + +* Tue May 2 2006 Joe Orton 1.2.7-3 +- fix installbuilddir in apr-1-config + +* Tue May 2 2006 Joe Orton 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 1.2.6-2 +- update to 1.2.6 + +* Fri Feb 10 2006 Jesse Keating - 1.2.2-7.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 1.2.2-7.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Wed Jan 4 2006 Joe Orton 1.2.2-7 +- fix namespace pollution (r354824, r355464) + +* Wed Jan 4 2006 Joe Orton 1.2.2-6 +- fix build with recent glibc (#176911) + +* Tue Jan 3 2006 Jesse Keating 1.2.2-5.2 +- rebuilt again + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Fri Dec 9 2005 Joe Orton 1.2.2-5 +- rebuild for new gcc + +* Thu Dec 8 2005 Joe Orton 1.2.2-4 +- add apr_file_seek() fixes from upstream (r326593, r326597) + +* Wed Dec 7 2005 Joe Orton 1.2.2-3 +- apr-1-config: strip more exports (#175124) + +* Tue Dec 6 2005 Joe Orton 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 1.2.2-1 +- update to 1.2.2 + +* Thu Nov 24 2005 Joe Orton 0.9.7-3 +- use RTLD_DEEPBIND in apr_dso_open by default + +* Thu Oct 20 2005 Joe Orton 0.9.7-2 +- update to 0.9.7 + +* Fri Sep 30 2005 Florian La Roche +- rebuild for new gcc + +* Thu Sep 15 2005 Joe Orton 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 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 +- rebuild + +* Tue May 17 2005 Joe Orton 0.9.6-3 +- fix apr_procattr_child_*_set error handling + +* Tue Mar 1 2005 Joe Orton 0.9.6-2 +- have apr-devel depend on specific version of gcc +- add NOTICE to docdir + +* Wed Feb 9 2005 Joe Orton 0.9.6-1 +- update to 0.9.6 + +* Wed Feb 2 2005 Joe Orton 0.9.5-4 +- don't disable sendfile on s390 (IBM LTC, #146891) + +* Mon Nov 22 2004 Joe Orton 0.9.5-3 +- really fix apr-config --srcdir + +* Mon Nov 22 2004 Joe Orton 0.9.5-2 +- fix apr-config --srcdir again + +* Sun Nov 21 2004 Joe Orton 0.9.5-1 +- update to 0.9.5 + +* Mon Sep 27 2004 Joe Orton 0.9.4-24 +- rebuild + +* Wed Sep 1 2004 Joe Orton 0.9.4-23 +- have -devel require apr of same V-R + +* Tue Aug 31 2004 Joe Orton 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 0.9.4-21 +- rebuild for another attempt at using sem_open + +* Tue Jul 13 2004 Joe Orton 0.9.4-20 +- move sticky/suid bits outside APR_OS_DEFAULT bitmask (Greg Hudson) + +* Thu Jul 1 2004 Joe Orton 0.9.4-19 +- rebuild + +* Wed Jun 30 2004 Joe Orton 0.9.4-18 +- rebuild now /dev/shm is mounted + +* Thu Jun 17 2004 Joe Orton 0.9.4-17 +- add fix for cleanup structure reuse (part of upstream #23567) + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Thu Jun 10 2004 Joe Orton 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 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 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 0.9.4-12 +- use APR_LARGEFILE in apr_file_{copy,append} + +* Wed Mar 24 2004 Joe Orton 0.9.4-11 +- add APR_LARGEFILE flag + +* Mon Mar 15 2004 Joe Orton 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 0.9.4-9.1 +- rebuilt + +* Thu Feb 19 2004 Joe Orton 0.9.4-9 +- undocument apr_dir_read() ordering constraint and fix tests + +* Sun Feb 15 2004 Joe Orton 0.9.4-8 +- rebuilt without -Wall -Werror + +* Fri Feb 13 2004 Elliot Lee 0.9.4-7 +- rebuilt + +* Tue Feb 3 2004 Joe Orton 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 0.9.4-5 +- add apr_temp_dir_get fixes from HEAD + +* Thu Jan 8 2004 Joe Orton 0.9.4-4 +- ensure that libapr is linked against libpthread +- don't link libapr against -lnsl + +* Thu Nov 13 2003 Joe Orton 0.9.4-3 +- -devel package no longer requires libtool + +* Fri Oct 3 2003 Joe Orton 0.9.4-2 +- disable tests on x86_64 (#97611) + +* Fri Oct 3 2003 Joe Orton 0.9.4-1 +- update to 0.9.4, enable tests +- ensure that libresolv is not used + +* Sun Sep 7 2003 Joe Orton 0.9.3-14 +- use /dev/urandom (#103049) + +* Thu Jul 24 2003 Joe Orton 0.9.3-13 +- add back CC=gcc, CXX=g++ + +* Tue Jul 22 2003 Nalin Dahyabhai 0.9.3-12 +- rebuild + +* Mon Jul 14 2003 Joe Orton 0.9.3-11 +- work round useless autoconf 2.57 AC_DECL_SYS_SIGLIST + +* Thu Jul 10 2003 Joe Orton 0.9.3-10 +- support --cc and --cpp arguments in apr-config + +* Thu Jul 3 2003 Joe Orton 0.9.3-9 +- force libtool to use CC=gcc, CXX=g++ + +* Thu Jul 3 2003 Joe Orton 0.9.3-8 +- fix libtool location in apr_rules.mk + +* Mon Jun 30 2003 Joe Orton 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 0.9.3-6 +- don't use /usr/bin/libtool + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Tue May 20 2003 Joe Orton 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 0.9.3-4 +- link libapr against libpthread +- make apr-devel conflict with old subversion-devel +- fix License + +* Tue Apr 29 2003 Joe Orton 0.9.3-3 +- run ldconfig in post/postun + +* Tue Apr 29 2003 Joe Orton 0.9.3-2 +- patch test suite to not care if IPv6 is disabled + +* Mon Apr 28 2003 Joe Orton 0.9.3-1 +- initial build