aboutsummaryrefslogtreecommitdiff
path: root/file_io/unix/filepath.c
diff options
context:
space:
mode:
authorIan Holsman <ianh@apache.org>2001-11-27 17:33:13 +0000
committerIan Holsman <ianh@apache.org>2001-11-27 17:33:13 +0000
commit2f5a8c72d2cb75fd8ebd7f86e0da4d68513a8584 (patch)
tree191d0fa6c1d9a88b2e85846e5a7bcdbd967f2953 /file_io/unix/filepath.c
parentb17fe4097501ca7a5b57e173b835d23746d6e060 (diff)
downloadapr-2f5a8c72d2cb75fd8ebd7f86e0da4d68513a8584.tar.gz
apr-2f5a8c72d2cb75fd8ebd7f86e0da4d68513a8584.zip
remove a big nasty strdup for apr_filepath_merge
Submitted by: Brian Pane <bpane@pacbell.net> Reviewed by: Ian Holsman git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@62565 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'file_io/unix/filepath.c')
-rw-r--r--file_io/unix/filepath.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/file_io/unix/filepath.c b/file_io/unix/filepath.c
index d11350719..77845f3d2 100644
--- a/file_io/unix/filepath.c
+++ b/file_io/unix/filepath.c
@@ -118,8 +118,9 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
apr_int32_t flags,
apr_pool_t *p)
{
- char path[APR_PATH_MAX]; /* isn't null term */
+ char *path;
apr_size_t rootlen; /* is the length of the src rootpath */
+ apr_size_t maxlen; /* maximum total path length */
apr_size_t keptlen; /* is the length of the retained rootpath */
apr_size_t pathlen; /* is the length of the result path */
apr_size_t seglen; /* is the end of the current segment */
@@ -184,6 +185,18 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
}
rootlen = strlen(rootpath);
+ maxlen = rootlen + strlen(addpath) + 4; /* 4 for slashes at start, after
+ * root, and at end, plus trailing
+ * null */
+ if (maxlen > APR_PATH_MAX) {
+ if (rootlen >= APR_PATH_MAX) {
+ return APR_ENAMETOOLONG;
+ }
+ maxlen = APR_PATH_MAX;
+ }
+ path = (char *)apr_palloc(p, maxlen);
+
+
if (addpath[0] == '/')
{
@@ -207,14 +220,12 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
/* Base the result path on the rootpath
*/
keptlen = rootlen;
- if (rootlen >= sizeof(path))
- return APR_ENAMETOOLONG;
memcpy(path, rootpath, rootlen);
/* Always '/' terminate the given root path
*/
if (keptlen && path[keptlen - 1] != '/') {
- if (keptlen + 1 >= sizeof(path))
+ if (keptlen + 1 >= maxlen)
return APR_ENAMETOOLONG;
path[keptlen++] = '/';
}
@@ -262,7 +273,7 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
/* Otherwise append another backpath.
*/
- if (pathlen + 3 >= sizeof(path))
+ if (pathlen + 3 >= maxlen )
return APR_ENAMETOOLONG;
memcpy(path + pathlen, "../", 3);
pathlen += 3;
@@ -291,7 +302,7 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
/* An actual segment, append it to the destination path
*/
apr_size_t i = (addpath[seglen] != '\0');
- if (pathlen + seglen + i >= sizeof(path))
+ if (pathlen + seglen + i >= maxlen)
return APR_ENAMETOOLONG;
memcpy(path + pathlen, addpath, seglen + i);
pathlen += seglen + i;
@@ -320,6 +331,6 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
return APR_EABOVEROOT;
}
- *newpath = apr_pstrdup(p, path);
+ *newpath = path;
return APR_SUCCESS;
}