summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Zhakov <ivan@apache.org>2022-09-12 16:27:37 +0000
committerIvan Zhakov <ivan@apache.org>2022-09-12 16:27:37 +0000
commite92a8ccc12f3fdb2fe670f99ce6c2ac170e53db4 (patch)
treef3456f37c44a3c3db6c39396fcf11dfa449cef11
parentec60e59e5dfde238caaeaa02045de5dfb080f92c (diff)
downloadapr-e92a8ccc12f3fdb2fe670f99ce6c2ac170e53db4.tar.gz
On 1.7.x branch: Merge r1902110 from 1.8.x branch:
win32: Fix attempt to free invalid memory on exit when apr_app is used. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.7.x@1904024 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES3
-rw-r--r--misc/win32/apr_app.c32
2 files changed, 30 insertions, 5 deletions
diff --git a/CHANGES b/CHANGES
index b10cd95ba..f7eccf9cd 100644
--- a/CHANGES
+++ b/CHANGES
@@ -70,6 +70,9 @@ Changes for APR 1.7.1
*) Fixed: apr_get_oslevel() was returning APR_WIN_XP on Windows 10
+ *) Fix attempt to free invalid memory on exit when apr_app is used
+ on Windows. [Ivan Zhakov]
+
Changes for APR 1.7.0
*) apr_dir_read: [Unix] Dropped the preference of the dirread_r() flavor
diff --git a/misc/win32/apr_app.c b/misc/win32/apr_app.c
index 4e08e33d7..f1b6ce57c 100644
--- a/misc/win32/apr_app.c
+++ b/misc/win32/apr_app.c
@@ -51,15 +51,37 @@ int wmain(int argc, const wchar_t **wargv, const wchar_t **wenv)
{
char **argv;
char **env;
- int dupenv;
+ int envc;
+ int i;
(void)apr_wastrtoastr(&argv, wargv, argc);
- dupenv = apr_wastrtoastr(&env, wenv, -1);
+ envc = 0;
+ while (wenv[envc]) {
+ envc++;
+ }
+
+ /* Initial environment stored as single heap block, but uses
+ * separate heap entry for every environment variable
+ * after first change.
+ */
+ env = apr_malloc_dbg((envc + 1) * sizeof(char *), __FILE__, __LINE__);
+
+ for (i = 0; i < envc; i++) {
+ apr_size_t wcount;
+ apr_size_t envlen;
+
+ wcount = wcslen(wenv[i]) + 1;
+ envlen = (wcount - 1) * 3 + 1;
+
+ env[i] = apr_malloc_dbg(envlen, __FILE__, __LINE__);
+
+ (void)apr_conv_ucs2_to_utf8(wenv[i], &wcount, env[i], &envlen);
+ }
+
+ env[i] = NULL;
- _environ = apr_malloc_dbg((dupenv + 1) * sizeof (char *),
- __FILE__, __LINE__ );
- memcpy(_environ, env, (dupenv + 1) * sizeof (char *));
+ _environ = env;
/* MSVCRT will attempt to maintain the wide environment calls
* on _putenv(), which is bogus if we've passed a non-ascii