summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrane <brane@13f79535-47bb-0310-9956-ffa450edef68>2015-06-17 03:40:20 +0000
committerbrane <brane@13f79535-47bb-0310-9956-ffa450edef68>2015-06-17 03:40:20 +0000
commit764e7453de66b3a65ef3c80c4d48db14af63b785 (patch)
tree883484b1d920907a610868785cf61e519399500c
parentc779627003909f00abc380fc6f222b09f0cddd8e (diff)
downloadlibapr-764e7453de66b3a65ef3c80c4d48db14af63b785.tar.gz
apr_filepath_merge: Fix truename length calculation on Windows
in cases where the "short" name variant is actually longer than the "long" or "true" name. Patch submitted bu Bert Huijben <rhuijben a.o>. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@1685929 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES5
-rw-r--r--file_io/win32/filepath.c4
-rw-r--r--test/testnames.c34
3 files changed, 41 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index 52c1455bb..71d5df3d3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,11 @@
-*- coding: utf-8 -*-
Changes for APR 2.0.0
+ *) apr_filepath_merge: Fix truename length calculation on Windows
+ in cases where the "short" name variant is actually longer than
+ the "long" or "true" name. See: testnames.c:merge_shortname().
+ [Bert Huijben <rhuijben a.o>]
+
*) apr_file_mktemp: Use mkostemp() where available to save on system
calls. [Joe Orton]
diff --git a/file_io/win32/filepath.c b/file_io/win32/filepath.c
index 0bf5cc0ba..23870bc54 100644
--- a/file_io/win32/filepath.c
+++ b/file_io/win32/filepath.c
@@ -890,9 +890,9 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
memmove(path + keptlen + namelen + 1,
path + keptlen + seglen + 1,
pathlen - keptlen - seglen);
- pathlen += namelen - seglen;
- seglen = namelen;
}
+ pathlen += namelen - seglen;
+ seglen = namelen;
}
else { /* namelen > seglen */
if (pathlen + namelen - seglen >= sizeof(path))
diff --git a/test/testnames.c b/test/testnames.c
index 5afba0c44..4fcd3c033 100644
--- a/test/testnames.c
+++ b/test/testnames.c
@@ -214,6 +214,39 @@ static void merge_lowercasedrive(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
}
+
+static void merge_shortname(abts_case *tc, void *data)
+{
+ apr_status_t rv;
+ char *long_path;
+ char short_path[MAX_PATH+1];
+ DWORD short_len;
+ char *result_path;
+
+ /* 'A b.c' is not a valid short path, so will have multiple representations
+ when short path name generation is enabled... but its 'short' path will
+ most likely be longer than the long path */
+ rv = apr_dir_make_recursive("C:/data/short/A b.c",
+ APR_UREAD | APR_UWRITE | APR_UEXECUTE, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+ rv = apr_filepath_merge(&long_path, NULL, "C:/data/short/A b.c",
+ APR_FILEPATH_NOTRELATIVE, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+ short_len = GetShortPathName(long_path, short_path, sizeof(short_path));
+ if (short_len > MAX_PATH)
+ return; /* Unable to test. Impossible shortname */
+
+ if (! strcmp(long_path, short_path))
+ return; /* Unable to test. 8dot3name option is probably not enabled */
+
+ rv = apr_filepath_merge(&result_path, "", short_path, APR_FILEPATH_TRUENAME,
+ p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+ ABTS_STR_EQUAL(tc, long_path, result_path);
+}
#endif
static void root_absolute(abts_case *tc, void *data)
@@ -341,6 +374,7 @@ abts_suite *testnames(abts_suite *suite)
abts_run_test(suite, merge_dotdot_dotdot_dotdot, NULL);
#if defined(WIN32)
abts_run_test(suite, merge_lowercasedrive, NULL);
+ abts_run_test(suite, merge_shortname, NULL);
#endif
abts_run_test(suite, root_absolute, NULL);