in native/common/jk_util.c [2192:2295]
int jk_servlet_normalize(char *path, jk_log_context_t *log_ctx)
{
int l, w;
if (JK_IS_DEBUG_LEVEL(log_ctx)) {
jk_log(log_ctx, JK_LOG_DEBUG, "URI on entering jk_servlet_normalize: [%s]", path);
}
// This test allows the loops below to start at index 1 rather than 0.
if (path[0] != '/') {
if (path[0] == '*' && path[1] == '\0') {
/* Most likely an "OPTIONS *" request */
return 0;
}
jk_log(log_ctx, JK_LOG_WARNING, "Uri [%s] does not start with '/'.", path);
return JK_NORMALIZE_BAD_PATH;
}
/* First pass.
* Remove path parameters ;foo=bar/ from any path segment
*/
for (l = 1, w = 1; path[l] != '\0';) {
if (path[l] == ';') {
l++;
while (path[l] != '/' && path[l] != '\0') {
l++;
}
}
else
path[w++] = path[l++];
}
path[w] = '\0';
/*
* Second pass.
* Collapse ///// sequences to /
*/
for (l = 1, w = 1; path[l] != '\0';) {
if (path[w - 1] == '/' && (path[l] == '/')) {
l++;
}
else
path[w++] = path[l++];
}
path[w] = '\0';
/* Third pass.
* Remove /./ segments
* Both leading and trailing segments will be removed.
*/
for (l = 1, w = 1; path[l] != '\0';) {
if (path[l] == '.' &&
(path[l + 1] == '/' || path[l + 1] == '\0') &&
(l == 0 || path[l - 1] == '/')) {
l++;
if (path[l] == '/') {
l++;
}
}
else
path[w++] = path[l++];
}
path[w] = '\0';
/* Fourth pass.
* Remove /xx/../ segments
* Trailing segments will be removed but leading /../ segments are an error
* condition.
*/
for (l = 1, w = 1; path[l] != '\0';) {
if (path[l] == '.' && path[l + 1] == '.' &&
(path[l + 2] == '/' || path[l + 2] == '\0') &&
(l == 0 || path[l - 1] == '/')) {
// Wind w back to remove the previous segment
if (w == 1) {
jk_log(log_ctx,
JK_LOG_EMERG,
"[%s] contains a '/../' sequence that tries to escape above the root.",
path);
return JK_NORMALIZE_TRAVERSAL;
}
do {
w--;
} while (w != 0 && path[w - 1] != '/');
// Move l forward to the next segment
l += 2;
if (path[l] == '/') {
l++;
}
}
else
path[w++] = path[l++];
}
path[w] = '\0';
if (JK_IS_DEBUG_LEVEL(log_ctx)) {
jk_log(log_ctx, JK_LOG_DEBUG, "URI on exiting jk_servlet_normalize: [%s]", path);
}
return 0;
}