Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Lib/CGIHTTPServer.py

    r2 r388  
    3030import SimpleHTTPServer
    3131import select
     32import copy
    3233
    3334
     
    7172
    7273    def is_cgi(self):
    73         """Test whether self.path corresponds to a CGI script,
    74         and return a boolean.
    75 
    76         This function sets self.cgi_info to a tuple (dir, rest)
    77         when it returns True, where dir is the directory part before
    78         the CGI script name.  Note that rest begins with a
    79         slash if it is not empty.
    80 
    81         The default implementation tests whether the path
    82         begins with one of the strings in the list
    83         self.cgi_directories (and the next character is a '/'
    84         or the end of the string).
     74        """Test whether self.path corresponds to a CGI script.
     75
     76        Returns True and updates the cgi_info attribute to the tuple
     77        (dir, rest) if self.path requires running a CGI script.
     78        Returns False otherwise.
     79
     80        If any exception is raised, the caller should assume that
     81        self.path was rejected as invalid and act accordingly.
     82
     83        The default implementation tests whether the normalized url
     84        path begins with one of the strings in self.cgi_directories
     85        (and the next character is a '/' or the end of the string).
    8586        """
    86 
    87         path = self.path
    88 
    89         for x in self.cgi_directories:
    90             i = len(x)
    91             if path[:i] == x and (not path[i:] or path[i] == '/'):
    92                 self.cgi_info = path[:i], path[i+1:]
    93                 return True
     87        collapsed_path = _url_collapse_path(self.path)
     88        dir_sep = collapsed_path.find('/', 1)
     89        head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:]
     90        if head in self.cgi_directories:
     91            self.cgi_info = head, tail
     92            return True
    9493        return False
    9594
     
    107106    def run_cgi(self):
    108107        """Execute a CGI script."""
    109         path = self.path
    110108        dir, rest = self.cgi_info
    111109
    112         i = path.find('/', len(dir) + 1)
     110        i = rest.find('/')
    113111        while i >= 0:
    114             nextdir = path[:i]
    115             nextrest = path[i+1:]
     112            nextdir = rest[:i]
     113            nextrest = rest[i+1:]
    116114
    117115            scriptdir = self.translate_path(nextdir)
    118116            if os.path.isdir(scriptdir):
    119117                dir, rest = nextdir, nextrest
    120                 i = path.find('/', len(dir) + 1)
     118                i = rest.find('/')
    121119            else:
    122120                break
     
    159157        # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
    160158        # XXX Much of the following could be prepared ahead of time!
    161         env = {}
     159        env = copy.deepcopy(os.environ)
    162160        env['SERVER_SOFTWARE'] = self.version_string()
    163161        env['SERVER_NAME'] = self.server.server_name
     
    221219                  'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'):
    222220            env.setdefault(k, "")
    223         os.environ.update(env)
    224221
    225222        self.send_response(200, "Script output follows")
     
    253250                os.dup2(self.rfile.fileno(), 0)
    254251                os.dup2(self.wfile.fileno(), 1)
    255                 os.execve(scriptfile, args, os.environ)
     252                os.execve(scriptfile, args, env)
    256253            except:
    257254                self.server.handle_error(self.request, self.client_address)
     
    279276                                 stdin = subprocess.PIPE,
    280277                                 stdout = subprocess.PIPE,
    281                                  stderr = subprocess.PIPE
     278                                 stderr = subprocess.PIPE,
     279                                 env = env
    282280                                )
    283281            if self.command.lower() == "post" and nbytes > 0:
     
    293291            if stderr:
    294292                self.log_error('%s', stderr)
     293            p.stderr.close()
     294            p.stdout.close()
    295295            status = p.returncode
    296296            if status:
     
    298298            else:
    299299                self.log_message("CGI script exited OK")
     300
     301
     302def _url_collapse_path(path):
     303    """
     304    Given a URL path, remove extra '/'s and '.' path elements and collapse
     305    any '..' references and returns a colllapsed path.
     306
     307    Implements something akin to RFC-2396 5.2 step 6 to parse relative paths.
     308    The utility of this function is limited to is_cgi method and helps
     309    preventing some security attacks.
     310
     311    Returns: A tuple of (head, tail) where tail is everything after the final /
     312    and head is everything before it.  Head will always start with a '/' and,
     313    if it contains anything else, never have a trailing '/'.
     314
     315    Raises: IndexError if too many '..' occur within the path.
     316
     317    """
     318    # Similar to os.path.split(os.path.normpath(path)) but specific to URL
     319    # path semantics rather than local operating system semantics.
     320    path_parts = path.split('/')
     321    head_parts = []
     322    for part in path_parts[:-1]:
     323        if part == '..':
     324            head_parts.pop() # IndexError if more '..' than prior parts
     325        elif part and part != '.':
     326            head_parts.append( part )
     327    if path_parts:
     328        tail_part = path_parts.pop()
     329        if tail_part:
     330            if tail_part == '..':
     331                head_parts.pop()
     332                tail_part = ''
     333            elif tail_part == '.':
     334                tail_part = ''
     335    else:
     336        tail_part = ''
     337
     338    splitpath = ('/' + '/'.join(head_parts), tail_part)
     339    collapsed_path = "/".join(splitpath)
     340
     341    return collapsed_path
    300342
    301343
Note: See TracChangeset for help on using the changeset viewer.