[New-bugs-announce] [issue39650] Creating zip file where names in local header don't match with central header

Paul Marquess report at bugs.python.org
Sun Feb 16 08:52:17 EST 2020

New submission from Paul Marquess <pmqs at outlook.com>:

Consider this code (based on code from an issue on StackOverflow)

import zipfile
import os

allFilesToZip = ["/tmp/tom"]

with zipfile.ZipFile(allZipPath, 'w') as allZip:
    for f in allFilesToZip:
        allZip.write(f, compress_type=zipfile.ZIP_DEFLATED)
    for zip_info in allZip.infolist():
        if zip_info.filename[-1] == '/':
        zip_info.filename = os.path.basename(zip_info.filename)

The intention of the code is to add a number of files without the path component. The problem is with the use of infolist. (Forget for now that there is an easier way to achieve the expected result.)

The code works in two steps. First it uses the zipfile.write method which will immediately writes the local file header data and the compressed payload to the zipfile on disk. Next the zipinfo entry is used to update the filename. That data gets written only to the central directory in the zip file.

The end result is a badly-formed zip file.

Here is what I see when I run the code above with both Python 2.7 & 3.7. First create the zip file

echo abcd >/tmp/tom
python zip.py

Unzip sees there is a problem

$ unzip -t abc.zip
Archive:  abc.zip
tom:  mismatching "local" filename (tmp/tom),
         continuing with "central" filename version
    testing: tom                      OK
At least one warning-error was detected in abc.zip.

Next dump the internal structure of the zip file - Note the different filename fields output

$ zipdetails abc.zip

0000 LOCAL HEADER #1       04034B50
0004 Extract Zip Spec      14 '2.0'
0005 Extract OS            00 'MS-DOS'
0006 General Purpose Flag  0000
     [Bits 1-2]            0 'Normal Compression'
0008 Compression Method    0008 'Deflated'
000A Last Mod Time         50487109 'Sat Feb  8 14:08:18 2020'
000E CRC                   2CA20FEB
0012 Compressed Length     000000D8
0016 Uncompressed Length   00000180
001A Filename Length       0007
001C Extra Length          0000
001E Filename              'tmp/tom'
0025 PAYLOAD               eP...0.....,m.F\?. .

00FD CENTRAL HEADER #1     02014B50
0101 Created Zip Spec      14 '2.0'
0102 Created OS            03 'Unix'
0103 Extract Zip Spec      14 '2.0'
0104 Extract OS            00 'MS-DOS'
0105 General Purpose Flag  0000
     [Bits 1-2]            0 'Normal Compression'
0107 Compression Method    0008 'Deflated'
0109 Last Mod Time         50487109 'Sat Feb  8 14:08:18 2020'
010D CRC                   00001234
0111 Compressed Length     000000D8
0115 Uncompressed Length   00000180
0119 Filename Length       0003
011B Extra Length          0000
011D Comment Length        0000
011F Disk Start            0000
0121 Int File Attributes   0000
     [Bit 0]               0 'Binary Data'
0123 Ext File Attributes   81B40000
0127 Local Header Offset   00000000
012B Filename              'tom'

0132 Number of this disk   0000
0134 Central Dir Disk no   0000
0136 Entries in this disk  0001
0138 Total Entries         0001
013A Size of Central Dir   00000031
013E Offset to Central Dir 000000FD
0142 Comment Length        0000

Should zipfile allow the user to do this?

components: Library (Lib)
messages: 362072
nosy: pmqs
priority: normal
severity: normal
status: open
title: Creating zip file where names in local header don't match with central header
type: behavior
versions: Python 2.7, Python 3.7

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list