diff --git a/Fix-pool-debugging-output-so-that-creation-events-ar.patch b/Fix-pool-debugging-output-so-that-creation-events-ar.patch deleted file mode 100644 index 04554e5..0000000 --- a/Fix-pool-debugging-output-so-that-creation-events-ar.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 6df2b8ec805230db90677b54afe2d122cf0bd8c8 Mon Sep 17 00:00:00 2001 -From: Rainer Jung -Date: Wed, 17 Jul 2019 11:43:58 +0000 -Subject: [PATCH 05/10] Fix pool debugging output so that creation events are - always emitted before allocation events and subpool destruction events are - emitted on pool clear/destroy for proper accounting. - -Backport of r1675967 from trunk resp. r1863202 from 1.7.x. - - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.6.x@1863211 13f79535-47bb-0310-9956-ffa450edef68 ---- - CHANGES | 4 ++++ - memory/unix/apr_pools.c | 27 +++++++++++++-------------- - 2 files changed, 17 insertions(+), 14 deletions(-) - -diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c -index 17fadb42a..9fdd00129 100644 ---- a/memory/unix/apr_pools.c -+++ b/memory/unix/apr_pools.c -@@ -1886,10 +1886,6 @@ APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool, - - apr_pool_check_lifetime(pool); - --#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) -- apr_pool_log_event(pool, "CLEAR", file_line, 1); --#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */ -- - #if APR_HAS_THREADS - if (pool->parent != NULL) - mutex = pool->parent->mutex; -@@ -1905,6 +1901,10 @@ APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool, - - pool_clear_debug(pool, file_line); - -+#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) -+ apr_pool_log_event(pool, "CLEAR", file_line, 1); -+#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */ -+ - #if APR_HAS_THREADS - /* If we had our own mutex, it will have been destroyed by - * the registered cleanups. Recreate the mutex. Unlock -@@ -1929,12 +1929,12 @@ static void pool_destroy_debug(apr_pool_t *pool, const char *file_line) - { - apr_pool_check_lifetime(pool); - -+ pool_clear_debug(pool, file_line); -+ - #if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) - apr_pool_log_event(pool, "DESTROY", file_line, 1); - #endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */ - -- pool_clear_debug(pool, file_line); -- - /* Remove the pool from the parents child list */ - if (pool->parent) { - #if APR_HAS_THREADS -@@ -2043,6 +2043,9 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, - pool->owner_proc = (apr_os_proc_t)getnlmhandle(); - #endif /* defined(NETWARE) */ - -+#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) -+ apr_pool_log_event(pool, "CREATE", file_line, 1); -+#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */ - - if (parent == NULL || parent->allocator != allocator) { - #if APR_HAS_THREADS -@@ -2072,10 +2075,6 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, - - *newpool = pool; - --#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) -- apr_pool_log_event(pool, "CREATE", file_line, 1); --#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */ -- - return APR_SUCCESS; - } - -@@ -2129,6 +2128,10 @@ APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex_debug(apr_pool_t **newpoo - } - pool->allocator = pool_allocator; - -+#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) -+ apr_pool_log_event(pool, "CREATEU", file_line, 1); -+#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */ -+ - if (pool->allocator != allocator) { - #if APR_HAS_THREADS - apr_status_t rv; -@@ -2151,10 +2154,6 @@ APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex_debug(apr_pool_t **newpoo - - *newpool = pool; - --#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) -- apr_pool_log_event(pool, "CREATEU", file_line, 1); --#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */ -- - return APR_SUCCESS; - } - --- -2.19.1 - diff --git a/Pool-debugging-fixes.patch b/Pool-debugging-fixes.patch deleted file mode 100644 index 2d77e8e..0000000 --- a/Pool-debugging-fixes.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 39611db20eea29a751162c43f0df61b05f48b00f Mon Sep 17 00:00:00 2001 -From: Rainer Jung -Date: Wed, 17 Jul 2019 11:42:15 +0000 -Subject: [PATCH 03/10] Pool debugging fixes - -- avoid using a destroyed mutex in apr_pool_clear() -- if we create a sub-pool, we don't need to own the pool. - -Backport of r1481186 from trunk resp. r1863200 from 1.7.x. - - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.6.x@1863209 13f79535-47bb-0310-9956-ffa450edef68 ---- - memory/unix/apr_pools.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c -index 614919ede..cd6b17811 100644 ---- a/memory/unix/apr_pools.c -+++ b/memory/unix/apr_pools.c -@@ -1909,6 +1909,11 @@ APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool, - * the mutex we obtained above. - */ - if (mutex != pool->mutex) { -+ /* -+ * Prevent apr_palloc() in apr_thread_mutex_create() from trying to -+ * use the destroyed mutex. -+ */ -+ pool->mutex = NULL; - (void)apr_thread_mutex_create(&pool->mutex, - APR_THREAD_MUTEX_NESTED, pool); - -@@ -1985,7 +1990,7 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, - parent = global_pool; - } - else { -- apr_pool_check_integrity(parent); -+ apr_pool_check_lifetime(parent); - - if (!allocator) - allocator = parent->allocator; --- -2.19.1 - diff --git a/Split-apr_pool_check_integrity-into-two-parts.patch b/Split-apr_pool_check_integrity-into-two-parts.patch deleted file mode 100644 index f1bdb7e..0000000 --- a/Split-apr_pool_check_integrity-into-two-parts.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 68710d39de65fa4f16c890110342a249f60a66fa Mon Sep 17 00:00:00 2001 -From: Rainer Jung -Date: Wed, 17 Jul 2019 11:41:21 +0000 -Subject: [PATCH 02/10] Split apr_pool_check_integrity() into two parts - -Run the pool owner check part only after pre-cleanups have been run, in -order to give them a chance to kill of any threads that may still be -accessing the pool. - -Backport of r1460184 from trunk resp. r1863199 from 1.7.x. - - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.6.x@1863208 13f79535-47bb-0310-9956-ffa450edef68 ---- - memory/unix/apr_pools.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c -index 3361f7a7d..614919ede 100644 ---- a/memory/unix/apr_pools.c -+++ b/memory/unix/apr_pools.c -@@ -1594,7 +1594,7 @@ static int apr_pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent) - } - #endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME) */ - --static void apr_pool_check_integrity(apr_pool_t *pool) -+static void apr_pool_check_lifetime(apr_pool_t *pool) - { - /* Rule of thumb: use of the global pool is always - * ok, since the only user is apr_pools.c. Unless -@@ -1618,7 +1618,10 @@ static void apr_pool_check_integrity(apr_pool_t *pool) - abort(); - } - #endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME) */ -+} - -+static void apr_pool_check_owner(apr_pool_t *pool) -+{ - #if (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) - #if APR_HAS_THREADS - if (!apr_os_thread_equal(pool->owner, apr_os_thread_current())) { -@@ -1632,6 +1635,11 @@ static void apr_pool_check_integrity(apr_pool_t *pool) - #endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) */ - } - -+static void apr_pool_check_integrity(apr_pool_t *pool) -+{ -+ apr_pool_check_lifetime(pool); -+ apr_pool_check_owner(pool); -+} - - /* - * Initialization (debug) -@@ -1820,6 +1828,12 @@ static void pool_clear_debug(apr_pool_t *pool, const char *file_line) - run_cleanups(&pool->pre_cleanups); - pool->pre_cleanups = NULL; - -+ /* -+ * Now that we have given the pre cleanups the chance to kill of any -+ * threads using the pool, the owner must be correct. -+ */ -+ apr_pool_check_owner(pool); -+ - /* Destroy the subpools. The subpools will detach themselves from - * this pool thus this loop is safe and easy. - */ -@@ -1868,7 +1882,7 @@ APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool, - apr_thread_mutex_t *mutex = NULL; - #endif - -- apr_pool_check_integrity(pool); -+ apr_pool_check_lifetime(pool); - - #if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) - apr_pool_log_event(pool, "CLEAR", file_line, 1); -@@ -1906,7 +1920,7 @@ APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool, - - static void pool_destroy_debug(apr_pool_t *pool, const char *file_line) - { -- apr_pool_check_integrity(pool); -+ apr_pool_check_lifetime(pool); - - #if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) - apr_pool_log_event(pool, "DESTROY", file_line, 1); --- -2.19.1 - diff --git a/apr-1.2.2-libdir.patch b/apr-1.2.2-libdir.patch index aeb7ee1..3570989 100644 --- a/apr-1.2.2-libdir.patch +++ b/apr-1.2.2-libdir.patch @@ -1,9 +1,10 @@ - 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 @@ + +--- a/apr-config.in ++++ b/apr-config.in +@@ -213,8 +213,10 @@ while test $# -gt 0; do ;; --link-ld) if test "$location" = "installed"; then @@ -13,6 +14,11 @@ + flags="$flags -L$libdir" + fi + flags="$flags -l${APR_LIBNAME}" + elif test "$location" = "crosscompile"; then + flags="$flags -L$APR_TARGET_DIR/$libdir -l${APR_LIBNAME}" else - ### this surely can't work since the library is in .libs? - flags="$flags -L$APR_BUILD_DIR -l${APR_LIBNAME}" +-- + apr-config.in | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + + diff --git a/apr-1.7.0.tar.bz2 b/apr-1.7.0.tar.bz2 deleted file mode 100644 index e5fecb2..0000000 Binary files a/apr-1.7.0.tar.bz2 and /dev/null differ diff --git a/apr-1.7.4.tar.gz b/apr-1.7.4.tar.gz new file mode 100644 index 0000000..8d2e21d Binary files /dev/null and b/apr-1.7.4.tar.gz differ diff --git a/apr.spec b/apr.spec index 3cff353..7ff04d8 100644 --- a/apr.spec +++ b/apr.spec @@ -1,8 +1,8 @@ %define aprver 1 Name: apr -Version: 1.7.0 -Release: 5 +Version: 1.7.4 +Release: 1 Summary: Apache Portable Runtime. License: ASL 2.0 and BSD with advertising and ISC and BSD URL: http://apr.apache.org @@ -11,15 +11,6 @@ Source1: apr-wrapper.h Patch0: apr-1.2.2-libdir.patch Patch1: apr-1.2.7-pkgconf.patch -Patch2: Split-apr_pool_check_integrity-into-two-parts.patch -Patch3: Pool-debugging-fixes.patch -Patch4: Fix-pool-debugging-output-so-that-creation-events-ar.patch -Patch5: backport-CVE-2017-12613-Bounds-check-human-readable-date-fields.patch -Patch6: backport-build-apr_common.me-avoid-explicit-inclusion-if-conf.patch -Patch7: backport-Address-some-warnings-raised-by-MSVC-32-64.patch -Patch8: backport-apr_encode_base32-fix-advertised-output-len-when-cal.patch -Patch9: backport-apr_decode_base-64-32-16-stop-reading-before-not-inc.patch -Patch10:backport-CVE-2022-24963-encoding-Better-check-inputs-of-apr_-encode-decode-_.patch BuildRequires: gcc autoconf libtool libuuid-devel python3 lksctp-tools-devel @@ -103,6 +94,9 @@ make check %doc docs/incomplete_types docs/non_apr_programs %changelog +* Sat Feb 3 2024 caixiaomeng - 1.7.4-1 +Update to 1.7.4 + * Mon Feb 13 2023 fuanan - 1.7.0-5 - Type:CVE - ID:CVE-2022-24963 diff --git a/backport-Address-some-warnings-raised-by-MSVC-32-64.patch b/backport-Address-some-warnings-raised-by-MSVC-32-64.patch deleted file mode 100644 index c58ea43..0000000 --- a/backport-Address-some-warnings-raised-by-MSVC-32-64.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 66e41846004d40fd6d12811fd0acf08920a3d1cd Mon Sep 17 00:00:00 2001 -From: Yann Ylavic -Date: Wed, 3 Apr 2019 13:54:46 +0000 -Subject: [PATCH] Address some warnings raised by MSVC-32/64. - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1856873 13f79535-47bb-0310-9956-ffa450edef68 ---- - atomic/win32/apr_atomic64.c | 50 ++++++++----------------------------- - encoding/apr_encode.c | 4 +-- - file_io/win32/seek.c | 2 +- - memory/unix/apr_pools.c | 8 +++--- - 4 files changed, 18 insertions(+), 46 deletions(-) - -diff --git a/atomic/win32/apr_atomic64.c b/atomic/win32/apr_atomic64.c -index a5acc945e..e2cd06d6c 100644 ---- a/atomic/win32/apr_atomic64.c -+++ b/atomic/win32/apr_atomic64.c -@@ -18,55 +18,35 @@ - #include "apr_atomic.h" - #include "apr_thread_mutex.h" - --APR_DECLARE(apr_uint64_t) apr_atomic_add64(volatile apr_uint64_t *mem, apr_uint64_t val) --{ --#if (defined(_M_IA64) || defined(_M_AMD64)) -- return InterlockedExchangeAdd64(mem, val); --#else -- return InterlockedExchangeAdd64((long *)mem, val); --#endif --} -- - /* Of course we want the 2's compliment of the unsigned value, val */ - #ifdef _MSC_VER - #pragma warning(disable: 4146) - #endif - -+APR_DECLARE(apr_uint64_t) apr_atomic_add64(volatile apr_uint64_t *mem, apr_uint64_t val) -+{ -+ return InterlockedExchangeAdd64((volatile LONG64 *)mem, val); -+} -+ - APR_DECLARE(void) apr_atomic_sub64(volatile apr_uint64_t *mem, apr_uint64_t val) - { --#if (defined(_M_IA64) || defined(_M_AMD64)) -- InterlockedExchangeAdd64(mem, -val); --#else -- InterlockedExchangeAdd64((long *)mem, -val); --#endif -+ InterlockedExchangeAdd64((volatile LONG64 *)mem, -val); - } - - APR_DECLARE(apr_uint64_t) apr_atomic_inc64(volatile apr_uint64_t *mem) - { - /* we return old value, win64 returns new value :( */ --#if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) -- return InterlockedIncrement64(mem) - 1; --#else -- return InterlockedIncrement64((long *)mem) - 1; --#endif -+ return InterlockedIncrement64((volatile LONG64 *)mem) - 1; - } - - APR_DECLARE(int) apr_atomic_dec64(volatile apr_uint64_t *mem) - { --#if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) -- return InterlockedDecrement64(mem); --#else -- return InterlockedDecrement64((long *)mem); --#endif -+ return !!InterlockedDecrement64((volatile LONG64 *)mem); - } - - APR_DECLARE(void) apr_atomic_set64(volatile apr_uint64_t *mem, apr_uint64_t val) - { --#if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) -- InterlockedExchange64(mem, val); --#else -- InterlockedExchange64((long*)mem, val); --#endif -+ InterlockedExchange64((volatile LONG64 *)mem, val); - } - - APR_DECLARE(apr_uint64_t) apr_atomic_read64(volatile apr_uint64_t *mem) -@@ -77,18 +57,10 @@ APR_DECLARE(apr_uint64_t) apr_atomic_read64(volatile apr_uint64_t *mem) - APR_DECLARE(apr_uint64_t) apr_atomic_cas64(volatile apr_uint64_t *mem, apr_uint64_t with, - apr_uint64_t cmp) - { --#if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) -- return InterlockedCompareExchange64(mem, with, cmp); --#else -- return InterlockedCompareExchange64((long*)mem, with, cmp); --#endif -+ return InterlockedCompareExchange64((volatile LONG64 *)mem, with, cmp); - } - - APR_DECLARE(apr_uint64_t) apr_atomic_xchg64(volatile apr_uint64_t *mem, apr_uint64_t val) - { --#if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) -- return InterlockedExchange64(mem, val); --#else -- return InterlockedExchange64((long *)mem, val); --#endif -+ return InterlockedExchange64((volatile LONG64 *)mem, val); - } -diff --git a/encoding/apr_encode.c b/encoding/apr_encode.c -index 905185921..e44ae11f0 100644 ---- a/encoding/apr_encode.c -+++ b/encoding/apr_encode.c -@@ -1062,7 +1062,7 @@ 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_ssize_t size; - - if (!src) { - return APR_NOTFOUND; -@@ -1115,7 +1115,7 @@ 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_ssize_t size; - - if (!src) { - return APR_NOTFOUND; -diff --git a/file_io/win32/seek.c b/file_io/win32/seek.c -index afe6edb00..dfef57716 100644 ---- a/file_io/win32/seek.c -+++ b/file_io/win32/seek.c -@@ -170,7 +170,7 @@ APR_DECLARE(apr_status_t) apr_file_trunc(apr_file_t *thefile, apr_off_t offset) - thefile->bufpos = 0; - } - else if (offset < thefile->filePtr + (apr_off_t)thefile->bufpos) { -- thefile->bufpos = offset - thefile->filePtr; -+ thefile->bufpos = (apr_size_t)(offset - thefile->filePtr); - } - - if (thefile->bufpos != 0) { -diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c -index 5fa7da1b5..0ca715efa 100644 ---- a/memory/unix/apr_pools.c -+++ b/memory/unix/apr_pools.c -@@ -407,7 +407,7 @@ apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t in_size) - return NULL; - } - #endif -- node->index = index; -+ node->index = (apr_uint32_t)index; - node->endp = (char *)node + size; - - have_node: -@@ -877,7 +877,7 @@ APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t in_size) - free_index = (APR_ALIGN(active->endp - active->first_avail + 1, - BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX; - -- active->free_index = free_index; -+ active->free_index = (apr_uint32_t)free_index; - node = active->next; - if (free_index >= node->free_index) - goto have_mem; -@@ -1289,7 +1289,7 @@ static int psprintf_flush(apr_vformatter_buff_t *vbuff) - free_index = (APR_ALIGN(active->endp - active->first_avail + 1, - BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX; - -- active->free_index = free_index; -+ active->free_index = (apr_uint32_t)free_index; - node = active->next; - if (free_index < node->free_index) { - do { -@@ -1445,7 +1445,7 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap) - free_index = (APR_ALIGN(active->endp - active->first_avail + 1, - BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX; - -- active->free_index = free_index; -+ active->free_index = (apr_uint32_t)free_index; - node = active->next; - - if (free_index >= node->free_index) { --- -2.27.0 - diff --git a/backport-CVE-2017-12613-Bounds-check-human-readable-date-fields.patch b/backport-CVE-2017-12613-Bounds-check-human-readable-date-fields.patch deleted file mode 100644 index 374c0a9..0000000 --- a/backport-CVE-2017-12613-Bounds-check-human-readable-date-fields.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ad958385a4180d7a83d90589689fcd36e3bbc57a Mon Sep 17 00:00:00 2001 -From: Nick Kew -Date: Sun, 10 Sep 2017 22:30:14 +0000 -Subject: [PATCH] Bounds-check human-readable date fields (credit: Stefan - Sperling) - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1807975 13f79535-47bb-0310-9956-ffa450edef68 ---- - time/unix/time.c | 3 +++ - time/win32/time.c | 6 ++++++ - 2 files changed, 9 insertions(+) - -diff --git a/time/unix/time.c b/time/unix/time.c -index dfa45e690c..7f09581927 100644 ---- a/time/unix/time.c -+++ b/time/unix/time.c -@@ -142,6 +142,9 @@ APR_DECLARE(apr_status_t) apr_time_exp_get(apr_time_t *t, apr_time_exp_t *xt) - 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) -diff --git a/time/win32/time.c b/time/win32/time.c -index 2349799356..1a705443b2 100644 ---- a/time/win32/time.c -+++ b/time/win32/time.c -@@ -54,6 +54,9 @@ static void SystemTimeToAprExpTime(apr_time_exp_t *xt, SYSTEMTIME *tm) - 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. - */ -@@ -224,6 +227,9 @@ APR_DECLARE(apr_status_t) apr_time_exp_get(apr_time_t *t, - 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) diff --git a/backport-CVE-2022-24963-encoding-Better-check-inputs-of-apr_-encode-decode-_.patch b/backport-CVE-2022-24963-encoding-Better-check-inputs-of-apr_-encode-decode-_.patch deleted file mode 100644 index 3f46113..0000000 --- a/backport-CVE-2022-24963-encoding-Better-check-inputs-of-apr_-encode-decode-_.patch +++ /dev/null @@ -1,2870 +0,0 @@ -From 622905ddfa7b45dfca350e13442892de3c1f48e9 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic -Date: Mon, 27 Jun 2022 15:26:09 +0000 -Subject: [PATCH] encoding: Better check inputs of apr_{encode,decode}_* - functions. - -Check that the given sources can be encoded without overflowing. - -Return APR_EINVAL if the given "slen" is negative, APR_NOTFOUND if "dest" is -not NULL and "src" is NULL, or APR_ENOSPC if "dest" is NULL and the source -length (based on "slen" or APR_ENCODE_STRING) is too big to encode. - -* include/private/apr_encode_private.h(): - Rename ENCODE_TO_ASCII() and ENCODE_TO_NATIVE() to respectively TO_ASCII() - and TO_ENCODE(), and make them return an unsigned char. - -* encoding/apr_escape.c(): - Use the new TO_ASCII() and TO_NATIVE(). - -* encoding/apr_encode.c(apr_encode_*, apr_decode_*): - Forbid negative "slen" but APR_ENCODE_STRING, and use apr_size_t arithmetics - to check for overflows when encoding. - When "dest" is NULL, "src" can be NULL too. - Better check for trailing '='s or base16's APR_ENCODE_COLON ':' separators. - Rename ENCODE_TO_ASCII and ENCODE_TO_NATIVE to their new names, and remove - casts to (unsigned char) now unnecessary. - -* include/apr_encode.h(): - Update dox about acceptable inputs and returned errors. - -* test/testencode.c(): - Tests for error conditions. - - - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902281 13f79535-47bb-0310-9956-ffa450edef68 ---- - encoding/apr_encode.c | 1398 ++++++++++++++------------ - encoding/apr_escape.c | 6 +- - include/apr_encode.h | 407 +++++--- - include/private/apr_encode_private.h | 21 +- - test/testencode.c | 158 +++ - 5 files changed, 1184 insertions(+), 806 deletions(-) - -diff --git a/encoding/apr_encode.c b/encoding/apr_encode.c -index bc2dc5437..c18f44285 100644 ---- a/encoding/apr_encode.c -+++ b/encoding/apr_encode.c -@@ -211,19 +211,20 @@ static const char base16lower[] = "0123456789abcdef"; - 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 @@ APR_DECLARE(apr_status_t) apr_encode_base64(char *dest, const char *src, - 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 (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 < slen) { -- *bufout++ = base[ENCODE_TO_ASCII(((src[i]) >> 2) & 0x3F)]; -- if (i == (slen - 1)) { -- *bufout++ = base[ENCODE_TO_ASCII((((src[i]) & 0x3) << 4))]; -+ 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 @@ APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned ch - 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_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src, - { - 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_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigne - { - 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,157 +396,184 @@ APR_DECLARE(const char *)apr_pencode_base64_binary(apr_pool_t * p, const unsigne - 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 (count && pr2six[*bufin] < 64) { -- count--; -- bufin++; -- } -- nprbytes = bufin - (const unsigned char *)src; -- while (count && pr2six[*bufin] > 64) { -+ 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 (count && pr2six[*bufin] < 64) { -- count--; -- bufin++; -- } -- nprbytes = bufin - (const unsigned char *)src; -- while (count && pr2six[*bufin] > 64) { -+ 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, -@@ -535,14 +581,19 @@ APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *str, - { - 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; - } - } -@@ -555,15 +606,20 @@ APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p, - { - 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; - } - } -@@ -574,19 +630,20 @@ APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p, - 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; -@@ -595,24 +652,26 @@ APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src, - 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++ = '='; -@@ -622,11 +681,11 @@ APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src, - *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++ = '='; -@@ -634,13 +693,13 @@ APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src, - *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++ = '='; -@@ -648,49 +707,51 @@ APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src, - } - } - 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 + 4) / 5 * 8) + 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; -@@ -699,23 +760,25 @@ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned ch - 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 (i < slen) { -+ 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 < 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++ = '='; -@@ -726,9 +789,9 @@ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned ch - *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)) { -@@ -738,12 +801,12 @@ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned ch - *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++ = '='; -@@ -752,13 +815,13 @@ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned ch - } - } - 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)) { -@@ -767,20 +830,20 @@ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned ch - } - } - -- 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, -@@ -788,13 +851,19 @@ APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src, - { - 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; - } - } -@@ -807,13 +876,19 @@ APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigne - { - 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; - } - } -@@ -824,24 +899,20 @@ APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigne - 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; - } -@@ -850,105 +921,130 @@ APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src, - } - - bufin = (const unsigned char *)src; -- while (count && pr2[*bufin] < 32) { -- count--; -- bufin++; -- } -- nprbytes = bufin - (const unsigned char *)src; -- while (count && pr2[*bufin] > 32) { -+ 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; -+ -+ if (dest) { -+ unsigned char *bufout; -+ -+ bufout = (unsigned char *)dest; -+ bufin = (const unsigned char *)src; -+ -+ 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; -+ } - -- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : -- count ? APR_BADCH : APR_SUCCESS; -- -- 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; -- } -+ 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 (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]]); -+ dlen = bufout - (unsigned char *)dest; -+ dest[dlen] = '\0'; - } -+ } - -- if (len) { -- *len = bufout - (unsigned char *)dest; -+ 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; - } -- -- *(bufout++) = 0; -- -- return status; - } - - 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; - } -@@ -957,80 +1053,110 @@ APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest, - } - - bufin = (const unsigned char *)src; -- while (count && pr2[*bufin] < 32) { -- count--; -- bufin++; -- } -- nprbytes = bufin - (const unsigned char *)src; -- while (count && pr2[*bufin] > 32) { -+ 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; -+ -+ if (dest) { -+ unsigned char *bufout; -+ -+ bufout = (unsigned char *)dest; -+ bufin = (const unsigned char *)src; -+ -+ 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; -+ } - -- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : -- count ? APR_BADCH : APR_SUCCESS; -- -- 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; -- } -+ 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 (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]]); -+ dlen = bufout - dest; - } -+ } - -- if (len) { -- *len = bufout - dest; -+ 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; - } -- -- return status; - } - - 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, -@@ -1038,14 +1164,19 @@ APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *str, - { - 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; - } - } -@@ -1058,15 +1189,20 @@ APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p, - { - 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; - } - } -@@ -1077,16 +1213,20 @@ APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p, - 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_ssize_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; -@@ -1095,51 +1235,51 @@ APR_DECLARE(apr_status_t) apr_encode_base16(char *dest, - 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_ssize_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; -@@ -1148,33 +1288,35 @@ APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest, - 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, -@@ -1182,13 +1324,19 @@ APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p, - { - 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; - } - } -@@ -1202,13 +1350,19 @@ APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p, - { - 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; - } - } -@@ -1219,186 +1373,156 @@ APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p, - 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; -- -- 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); - } -- -- count = slen; -- bufin = (const unsigned char *)src; -- while (count && pr2two[*bufin] != 16) { -- count--; -- bufin++; -- } -- nprbytes = bufin - (const unsigned char *)src; -- while (count && pr2two[*bufin] > 16) { -- count--; -- bufin++; -+ else if (slen < 0 || (dest && !src)) { -+ return (src) ? APR_EINVAL : APR_NOTFOUND; - } - -- status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : -- count ? APR_BADCH : APR_SUCCESS; -+ if (src) { -+ const unsigned char *bufin; - -- 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)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; -- } -+ if (dest) { -+ unsigned char *bufout; - -- *(bufout++) = 0; -+ bufout = (unsigned char *)dest; -+ bufin = (const unsigned char *)src; - -- return status; -- } -- -- 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 (count && pr2two[*bufin] != 16) { -- count--; -- bufin++; -- } -- nprbytes = bufin - (const unsigned char *)src; -- while (count && pr2two[*bufin] > 16) { -- count--; -- bufin++; -- } -+ 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; -- } -- -- else { -+ if (dest) { -+ unsigned char *bufout; - -- count = 0; -- bufin = (const unsigned char *)src; -+ bufout = (unsigned char *)dest; -+ 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, -@@ -1406,14 +1530,19 @@ APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p, - { - 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; - } - } -@@ -1426,15 +1555,20 @@ APR_DECLARE(const unsigned char *)apr_pdecode_base16_binary(apr_pool_t * p, - { - 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; - } - } -diff --git a/encoding/apr_escape.c b/encoding/apr_escape.c -index b3bc82d35..6074d739e 100644 ---- a/encoding/apr_escape.c -+++ b/encoding/apr_escape.c -@@ -131,7 +131,7 @@ static char x2c(const char *what) - 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 @@ APR_DECLARE(apr_status_t) apr_unescape_entity(char *unescaped, const char *str, - size--; - } - else { -- *d = ENCODE_TO_ASCII(val); -+ *d = TO_ASCII(val); - found = 1; - } - } -@@ -737,7 +737,7 @@ APR_DECLARE(apr_status_t) apr_unescape_entity(char *unescaped, const char *str, - *d = '&'; /* unknown */ - } - else { -- *d = ENCODE_TO_ASCII(((const unsigned char *) ents)[j]); -+ *d = TO_ASCII(ents[j]); - s += i; - slen -= i; - found = 1; -diff --git a/include/apr_encode.h b/include/apr_encode.h -index 20fc932f6..8bae61f7b 100644 ---- a/include/apr_encode.h -+++ b/include/apr_encode.h -@@ -146,35 +146,44 @@ extern "C" { - - /** - * 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 @@ APR_DECLARE(apr_status_t) apr_encode_base64_binary(char *dest, const unsigned ch - * @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 @@ APR_DECLARE(const char *)apr_pencode_base64(apr_pool_t * p, const char *src, - * @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 @@ APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest, - * 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 @@ APR_DECLARE(const char *)apr_pdecode_base64(apr_pool_t * p, const char *src, - * 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 @@ APR_DECLARE(const unsigned char *)apr_pdecode_base64_binary(apr_pool_t * p, - - /** - * 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 @@ APR_DECLARE(apr_status_t) apr_encode_base32_binary(char *dest, const unsigned ch - * @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 @@ APR_DECLARE(const char *)apr_pencode_base32(apr_pool_t * p, const char *src, - * @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 @@ APR_DECLARE(const char *)apr_pencode_base32_binary(apr_pool_t * p, const unsigne - - /** - * 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 @@ APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest, - * 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 @@ APR_DECLARE(const char *)apr_pdecode_base32(apr_pool_t * p, const char *src, - * 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 @@ APR_DECLARE(const unsigned char *)apr_pdecode_base32_binary(apr_pool_t * p, - - /** - * 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 @@ APR_DECLARE(apr_status_t) apr_encode_base16_binary(char *dest, - * @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 @@ APR_DECLARE(const char *)apr_pencode_base16(apr_pool_t * p, const char *src, - * @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 @@ APR_DECLARE(const char *)apr_pencode_base16_binary(apr_pool_t * p, - - /** - * 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 @@ APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest, - /** - * 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 @@ APR_DECLARE(const char *)apr_pdecode_base16(apr_pool_t * p, const char *src, - /** - * 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) -diff --git a/include/private/apr_encode_private.h b/include/private/apr_encode_private.h -index 8db2e0166..93ce0a02d 100644 ---- a/include/private/apr_encode_private.h -+++ b/include/private/apr_encode_private.h -@@ -34,7 +34,8 @@ extern "C" { - */ - - #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 @@ extern "C" { - 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 @@ extern "C" { - 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 -diff --git a/test/testencode.c b/test/testencode.c -index b5e11566e..28d5b07f5 100644 ---- a/test/testencode.c -+++ b/test/testencode.c -@@ -905,6 +905,162 @@ static void test_decode_base16_binary(abts_case * tc, void *data) - apr_pool_destroy(pool); - } - -+typedef apr_status_t (*encdec_fn)(char*, const char*, apr_ssize_t, int, apr_size_t*); -+ -+static void test_encode_errors(abts_case * tc, void *data) -+{ -+ char dest[1]; -+ apr_size_t len; -+ apr_status_t rv; -+ -+ const encdec_fn *enc, encs[] = { -+ (encdec_fn)apr_encode_base64, -+ (encdec_fn)apr_encode_base64_binary, -+ (encdec_fn)apr_encode_base32, -+ (encdec_fn)apr_encode_base32_binary, -+ (encdec_fn)apr_encode_base16, -+ (encdec_fn)apr_encode_base16_binary, -+ NULL -+ }; -+ for (enc = encs; *enc; ++enc) { -+ rv = (*enc)(dest, "", -2, 0, &len); -+ ABTS_INT_EQUAL(tc, APR_EINVAL, rv); -+ -+ rv = (*enc)(dest, NULL, APR_ENCODE_STRING, 0, &len); -+ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv); -+ -+#if 0 -+ /* 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 :) -+ */ -+ { -+ static char huge_buffer[APR_SIZE_MAX / 4 * 3 + 1]; -+ memset(huge_buffer, !0, sizeof(huge_buffer) - 1); -+ rv = (*enc)(NULL, huge_buffer, APR_ENCODE_STRING, &len); -+ ABTS_INT_EQUAL(tc, APR_ENOSPC, rv); -+ } -+#endif -+ } -+} -+ -+static void test_decode_errors(abts_case * tc, void *data) -+{ -+ char dest[64]; -+ unsigned char *udest = (unsigned char *)dest; -+ apr_size_t len; -+ apr_status_t rv; -+ -+ const encdec_fn *dec, decs[] = { -+ (encdec_fn)apr_decode_base64, -+ (encdec_fn)apr_decode_base64_binary, -+ (encdec_fn)apr_decode_base32, -+ (encdec_fn)apr_decode_base32_binary, -+ (encdec_fn)apr_decode_base16, -+ (encdec_fn)apr_decode_base16_binary, -+ NULL -+ }; -+ for (dec = decs; *dec; ++dec) { -+ rv = (*dec)(dest, "", -2, 0, &len); -+ ABTS_INT_EQUAL(tc, APR_EINVAL, rv); -+ -+ rv = (*dec)(dest, NULL, APR_ENCODE_STRING, 0, &len); -+ ABTS_INT_EQUAL(tc, APR_NOTFOUND, rv); -+ -+ /* No possible APR_ENOSPC when decoding */ -+ } -+ -+ /* base64 */ -+ 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(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(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(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(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); -+} -+ - abts_suite *testencode(abts_suite * suite) - { - suite = ADD_SUITE(suite); -@@ -921,6 +1077,8 @@ abts_suite *testencode(abts_suite * suite) - 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; - } --- -2.27.0 - diff --git a/backport-apr_decode_base-64-32-16-stop-reading-before-not-inc.patch b/backport-apr_decode_base-64-32-16-stop-reading-before-not-inc.patch deleted file mode 100644 index 202c46d..0000000 --- a/backport-apr_decode_base-64-32-16-stop-reading-before-not-inc.patch +++ /dev/null @@ -1,199 +0,0 @@ -From e70d77ecc4aa9e0dccac6e7e5ba74639f71f50cf Mon Sep 17 00:00:00 2001 -From: Yann Ylavic -Date: Fri, 27 Nov 2020 17:04:06 +0000 -Subject: [PATCH] apr_decode_base{64,32,16}: stop reading before (not - including) NUL byte. - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1883870 13f79535-47bb-0310-9956-ffa450edef68 ---- - encoding/apr_encode.c | 60 ++++++++++++++++++++++++++++++------------- - test/testencode.c | 24 ++++++++++++----- - 2 files changed, 59 insertions(+), 25 deletions(-) - -diff --git a/encoding/apr_encode.c b/encoding/apr_encode.c -index b3278c7fd..bc2dc5437 100644 ---- a/encoding/apr_encode.c -+++ b/encoding/apr_encode.c -@@ -394,11 +394,15 @@ APR_DECLARE(apr_status_t) apr_decode_base64(char *dest, const char *src, - apr_status_t status; - - bufin = (const unsigned char *)src; -- while (pr2six[*(bufin++)] < 64 && count) -+ while (count && pr2six[*bufin] < 64) { - count--; -- nprbytes = (bufin - (const unsigned char *)src) - 1; -- while (pr2six[*(bufin++)] > 64 && count) -+ bufin++; -+ } -+ nprbytes = bufin - (const unsigned char *)src; -+ while (count && pr2six[*bufin] > 64) { - count--; -+ bufin++; -+ } - - status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : - count ? APR_BADCH : APR_SUCCESS; -@@ -469,11 +473,15 @@ APR_DECLARE(apr_status_t) apr_decode_base64_binary(unsigned char *dest, - apr_status_t status; - - bufin = (const unsigned char *)src; -- while (pr2six[*(bufin++)] < 64 && count) -+ while (count && pr2six[*bufin] < 64) { - count--; -- nprbytes = (bufin - (const unsigned char *)src) - 1; -- while (pr2six[*(bufin++)] > 64 && count) -+ bufin++; -+ } -+ nprbytes = bufin - (const unsigned char *)src; -+ while (count && pr2six[*bufin] > 64) { - count--; -+ bufin++; -+ } - - status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : - count ? APR_BADCH : APR_SUCCESS; -@@ -842,11 +850,15 @@ APR_DECLARE(apr_status_t) apr_decode_base32(char *dest, const char *src, - } - - bufin = (const unsigned char *)src; -- while (pr2[*(bufin++)] < 32 && count) -+ while (count && pr2[*bufin] < 32) { - count--; -- nprbytes = (bufin - (const unsigned char *)src) - 1; -- while (pr2[*(bufin++)] > 32 && count) -+ bufin++; -+ } -+ nprbytes = bufin - (const unsigned char *)src; -+ while (count && pr2[*bufin] > 32) { - count--; -+ bufin++; -+ } - - status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : - count ? APR_BADCH : APR_SUCCESS; -@@ -945,11 +957,15 @@ APR_DECLARE(apr_status_t) apr_decode_base32_binary(unsigned char *dest, - } - - bufin = (const unsigned char *)src; -- while (pr2[*(bufin++)] < 32 && count) -+ while (count && pr2[*bufin] < 32) { - count--; -- nprbytes = (bufin - (const unsigned char *)src) - 1; -- while (pr2[*(bufin++)] > 32 && count) -+ bufin++; -+ } -+ nprbytes = bufin - (const unsigned char *)src; -+ while (count && pr2[*bufin] > 32) { - count--; -+ bufin++; -+ } - - status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : - count ? APR_BADCH : APR_SUCCESS; -@@ -1220,11 +1236,15 @@ APR_DECLARE(apr_status_t) apr_decode_base16(char *dest, - - count = slen; - bufin = (const unsigned char *)src; -- while (pr2two[*(bufin++)] != 16 && count) -+ while (count && pr2two[*bufin] != 16) { - count--; -- nprbytes = (bufin - (const unsigned char *)src) - 1; -- while (pr2two[*(bufin++)] > 16 && count) -+ bufin++; -+ } -+ nprbytes = bufin - (const unsigned char *)src; -+ while (count && pr2two[*bufin] > 16) { - count--; -+ bufin++; -+ } - - status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : - count ? APR_BADCH : APR_SUCCESS; -@@ -1310,11 +1330,15 @@ APR_DECLARE(apr_status_t) apr_decode_base16_binary(unsigned char *dest, - - count = slen; - bufin = (const unsigned char *)src; -- while (pr2two[*(bufin++)] != 16 && count) -+ while (count && pr2two[*bufin] != 16) { - count--; -- nprbytes = (bufin - (const unsigned char *)src) - 1; -- while (pr2two[*(bufin++)] > 16 && count) -+ bufin++; -+ } -+ nprbytes = bufin - (const unsigned char *)src; -+ while (count && pr2two[*bufin] > 16) { - count--; -+ bufin++; -+ } - - status = flags & APR_ENCODE_RELAXED ? APR_SUCCESS : - count ? APR_BADCH : APR_SUCCESS; -diff --git a/test/testencode.c b/test/testencode.c -index 3680fa380..ba23aaf28 100644 ---- a/test/testencode.c -+++ b/test/testencode.c -@@ -134,37 +134,42 @@ static void test_decode_base64(abts_case * tc, void *data) - src = ""; - target = ""; - dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -- ABTS_STR_EQUAL(tc, dest, target); -+ ABTS_STR_EQUAL(tc, target, dest); - - src = "Zg=="; - target = "f"; - dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -- ABTS_STR_EQUAL(tc, dest, target); -+ ABTS_STR_EQUAL(tc, target, dest); -+ -+ src = "Zg="; -+ target = "f"; -+ dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -+ ABTS_STR_EQUAL(tc, target, dest); - - src = "Zg"; - target = "f"; - dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -- ABTS_STR_EQUAL(tc, dest, target); -+ ABTS_STR_EQUAL(tc, target, dest); - - src = "Zm8="; - target = "fo"; - dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -- ABTS_STR_EQUAL(tc, dest, target); -+ ABTS_STR_EQUAL(tc, target, dest); - - src = "Zm8"; - target = "fo"; - dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -- ABTS_STR_EQUAL(tc, dest, target); -+ ABTS_STR_EQUAL(tc, target, dest); - - src = "Zm9v"; - target = "foo"; - dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -- ABTS_STR_EQUAL(tc, dest, target); -+ ABTS_STR_EQUAL(tc, target, dest); - - src = "Zm9v"; - target = "foo"; - dest = apr_pdecode_base64(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -- ABTS_STR_EQUAL(tc, dest, target); -+ ABTS_STR_EQUAL(tc, target, dest); - - apr_pool_destroy(pool); - } -@@ -191,6 +196,11 @@ static void test_decode_base64_binary(abts_case * tc, void *data) - ABTS_ASSERT(tc, "apr_pdecode_base64_binary target!=dest", memcmp(ufoobar, udest, 1) == 0); - ABTS_INT_EQUAL(tc, len, 1); - -+ src = "Zg="; -+ udest = apr_pdecode_base64_binary(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); -+ ABTS_ASSERT(tc, "apr_pdecode_base64_binary target!=dest", memcmp(ufoobar, udest, 1) == 0); -+ ABTS_INT_EQUAL(tc, len, 1); -+ - src = "Zg"; - udest = apr_pdecode_base64_binary(pool, src, APR_ENCODE_STRING, APR_ENCODE_NONE, &len); - ABTS_ASSERT(tc, "apr_pdecode_base64_binary target!=dest", memcmp(ufoobar, udest, 1) == 0); --- -2.27.0 - diff --git a/backport-apr_encode_base32-fix-advertised-output-len-when-cal.patch b/backport-apr_encode_base32-fix-advertised-output-len-when-cal.patch deleted file mode 100644 index 46a1667..0000000 --- a/backport-apr_encode_base32-fix-advertised-output-len-when-cal.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 2b0eb50e43667ce8cebf0bb745a0eb7d493385c2 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic -Date: Fri, 27 Nov 2020 16:54:50 +0000 -Subject: [PATCH] apr_encode_base32: fix advertised output *len when called - with dst == NULL. - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1883868 13f79535-47bb-0310-9956-ffa450edef68 ---- - encoding/apr_encode.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/encoding/apr_encode.c b/encoding/apr_encode.c -index e44ae11f0..b3278c7fd 100644 ---- a/encoding/apr_encode.c -+++ b/encoding/apr_encode.c -@@ -665,7 +665,7 @@ APR_DECLARE(apr_status_t) apr_encode_base32(char *dest, const char *src, - } - - if (len) { -- *len = ((slen + 2) / 3 * 4) + 1; -+ *len = ((slen + 4) / 5 * 8) + 1; - } - - return APR_SUCCESS; --- -2.27.0 - diff --git a/backport-build-apr_common.me-avoid-explicit-inclusion-if-conf.patch b/backport-build-apr_common.me-avoid-explicit-inclusion-if-conf.patch deleted file mode 100644 index baadd6b..0000000 --- a/backport-build-apr_common.me-avoid-explicit-inclusion-if-conf.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0a763c5e500f4304b7c534fae0fad430d64982e8 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic -Date: Sat, 6 Mar 2021 22:20:59 +0000 -Subject: [PATCH] build/apr_common.m4: avoid explicit inclusion of "confdefs.h" - -The failure is observed on `autoconf-2.69d` (soon to be released -as `autoconf-2.70`). There `int64_t` detection fails as: - -$ autoreconf && ./configure -checking whether int64_t and int use fmt %d... no -checking whether int64_t and long use fmt %ld... no -checking whether int64_t and long long use fmt %lld... no -configure: error: could not determine the string function for int64_t -``` - -This happens because `./configure` always stumbles on warning: - -configure:3350: gcc -c -g -O2 -Werror conftest.c >&5 -In file included from conftest.c:31: -confdefs.h:22: error: "__STDC_WANT_IEC_60559_ATTRIBS_EXT__" redefined [-Werror] - 22 | #define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1 - | - -It's triggered by double inclusion of `"confdefs.h"` contents: -explicitly in `APR_TRY_COMPILE_NO_WARNING` macro and implicitly -via `AC_LANG_SOURCE` use. - -To fix it and avoid having to define `main()` declaration the change -uses `AC_LANG_PROGRAM` instead. - -Tested on both `autoconf-2.69` and `autoconf-2.69d`. - - -Github: closes #25 -Submitted by: Sergei Trofimovich -Reviewed by: ylavic - - -git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1887279 13f79535-47bb-0310-9956-ffa450edef68 ---- - build/apr_common.m4 | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/build/apr_common.m4 b/build/apr_common.m4 -index 3dfe85542b7..67d004983d2 100644 ---- a/build/apr_common.m4 -+++ b/build/apr_common.m4 -@@ -467,13 +467,9 @@ AC_DEFUN([APR_TRY_COMPILE_NO_WARNING], - CFLAGS="$CFLAGS -Werror" - fi - AC_COMPILE_IFELSE( -- [AC_LANG_SOURCE( -- [#include "confdefs.h" -- ] -- [[$1]] -- [int main(int argc, const char *const *argv) {] -+ [AC_LANG_PROGRAM( -+ [[$1]], - [[$2]] -- [ return 0; }] - )], [CFLAGS=$apr_save_CFLAGS - $3], [CFLAGS=$apr_save_CFLAGS - $4])