From 8e36d28f3c082d7c10e5d7cbbb5301ec6e0d7d32 Mon Sep 17 00:00:00 2001 From: Greg Ward Date: Wed, 18 Jun 2003 00:53:06 +0000 Subject: [PATCH] SF patch #755987 (Jim Ahlstrom): This is a patch for Bug 755031: If a null byte appears in a file name, Python zipfile.py retains it, but InfoZip terminates the name. Null bytes in file names are used as a trick by viruses. I tested WinZip, and it also truncates the file name at the null byte. The patch also fixes a buglet: If a zipfile incorrectly uses a directory separator other than '/', there was an invalid complaint that the central directory name does not match the file header name. I also removed my name from the top of the file. It was there for legal reasons which I believe no longer apply. Many people have worked on this file besides me. --- Lib/zipfile.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 80d7925413..576eaf97d0 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1,6 +1,4 @@ "Read and write ZIP files." -# Written by James C. Ahlstrom jim@interet.com -# All rights transferred to CNRI pursuant to the Python contribution agreement import struct, os, time import binascii @@ -116,7 +114,19 @@ class ZipInfo: """Class with attributes describing each file in the ZIP archive.""" def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): - self.filename = _normpath(filename) # Name of the file in the archive + self.orig_filename = filename # Original file name in archive +# Terminate the file name at the first null byte. Null bytes in file +# names are used as tricks by viruses in archives. + null_byte = filename.find(chr(0)) + if null_byte >= 0: + filename = filename[0:null_byte] + print "File name %s contains a suspicious null byte!" % filename +# This is used to ensure paths in generated ZIP files always use +# forward slashes as the directory separator, as required by the +# ZIP format specification. + if os.sep != "/": + filename = filename.replace(os.sep, "/") + self.filename = filename # Normalized file name self.date_time = date_time # year, month, day, hour, min, sec # Standard values: self.compress_type = ZIP_STORED # Type of compression for the file @@ -157,17 +167,6 @@ class ZipInfo: return header + self.filename + self.extra -# This is used to ensure paths in generated ZIP files always use -# forward slashes as the directory separator, as required by the -# ZIP format specification. -if os.sep != "/": - def _normpath(path): - return path.replace(os.sep, "/") -else: - def _normpath(path): - return path - - class ZipFile: """ Class with methods to open, read, write, close, list zip files. @@ -300,10 +299,10 @@ class ZipFile: + fheader[_FH_FILENAME_LENGTH] + fheader[_FH_EXTRA_FIELD_LENGTH]) fname = fp.read(fheader[_FH_FILENAME_LENGTH]) - if fname != data.filename: + if fname != data.orig_filename: raise RuntimeError, \ 'File name in directory "%s" and header "%s" differ.' % ( - data.filename, fname) + data.orig_filename, fname) def namelist(self): """Return a list of file names in the archive.""" -- 2.50.1