Python zipfile module adds files with null bytes instead of correct content
Question: When I use `zipfile.ZipFile.writestr`, the file contains the correct amount of
characters afterwards, but all of them are null bytes.

Minimal example:

    
    
    import zipfile
    z=zipfile.ZipFile("test.zip", "w")
    z.writestr("foo", "test")
    z.close()
    

The resulting test.zip has a file "foo" inside, which contains 4 null bytes.


Answer: Got the same problem, and it seems ZipInfo is the obvious workaround.

    
    
    import zipfile, os
    
    name = 'foo.txt'
    data = b'This is a test text.'
    
    open(name, 'wb').write(data)
    zipfile.ZipFile('write.zip', 'w').write(name)              # OK for Ark
    zipfile.ZipFile('writestr.zip', 'w').writestr(name, data)  # nulls by Ark
    
    wrt_attr = zipfile.ZipFile('write.zip').getinfo(name)
    wrts_attr = zipfile.ZipFile('writestr.zip').getinfo(name)
    
    os.remove(name)
    os.remove('write.zip')
    os.remove('writestr.zip')
    
    for attr in wrt_attr.__slots__:
        if getattr(wrt_attr, attr) != getattr(wrts_attr, attr):
            attr, getattr(wrt_attr, attr), getattr(wrts_attr, attr)
    
    attr = 'external_attr'
    oct(getattr(wrt_attr, attr)>>16), oct(getattr(wrts_attr, attr)>>16)
    

The [ZIP spec](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT)
says, `external_attr` should be set to zero if the content is came from
`stdin`. However, `writestr` constructs an
[invalid](https://github.com/python/cpython/blob/3.0/Lib/zipfile.py#1096)
external_attr when the first argument is str.

It could be

    
    
    0o100xxx (regular file with umasked permission)
    

or

    
    
    zero (as the spec)
    

but not

    
    
    0oxxx (file type absent)
    

