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

Check if file or stream is a valid "zip" archive #307

Closed
abrasat opened this issue Sep 7, 2023 · 10 comments · Fixed by #310
Closed

Check if file or stream is a valid "zip" archive #307

abrasat opened this issue Sep 7, 2023 · 10 comments · Fixed by #310
Labels
question Further information is requested

Comments

@abrasat
Copy link
Contributor

abrasat commented Sep 7, 2023

Is there any function available, that allows to check if a file or stream is a valid zip archive?

@abrasat abrasat changed the title Check if file or stream is a valid "zip" format Check if file or stream is a valid "zip" archive Sep 7, 2023
@kuba-- kuba-- added the question Further information is requested label Sep 7, 2023
@kuba--
Copy link
Owner

kuba-- commented Sep 7, 2023

Nothing public. Of course zip_open should fail, but mainly because miniz function mz_zip_reader_read_central_dir will fail.
So, if you need some workaround/shortcut, take a look into miniz.h mz_zip_reader_read_central_dir

@abrasat
Copy link
Contributor Author

abrasat commented Sep 7, 2023

Is there at least a "non" public function available, that checks the "End of central directory signature"?

@kuba--
Copy link
Owner

kuba-- commented Sep 7, 2023

You can take a look into static function in miniz.h (mz_zip_reader_locate_header_sig):
https://github.com/kuba--/zip/blob/master/src/miniz.h#L5449

and how it's used in mz_zip_reader_read_central_dir:

 if (!mz_zip_reader_locate_header_sig(
          pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG,
          MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
    return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);

  /* Read and verify the end of central directory record. */
  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf,
                    MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) !=
      MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)

@abrasat
Copy link
Contributor Author

abrasat commented Sep 7, 2023

Thanks, I will take a look. Not sure if a separate function with the zip validity check can be extracted from the code

@abrasat
Copy link
Contributor Author

abrasat commented Sep 8, 2023

Maybe it would be a good idea to add an "archive_corrupted" boolean flag in "struct zip_t". it would be set if zip_open() or zip_stream_open() fails, instead of returning a null zip_t pointer. The caller of the function could then check the "m_last_error" value in zip_t->mz_zip_archive.
Alternatively some new function zip_check_open (zip_stream_check_open) could be added.

@kuba--
Copy link
Owner

kuba-- commented Sep 8, 2023

Make sense, I think adding a new function which gonna set an error (like most of functions in our API) is the best approach.

kuba-- added a commit that referenced this issue Sep 24, 2023
@kuba--
Copy link
Owner

kuba-- commented Sep 24, 2023

@abrasat I've pushed PR: https://github.com/kuba--/zip/pull/309
where I added:

int zip_noallocopen(struct zip_t **zip, const char *zipname, int level, char mode);

The function requires pre-allocated zip and returns < 0 on error.

Right now, zip_open is basically wrapper on top of zip_noallocopen:

struct zip_t *zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t));
if (zip_noallocopen(&zip, zipname, level, mode) < 0) {
    CLEANUP(zip);
    return NULL;
}

Take a look, test it and let me know if it works for you.

@abrasat
Copy link
Contributor Author

abrasat commented Sep 26, 2023

Thanks. Would be possible to forward the zip_noallocopen() error code to zip_open? Maybe add an new zip_open_extended function:

struct zip_t *zip_open_extended(const char *zipname, int level, char mode, int* errorCode) {
  struct zip_t *zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t));
  *errorCode = zip_noallocopen(&zip, zipname, level, mode);
  if (*errorCode < 0) {
    CLEANUP(zip);
    return NULL;
  }
  return zip;
}

And please add also the same error check for the zip_stream_open() function

@kuba--
Copy link
Owner

kuba-- commented Sep 27, 2023

Yep, I'll add zip_stream_noallocopen in the similar way. But frankly speaking, having these noalloc version I do not see the point to add yet another wrapper to the API. I hope it's not a lot of work to write own extended function (maybe with more error handling stuff)

@kuba--
Copy link
Owner

kuba-- commented Sep 30, 2023

@abrasat - I closed the previous PR, because I realized it's not usable (you cannot preallocate anonymous struct).
So, I've just sent a new one (https://github.com/kuba--/zip/pull/310), which most likely works better for you.
PTAL.

@kuba-- kuba-- linked a pull request Sep 30, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants