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

UNZ_BADZIPFILE due to incorrect offset of central directory record #44

Closed
chenxiaolong opened this issue Jan 24, 2016 · 6 comments
Closed
Labels
1.2 Related to older version of minizip 1.2 fixed Issue or bug has been fixed zip ZIP file format

Comments

@chenxiaolong
Copy link

A user of my DualBootPatcher project, which uses minizip, let me know that this particular zip file was having trouble being opened: https://drive.google.com/file/d/0B3vBKWqY-uX-QkdCd3BpQ1F1Yzg/view (I apologize for the large file size. I don't know how the file was created, so I couldn't create a smaller sample file.)

I did some digging and it seems that minizip might not be calculating the correct offset of the central directory record. Looking at the output of zipinfo, the central directory should be at 968,265,440 bytes: https://gist.github.com/chenxiaolong/22961396f606118c49d4 However, minizip is seeking to 968,265,516 bytes and failing because the central directory magic doesn't match.

From unz64local_GetCurrentFileInfoInternal in unzip.c, it appears that s->pos_in_central_dir already has the correct offset and s->byte_before_the_zipfile might be throwing the value off.

Any ideas why this might be happening?

Thanks in advance!


I just added a few printf's to see what minizip is doing:

    printf("s->pos_in_central_dir:      %lld\n", s->pos_in_central_dir);
    printf("s->byte_before_the_zipfile: %lld\n", s->byte_before_the_zipfile);
    if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,
            s->pos_in_central_dir + s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
        err = UNZ_ERRNO;

    /* Check the magic */
    if (err == UNZ_OK)
    {
        if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uMagic) != UNZ_OK)
            err = UNZ_ERRNO;
        else if (uMagic != CENTRALHEADERMAGIC) {
            printf("Expected: 0x%08x\n", CENTRALHEADERMAGIC);
            printf("Actual:   0x%08x\n", uMagic);
            err = UNZ_BADZIPFILE;
        }
    }

Output:

s->pos_in_central_dir:      968265440
s->byte_before_the_zipfile: 76
Expected: 0x02014b50
Actual:   0xdf08077f
@chenxiaolong
Copy link
Author

Is there any way I could help to resolve this issue? Thanks!

@nmoinvaz
Copy link
Member

It appears to be a problem with the ZIP64 end of central directory headers. Normally if those ZIP64 headers exists, then certain values in the non-ZIP64 central directory are set to 0xffffffff.

See unzip.c line ~ 461: ((us.gi.number_entry == 0xffff) || (us.size_central_dir == 0xffff) || (us.offset_central_dir == 0xffffffff))).

In this particular archive however, it does not set those values.

@nmoinvaz
Copy link
Member

I have modified minizip to look for the ZIP64 end of central directory regardless of those values.

chenxiaolong pushed a commit to chenxiaolong/DualBootPatcher that referenced this issue Feb 20, 2016
@chenxiaolong
Copy link
Author

Thank you very much for fixing this!

@nmoinvaz nmoinvaz added 1.2 Related to older version of minizip 1.2 fixed Issue or bug has been fixed zip ZIP file format labels Apr 19, 2019
@reyhan-sadak
Copy link

Hello, I have a problem opening the file in the link:
https://drive.mobisystems.com/sharelink/714xQfiNQl3XH9nsYc5iWL2CU0oVTqBmEsnf4ez8fpth
I call unzOpen2_64() and in unzOpenInternal() unz64local_SearchCentralDir64() returns 0.
I tried to debug it and it seems that the reason is that the central dir position is not found:
if (uPosFound == 0)
return 0;

@nmoinvaz
Copy link
Member

Please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.2 Related to older version of minizip 1.2 fixed Issue or bug has been fixed zip ZIP file format
Projects
None yet
Development

No branches or pull requests

3 participants