Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7z reports CRC error on files downloaded from NextCloud #37

Open
andyboeh opened this issue Mar 11, 2017 · 14 comments
Open

7z reports CRC error on files downloaded from NextCloud #37

andyboeh opened this issue Mar 11, 2017 · 14 comments

Comments

@andyboeh
Copy link

There is already a NC bug open: nextcloud/server/issues/2352
Some files downloaded from NextCloud won't work in Windows ZIP or, in my case. 7z for Linux or any frontend (e.g. Engrampa).
Disabling Zip64 seems to fix the issue.

I get the following output using 7z t file.zip:

7z t file.zip 

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_GB.utf8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz (40651),ASM,AES-NI)

Scanning the drive for archives:
1 file, 8363809 bytes (8168 KiB)

Testing archive: file.zip

ERRORS:
Headers Error

--
Path = file.zip
Type = zip
ERRORS:
Headers Error
Physical Size = 8363809
64-bit = +

    

Archives with Errors: 1

Open Errors: 1

@McNetic
Copy link
Owner

McNetic commented Mar 12, 2017

I will first try to find the source of the problem in the nextcloud issue (unless someone provided reproduction of the problem with ZipStreamer directly).

@tspivey
Copy link

tspivey commented May 29, 2017

With ZipStreamer, I can reproduce this 7zip issue with the following code:

<?php
require("src/ZipStreamer.php");
$zip = new ZipStreamer\ZipStreamer();
$stream = fopen("README.md", "r");
$zip->addFileFromStream($stream, 'README.test');
fclose($stream);
$zip->finalize();
?>

Running php test.php >test.zip and 7z t test.zip
gives me the same Headers Error.

I'm using p7zip 16.02 on Linux. Some debugging showed me this error is caused when reading the end of central directory record.
From CPP/7zip/Archive/Zip/ZipIn.cpp:2077:

  if (ecd.NumEntries > items.Size())
    HeadersError = true;

ecd.NumEntries is 0xffff.

If I modify buildEndOfCentralDirectoryRecord() to put the correct number of entries in the record:

      $cdRecCount = min(sizeof($this->cdRec), 0xffff);

p7zip can test the archive without errors.

@McNetic
Copy link
Owner

McNetic commented Jun 8, 2017

As far as I can see, the behaviour of ZipStreamer is compliant with the spec. See https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.4.TXT, section 4.4.21 and 4.4.22:

The total number of files [...]. If an archive is in ZIP64 format and the value in this field is 0xFFFF, the size will be in the corresponding 8 byte zip64 end of central directory field.

As already noted in #2352, the 7zip author acknowledged this to be a bug in 7zip: https://sourceforge.net/p/sevenzip/discussion/45797/thread/cc8912f1/

@midluk
Copy link

midluk commented Jun 9, 2017

But 7zip does not seem to be the only software with problems. And just because you can max out the ZIP64 specification does not mean you have to. I don't see a good reason to insist on using the extended fields when the traditional fields are sufficient.
If you can work around the issues in ZipStreamer while not losing anything (except perhaps for your pride) and still producing valid zip files, you should do it.

@McNetic
Copy link
Owner

McNetic commented Jun 9, 2017

There's really no need to get personal. This is not about my pride. The Zip64 support in ZipStreamer was not even written by me.
Let me assure, if I knew a way to support files bigger than 4GB without the Zip64 extension, I would do so. If I knew a way to stream zip files on the fly without using the data descriptor and not setting the "traditional" fields, I would do so.

@radistmorse
Copy link

You may be actually wrong about being compliant to the spec. As far as I understand section 4.4.1.4, it says that you should put 0xffff only if the value is too big for the regular record.
But even if you're right, and this behaviour actually is correct, the spec doesn't require you to put f's there. You still can put normal value in both places, no-one will be hurt, and more unpackers will be happy. I just tested it by changing the line 528 to put the meaningful value there. p7zip was quite happy with the result.

@benbrummer
Copy link

benbrummer commented Jul 6, 2017

Looks like it is not a bug in 7z.

https://sourceforge.net/p/sevenzip/discussion/45797/thread/cc8912f1/

"That archive contains unused space in zip64 extra fields.
You can report about that problem to creators of that archive (Owncloud or someone else)."

Changing Line 528 to "$cdRecCount = min(sizeof($this->cdRec), 0xffff);" gets valid zips for 7z

@merlijn-sebrechts
Copy link

@McNetic

Just bumped into this too. I was quite surprised a zip archive created by Owncloud doesn't open on Ubuntu.

Do you see any issues with the following patch?

Changing Line 528 to $cdRecCount = min(sizeof($this->cdRec), 0xffff); gets valid zips for 7z

From my limited understanding, it seems as if this patch provides compatibility with 7z while still maintaining spec compliance. Is this correct or am I missing something?

@hanzei
Copy link

hanzei commented Aug 1, 2017

Changing Line 528 to $cdRecCount = min(sizeof($this->cdRec), 0xffff); gets valid zips for 7z

Tested on Ubuntu with different tools. Works fine!

@jreimone
Copy link

What is the current state on this issue?

@israel-lugo
Copy link

As per the 7z programmer's comment:

"That archive contains unused space in zip64 extra fields.
You can report about that problem to creators of that archive (Owncloud or someone else)."

It seems to me that perhaps the proposed patch is working around the problem, by not requiring the decompresser to go into the zip64 fields. That is, there may be an actual problem with the zip64 fields generated by PHPZipStreamer, at least according to the 7z programmer. However, I do not know the ZIP format myself, so I may be wrong.

@McNetic Would it be fair to assume that, at least for files < 4GB, the traditional size field can be used? Even if this is not the problem, it might be good to do it as a workaround, if it helps users deal with the vast majority of cases... (I'm assuming the vast majority of use cases don't involve huge multi-GB ZIP files).

DeepDiver1975 added a commit to DeepDiver1975/PHPZipStreamer that referenced this issue Sep 12, 2017
@DeepDiver1975
Copy link

PR is open ....

@glannes31
Copy link

Hello everyone, the project was abandonned? @DeepDiver1975 Your PR is in error ..

@DeepDiver1975
Copy link

Hello everyone, the project was abandonned? @DeepDiver1975 Your PR is in error ..

see #39 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests