diff options
author | Senthil Kumaran <senthil@uthcode.com> | 2012-04-11 18:23:23 (GMT) |
---|---|---|
committer | Senthil Kumaran <senthil@uthcode.com> | 2012-04-11 18:23:23 (GMT) |
commit | 5f7e7345cf4f583c127160aa43ee5c3fea7ba06f (patch) | |
tree | 6ce93dfa3afc325fe585a53564d9c37a468a71ad /Lib/CGIHTTPServer.py | |
parent | dc0b324a0f73692e90fe999260f1d0f3c8371147 (diff) | |
download | cpython-5f7e7345cf4f583c127160aa43ee5c3fea7ba06f.zip cpython-5f7e7345cf4f583c127160aa43ee5c3fea7ba06f.tar.gz cpython-5f7e7345cf4f583c127160aa43ee5c3fea7ba06f.tar.bz2 |
Issue 10484 - Incorporate improvements to CGI module - Suggested by Glenn Linderman. Refactor code and tests
Diffstat (limited to 'Lib/CGIHTTPServer.py')
-rw-r--r-- | Lib/CGIHTTPServer.py | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/Lib/CGIHTTPServer.py b/Lib/CGIHTTPServer.py index 61f34f8..47a994c 100644 --- a/Lib/CGIHTTPServer.py +++ b/Lib/CGIHTTPServer.py @@ -84,10 +84,9 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): path begins with one of the strings in self.cgi_directories (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 @@ -301,44 +300,46 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): self.log_message("CGI script exited OK") -# 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 |