diff options
author | Senthil Kumaran <senthil@uthcode.com> | 2012-04-11 18:37:11 (GMT) |
---|---|---|
committer | Senthil Kumaran <senthil@uthcode.com> | 2012-04-11 18:37:11 (GMT) |
commit | 690598aba28c0b0fcc01888ccd0233df4bb7f95f (patch) | |
tree | bb361a63365525fee023880d5b84038868b0ca00 /Lib/http | |
parent | 1c94ff8b688527faf38c7ed3da6d9a0f7cc45cbe (diff) | |
parent | d70846b1b176eb28c37e4b4bbffdbf6bf8592fd8 (diff) | |
download | cpython-690598aba28c0b0fcc01888ccd0233df4bb7f95f.zip cpython-690598aba28c0b0fcc01888ccd0233df4bb7f95f.tar.gz cpython-690598aba28c0b0fcc01888ccd0233df4bb7f95f.tar.bz2 |
merge to default - Issue 10484 - Incorporate improvements to CGI module - Suggested by Glenn Linderman. Refactor code and tests
Diffstat (limited to 'Lib/http')
-rw-r--r-- | Lib/http/server.py | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/Lib/http/server.py b/Lib/http/server.py index 4c0e6cd..18313cf 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -840,44 +840,47 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): # Utilities for CGIHTTPRequestHandler -# TODO(gregory.p.smith): Move this into an appropriate library. -def _url_collapse_path_split(path): +def _url_collapse_path(path): """ Given a URL path, remove extra '/'s and '.' path elements and collapse - any '..' references. + any '..' references and returns a colllapsed path. Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. + The utility of this function is limited to is_cgi method and helps + preventing some security attacks. Returns: A tuple of (head, tail) where tail is everything after the final / and head is everything before it. Head will always start with a '/' and, if it contains anything else, never have a trailing '/'. Raises: IndexError if too many '..' occur within the path. + """ # Similar to os.path.split(os.path.normpath(path)) but specific to URL # path semantics rather than local operating system semantics. - path_parts = [] - for part in path.split('/'): - if part == '.': - path_parts.append('') - else: - path_parts.append(part) - # Filter out blank non trailing parts before consuming the '..'. - path_parts = [part for part in path_parts[:-1] if part] + path_parts[-1:] + path_parts = path.split('/') + head_parts = [] + for part in path_parts[:-1]: + if part == '..': + head_parts.pop() # IndexError if more '..' than prior parts + elif part and part != '.': + head_parts.append( part ) if path_parts: tail_part = path_parts.pop() + if tail_part: + if tail_part == '..': + head_parts.pop() + tail_part = '' + elif tail_part == '.': + tail_part = '' else: tail_part = '' - head_parts = [] - for part in path_parts: - if part == '..': - head_parts.pop() - else: - head_parts.append(part) - if tail_part and tail_part == '..': - head_parts.pop() - tail_part = '' - return ('/' + '/'.join(head_parts), tail_part) + + splitpath = ('/' + '/'.join(head_parts), tail_part) + collapsed_path = "/".join(splitpath) + + return collapsed_path + nobody = None @@ -954,16 +957,15 @@ class CGIHTTPRequestHandler(SimpleHTTPRequestHandler): (and the next character is a '/' or the end of the string). """ - - splitpath = _url_collapse_path_split(self.path) - joined_path = '/'.join(splitpath) - dir_sep = joined_path.find('/',1) - head, tail = joined_path[:dir_sep], joined_path[dir_sep+1:] + collapsed_path = _url_collapse_path(self.path) + dir_sep = collapsed_path.find('/', 1) + head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:] if head in self.cgi_directories: self.cgi_info = head, tail return True return False + cgi_directories = ['/cgi-bin', '/htbin'] def is_executable(self, path): |