diff -Naur thttpd-2.25b.org/libhttpd.c thttpd-2.25b-cgi_common_for_all_vhosts/libhttpd.c --- thttpd-2.25b.org/libhttpd.c 2007-08-30 23:17:16.000000000 +0200 +++ thttpd-2.25b-cgi_common_for_all_vhosts/libhttpd.c 2007-08-31 23:06:30.000000000 +0200 @@ -1427,7 +1427,10 @@ } -/* Expands all symlinks in the given filename, eliding ..'s and leading /'s. +/* Expands all symlinks in the given filename, eliding ..'s, .'s and leading /'s. +** Eliding .'s is necessary for vhost symlinked into non-vhost root +** (e.g. in case of HTTP/1.0 client). +** ** Returns the expanded path (pointer to static string), or (char*) 0 on ** errors. Also returns, in the string pointed to by restP, any trailing ** parts of the path that don't exist. @@ -1521,6 +1524,10 @@ (void) strncpy( &checked[checkedlen], r, 1 ); checkedlen += 1; } + else if ( strncmp( r, ".", MAX( i, 1 ) ) == 0 ) + { + /* skip "the same directory" */ + } else if ( strncmp( r, "..", MAX( i, 2 ) ) == 0 ) { /* Ignore ..'s that go above the start of the path. */ @@ -3035,10 +3042,17 @@ size_t l; envp[envn++] = build_env( "PATH_INFO=/%s", hc->pathinfo ); l = strlen( hc->hs->cwd ) + strlen( hc->pathinfo ) + 1; + /* CGI is out of virtual hosts, embed path to virtual host */ + if ( hc->hs->vhost && hc->hostname != (char*) 0 ) { + l += strlen( hc->hostname ) + 1; + } cp2 = NEW( char, l ); if ( cp2 != (char*) 0 ) { - (void) my_snprintf( cp2, l, "%s%s", hc->hs->cwd, hc->pathinfo ); + if ( hc->hs->vhost && hc->hostname != (char*) 0 ) + (void) my_snprintf( cp2, l, "%s%s/%s", hc->hs->cwd, hc->hostname, hc->pathinfo ); + else + (void) my_snprintf( cp2, l, "%s%s", hc->hs->cwd, hc->pathinfo ); envp[envn++] = build_env( "PATH_TRANSLATED=%s", cp2 ); } } @@ -4237,3 +4251,5 @@ str_alloc_count, (unsigned long) str_alloc_size, (float) str_alloc_size / str_alloc_count ); } +/* vim:noet ts=8 + * */