You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by mt...@apache.org on 2011/11/08 14:39:29 UTC

svn commit: r1199238 - in /tomcat/jk/trunk: native/iis/jk_isapi_plugin.c xdocs/miscellaneous/changelog.xml

Author: mturk
Date: Tue Nov  8 13:39:28 2011
New Revision: 1199238

URL: http://svn.apache.org/viewvc?rev=1199238&view=rev
Log:
BZ46406 Allow relative paths for configuration directives. The paths are presumed to be relative from isapi_redirect.dll load location

Modified:
    tomcat/jk/trunk/native/iis/jk_isapi_plugin.c
    tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml

Modified: tomcat/jk/trunk/native/iis/jk_isapi_plugin.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/iis/jk_isapi_plugin.c?rev=1199238&r1=1199237&r2=1199238&view=diff
==============================================================================
--- tomcat/jk/trunk/native/iis/jk_isapi_plugin.c (original)
+++ tomcat/jk/trunk/native/iis/jk_isapi_plugin.c Tue Nov  8 13:39:28 2011
@@ -605,6 +605,10 @@ static int get_iis_info(iis_info_t *info
 
 static int isapi_write_client(isapi_private_data_t *p, const char *buf, unsigned int write_length);
 
+static char *path_merge(const char *root, const char *path);
+
+static int is_path_relative(const char *path);
+
 static char x2c(const char *what)
 {
     register char digit;
@@ -2141,7 +2145,7 @@ DWORD WINAPI HttpFilterProc(PHTTP_FILTER
                         StringCbCat(serverName, MAX_SERVERNAME, "_");
                         StringCbCat(serverName, MAX_SERVERNAME, app_poolId);
                     }
-                }                
+                }
                 for (i = 0; i < (DWORD)strlen(serverName); i++) {
                     if (serverName[i] == ' ' || serverName[i] == '/' || serverName[i] == '\\')
                         serverName[i] = '_';
@@ -2908,16 +2912,23 @@ static int read_registry_init_data(void)
         }
     }
     ok = ok && get_config_parameter(src, JK_LOG_FILE_TAG, log_file, sizeof(log_file));
-    if (get_config_parameter(src, JK_LOG_LEVEL_TAG, tmpbuf, sizeof(tmpbuf))) {
+    if (ok && is_path_relative(log_file)) {
+        char *fp = path_merge(dll_file_path, log_file);
+        if (fp) {
+            StringCbCopy(log_file, sizeof(log_file), fp);
+            free(fp);
+        }
+    }
+    if (ok && get_config_parameter(src, JK_LOG_LEVEL_TAG, tmpbuf, sizeof(tmpbuf))) {
         log_level = jk_parse_log_level(tmpbuf);
     }
-    if (get_config_parameter(src, LOG_ROTATION_TIME_TAG, tmpbuf, sizeof(tmpbuf))) {
+    if (ok && get_config_parameter(src, LOG_ROTATION_TIME_TAG, tmpbuf, sizeof(tmpbuf))) {
         log_rotationtime = atol(tmpbuf);
         if (log_rotationtime < 0) {
             log_rotationtime = 0;
         }
     }
-    if (get_config_parameter(src, LOG_FILESIZE_TAG, tmpbuf, sizeof(tmpbuf))) {
+    if (ok && get_config_parameter(src, LOG_FILESIZE_TAG, tmpbuf, sizeof(tmpbuf))) {
         size_t tl = strlen(tmpbuf);
         if (tl > 0) {
             /* rotatelogs has an 'M' suffix on filesize, which we optionally support for consistency */
@@ -2935,10 +2946,32 @@ static int read_registry_init_data(void)
 
     ok = ok && get_config_parameter(src, EXTENSION_URI_TAG, extension_uri, sizeof(extension_uri));
     ok = ok && get_config_parameter(src, JK_WORKER_FILE_TAG, worker_file, sizeof(worker_file));
+    if (ok && is_path_relative(worker_file)) {
+        char *fp = path_merge(dll_file_path, worker_file);
+        if (fp) {
+            StringCbCopy(worker_file, sizeof(worker_file), fp);
+            free(fp);
+        }
+    }
     ok = ok && get_config_parameter(src, JK_MOUNT_FILE_TAG, worker_mount_file, sizeof(worker_mount_file));
+    if (ok && is_path_relative(worker_mount_file)) {
+        char *fp = path_merge(dll_file_path, worker_mount_file);
+        if (fp) {
+            StringCbCopy(worker_mount_file, sizeof(worker_mount_file), fp);
+            free(fp);
+        }
+    }
     if (!ok)
         goto cleanup;
-    get_config_parameter(src, URI_REWRITE_TAG, rewrite_rule_file, sizeof(rewrite_rule_file));
+    if (get_config_parameter(src, URI_REWRITE_TAG, rewrite_rule_file, sizeof(rewrite_rule_file))) {
+        if (is_path_relative(rewrite_rule_file)) {
+            char *fp = path_merge(dll_file_path, rewrite_rule_file);
+            if (fp) {
+                StringCbCopy(rewrite_rule_file, sizeof(rewrite_rule_file), fp);
+                free(fp);
+            }
+        }
+    }
     if (get_config_parameter(src, URI_SELECT_TAG, tmpbuf, sizeof(tmpbuf))) {
         int opt = parse_uri_select(tmpbuf);
         if (opt >= 0) {
@@ -3555,3 +3588,201 @@ static int get_iis_info(iis_info_t* iis_
     }
     return rv;
 }
+
+/*
+ * 1. Remove  //?/ prefix
+ * 2. Replace UNC/ with //
+ */
+static __inline char *NO2UNC(char *fname)
+{
+    if (fname[0] == '/' && fname[1] == '/' &&
+        fname[2] == '?' && fname[3] == '/') {
+        fname += 4;
+        if (fname[0] == 'U' && fname[1] == 'N' &&
+            fname[2] == 'C' && fname[3] == '/') {
+            fname += 2;
+            *fname = '/';
+        }
+        else if (fname[0] == 'U' && fname[1] == 'N' &&
+            fname[2] == '/' && fname[3] == '/') {
+            fname += 2;
+            /* Already modified in-place.
+             */
+            fname += 2;
+        }
+    }
+    return fname;
+}
+
+static __inline void FS2BSA(char *str)
+{
+    for (; *str != 0; str++) {
+        if (*str == '/')
+            *str = '\\';
+    }
+}
+
+static __inline void BS2FSA(char *str)
+{
+    for (; *str != 0; str++) {
+        if (*str == '\\')
+            *str = '/';
+    }
+}
+
+#define NON_UNC_PATH_LENGTH     248
+
+#define IS_PATH_SEP(C)   ((C) == '/' || (C) == '\0')
+#define IS_DRIVE_CHAR(C) (((C) >= 'A' && (C) <= 'Z') || \
+                          ((C) >= 'a' && (C) <= 'z'))
+#define _INS_TRAILING_PATH_SEP(s, l)  \
+    if (l > 0 && s[l - 1] != '/') s[l++] = '/', s[l] = '\0'
+#define _DEL_TRAILING_PATH_SEP(s, l)  \
+    do {                                                    \
+        if (l > 1 && s[l - 1] == '/') {                     \
+            if (s[l - 2] != '/' && s[l - 2] != ':')         \
+                s[--l] = '\0';                              \
+        }                                                   \
+    } while(0)
+
+static char *relative_path(char *path, size_t size)
+{
+    char *sp;
+    char *cp;
+    int   ch = '/';
+
+    /* Convert everything to foward slashes
+     */
+    BS2FSA(path);
+    /* Remove \\?\ and replace \\?\UNC\ with \\
+     */
+    path = NO2UNC(path);
+    size = strlen(path);
+    if (size < 2) {
+        if (path[0] == ' ') {
+            /* Single Trailing space is invalid path
+             */
+            SetLastError(ERROR_BAD_PATHNAME);
+            return 0;
+        }
+        return path;
+    }
+    else {
+        /* Remove any trailing slash unless this is
+         * a single slash path.
+         */
+        _DEL_TRAILING_PATH_SEP(path, size);
+        if (path[size - 1] == ' ' || path[size - 1] == '.') {
+            /* Trailing space and dot are invalid file or dir names
+             */
+            SetLastError(ERROR_BAD_PATHNAME);
+            return 0;
+        }
+    }
+    sp = path;
+    if (size > 1 && path[1] == ':' && IS_DRIVE_CHAR(path[0])) {
+        /* Never go above C: */
+        path += 2;
+    }
+    else if (path[0] == '/' && path[1] == '/') {
+        /* Never go above //share/
+         */
+        if (path[2] == '.' && path[3] == '/') {
+            /* This is probably //./pipe/ */
+            return path;
+        }
+        cp = strchr(path + 2, '/');
+        if (cp != 0)
+            path = cp;
+        else {
+            /* We only have //share
+             */
+            return path;
+        }
+    }
+    /* Remaining is the same as on unixes */
+    cp = path;
+    while (*path) {
+        if (IS_PATH_SEP(ch) && *path == '.') {
+            int nd = 0;
+            while (path[nd] == '.')
+                nd++;
+            if (nd > 2 && path[nd] == '/') {
+                SetLastError(ERROR_BAD_PATHNAME);
+                return 0;
+            }
+            if (IS_PATH_SEP(path[nd])) {
+                path += nd;
+                if (*path)
+                    path++;
+                while (nd > 1) {
+                    if (cp > sp + 1) {
+                        cp--;
+                        while (cp > sp) {
+                            if (IS_PATH_SEP(*(cp - 1)))
+                                break;
+                            cp--;
+                        }
+                    }
+                    else
+                        break;
+                    nd--;
+                }
+            }
+            else
+                ch = *cp++ = *path++;
+        }
+        else
+            ch = *cp++ = *path++;
+    }
+    *cp = '\0';
+    return sp;
+}
+
+static char *path_merge(const char *root, const char *path)
+{
+    char  merge[8192];
+    char *rel;
+    char *out = 0;
+    size_t sz;
+
+    if (root == NULL || path == NULL) {
+        SetLastError(ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+    if (FAILED(StringCbCopy(merge, 8190, path))) {
+        /* TODO: Use dynamic buffer with larger size */
+        SetLastError(ERROR_FILENAME_EXCED_RANGE);
+        return 0;
+    }
+    sz = strlen(merge);
+    /* Normalize path */
+    if ((rel = relative_path(merge, sz))) {
+        size_t bl = strlen(root) + sz + 1;
+        out = malloc(bl);
+        if (out == 0)
+            return 0;
+        /* Prepend root */
+        StringCbCopy(out, bl, root);
+        sz = strlen(out);
+        BS2FSA(out);
+        _INS_TRAILING_PATH_SEP(out, sz);
+        if ((IS_DRIVE_CHAR(rel[0]) && rel[1] == ':'))
+            rel += 2;
+        if (rel[0] == '/')
+            ++rel;
+        if (*rel != '\0')
+            StringCbCopy(out + sz, bl - sz, rel);
+            FS2BSA(out);
+    }
+    return out;
+}
+
+static int is_path_relative(const char *path)
+{
+    if ((IS_DRIVE_CHAR(path[0]) && path[1] == ':') ||
+         path[0] == '/' || path[0] == '\\')
+        return 0;
+    else
+        return 1;
+}

Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1199238&r1=1199237&r2=1199238&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original)
+++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Tue Nov  8 13:39:28 2011
@@ -44,6 +44,10 @@
   <br />
   <subsection name="Native">
     <changelog>
+      <update>
+        <bug>46406</bug>: IIS: Support relative paths in configuration.
+        The paths are presumed to be relative from isapi_redirect.dll. (mturk)
+      </update>        
       <fix>
         <bug>50233</bug>: Do not use hard limit on uri size (mturk).
       </fix>        



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org