def test_resolve(self): # tuples of test data, expected results tests = [ ('C:\\..\\./drupal.js', 'drupal.js'), ('\\includes\\..\\webform.components.inc\\', 'webform.components.inc'), ('includes/../webform.components.inc', 'webform.components.inc'), ('////.//includes/./../..//..///../webform.components.inc/.', 'dotdot/dotdot/dotdot/webform.components.inc'), (u'////.//includes/./../..//..///../webform.components.inc/.', u'dotdot/dotdot/dotdot/webform.components.inc'), ('includes/../', '.'), ] for tst, expected in tests: assert expected == paths.resolve(tst)
def test_resolve(self): # tuples of test data, expected results tests = [ ("C:\\..\\./drupal.js", "drupal.js"), ("\\includes\\..\\webform.components.inc\\", "webform.components.inc"), ("includes/../webform.components.inc", "webform.components.inc"), ( "////.//includes/./../..//..///../webform.components.inc/.", "dotdot/dotdot/dotdot/webform.components.inc", ), ( u"////.//includes/./../..//..///../webform.components.inc/.", u"dotdot/dotdot/dotdot/webform.components.inc", ), ("includes/../", "."), ] for tst, expected in tests: assert expected == paths.resolve(tst)
def extract(location, target_dir): """ Extract all files from the tar archive file at `location` in the `target_dir`. Plain tars and tars compressed with gzip and bzip2 are supported transparently. Other compressions such as xz or lzma are handled in two steps. Return a list of warnings messages. Raise Exceptions on errors. Skip special files. Contains code derived from Python tarfile.extractall. Copyright (C) 2002 Lars Gustabel <*****@*****.**> All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Credits: Gustavo Niemeyer, Niels Gustabel, Richard Townsend. """ assert location assert target_dir warnings = defaultdict(list) # track directories to fixup modification times at the end directories = [] with closing(tarfile.open(location)) as tar: tar.errorlevel = 1 names = set() for tinfo in tar.getmembers(): is_special = not any( (tinfo.isfile(), tinfo.isdir(), tinfo.islnk(), tinfo.issym())) if is_special: # FIXME: we should not report a warning? warnings[tinfo.name].append('Skipping special file.') continue # hardlinks and symlinks are treated as regular files if tinfo.islnk() or tinfo.issym(): if tinfo.issym(): # Always search the entire archive. linkname = '/'.join( filter(None, (os.path.dirname(tinfo.name), tinfo.linkname))) limit = None else: # Search the archive before the link, because a hard link # is just a reference to an already archived file. linkname = tinfo.linkname limit = tinfo realfile = tar._getmember(linkname, tarinfo=limit, normalize=True) if realfile is None: warnings[tinfo.name].append( 'Skipping broken link to: %(linkname)s' % locals()) continue if not (realfile.isfile() or realfile.isdir()): warnings[tinfo.name].append( 'Skipping link to special file: %(linkname)s' % locals()) continue if realfile.islnk() or realfile.issym(): # FIXME: Check tarbomb warnings[tinfo.name].append( 'Skipping multi-level link to: %(linkname)s' % locals()) continue # replace the tarinfo with the linked-to file info # but keep the link name lname = tinfo.name tinfo = copy.copy(realfile) tinfo.name = lname # FIXME: we skip duplicates, this can happen and will fail if the # location is read-only, we should instead rename duplicates # using extractcode.new_name if tinfo.name.lower() in names: warnings[tinfo.name].append('Skipping duplicate file name.') names.add(tinfo.name.lower()) tinfo = copy.copy(tinfo) # ensure we do stay always under the target dir tinfo.name = resolve(tinfo.name) # Extract all files with a safe mode # FIXME: use the current user mask tinfo.mode = 0700 # keep a list of dirs to fix mtime once they are all created if tinfo.isdir(): directories.append(tinfo) try: tar.extract(tinfo, target_dir) except Exception, e: # FIXME: we must keep the traceback for diagnostics raise ExtractError()
def test_resolve_6(self): test = paths.resolve('includes/../') expected = '.' assert expected == test
def test_resolve_3(self): test = paths.resolve('includes/../webform.components.inc') expected = 'webform.components.inc' assert expected == test
def test_resolve_5(self): test = paths.resolve( u'////.//includes/./../..//..///../webform.components.inc/.') expected = u'dotdot/dotdot/dotdot/webform.components.inc' assert expected == test
def test_resolve_mixed_slash(self): test = paths.resolve('C:\\..\\./drupal.js') expected = 'C/drupal.js' assert expected == test
def test_resolve_2(self): test = paths.resolve('\\includes\\..\\webform.components.inc\\') expected = 'webform.components.inc' assert expected == test
def test_resolve_4(self): test = paths.resolve( '////.//includes/./../..//..///../webform.components.inc/.') expected = 'dotdot/dotdot/dotdot/webform.components.inc' assert test == expected
def extract(location, target_dir): """ Extract all files from the tar archive file at `location` in the `target_dir`. Plain tars and tars compressed with gzip and bzip2 are supported transparently. Other compressions such as xz or lzma are handled in two steps. Return a list of warnings messages. Raise Exceptions on errors. Skip special files. Contains code derived from Python tarfile.extractall. Copyright (C) 2002 Lars Gustabel <*****@*****.**> All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Credits: Gustavo Niemeyer, Niels Gustabel, Richard Townsend. """ assert location assert target_dir warnings = defaultdict(list) with closing(tarfile.open(location)) as tar: tar.errorlevel = 1 directories = [] names = set() for tinfo in tar.getmembers(): is_special = not (tinfo.isfile() or tinfo.isdir() or tinfo.islnk() or tinfo.issym()) if is_special: # FIXME: we should not report a warning? warnings[tinfo.name].append('Skipping special file.') continue # hardlinks and symlinks are treated as regular files if tinfo.islnk() or tinfo.issym(): if tinfo.issym(): # Always search the entire archive. linkname = '/'.join(filter(None, (os.path.dirname(tinfo.name), tinfo.linkname))) limit = None else: # Search the archive before the link, because a hard link # is just a reference to an already archived file. linkname = tinfo.linkname limit = tinfo realfile = tar._getmember(linkname, tarinfo=limit, normalize=True) if realfile is None: warnings[tinfo.name].append('Skipping broken link to: %(linkname)r' % locals()) continue if not (realfile.isfile() or realfile.isdir()): warnings[tinfo.name].append('Skipping link to special file: %(linkname)r' % locals()) continue if realfile.islnk() or realfile.issym(): # FIXME: Check tarbomb warnings[tinfo.name].append('Skipping multi-level link to: %(linkname)r' % locals()) continue # replace the tarinfo with the linked-to file info # but keep the link name lname = tinfo.name tinfo = copy.copy(realfile) tinfo.name = lname # FIXME: we skip duplicates, this can happen and will fail if the # location is read-only, we should instead rename duplicates # using extractcode.new_name if tinfo.name.lower() in names: warnings[tinfo.name].append('Skipping duplicate file name.') names.add(tinfo.name.lower()) tinfo = copy.copy(tinfo) # ensure we do stay always under the target dir tinfo.name = resolve(tinfo.name) # Extract all files with a safe mode # FIXME: use the current user mask tinfo.mode = 0700 # keep a list of dirs to fix mtime once they are all created if tinfo.isdir(): directories.append(tinfo) try: tar.extract(tinfo, target_dir) except Exception, e: raise ExtractError() # Set correct mtime on directories, starting from the bottom of the # tree for tinfo in sorted(directories, cmp=lambda a, b: cmp(a.name, b.name), reverse=True): dir_loc = os.path.join(target_dir, tinfo.name) try: # NOTE: this may not work at all on Windows tar.utime(tinfo, dir_loc) except Exception, e: warnings[tinfo.name].append(str(e))
def test_resolve_5(self): test = paths.resolve(u'////.//includes/./../..//..///../webform.components.inc/.') expected = u'dotdot/dotdot/dotdot/webform.components.inc' assert expected == test