3

I use libzip to open zip files in my application and in order to ensure good behavior in case of corrupt zip files I manually corrupted a zip file (by removing a few random lines with a text editor) and try to load that file. However this hangs the entire app because zip_fread() never returns.

Is there a where to determine if a zip file is valid before loading it to avoid such situations?

Update

The behavior seems to depend on the version, so I probably only need to update. This is the code I use on Windows, Mac OS and Linux:

  int err;
  zip *z= zip_open(zipfile.c_str(), 0, &err);
  if (!z)
  {
    if (err == ZIP_ER_NOZIP)
      throw std::runtime_error("The file is not a Workbench document.");
    else if (err == ZIP_ER_MEMORY)
      throw grt::os_error("Cannot allocate enough memory to open document.");
    else if (err == ZIP_ER_NOENT)
      throw grt::os_error("File not found.");

    int len= zip_error_to_str(NULL, 0, 0, err);
    std::string msg;
    if (len > 0)
    {
      char *buf= (char*)g_malloc(len+1);
      zip_error_to_str(buf, len+1, 0, err);
      msg= buf;
      g_free(buf);
    }
    else
      msg= "error opening zip archive";

    zip_close(z);
    throw std::runtime_error(strfmt(_("Cannot open document file: %s"), msg.c_str()));
  }

On OS X this fragment does not return an error (I used the same file for all platforms). Instead the following zip_read() call just hangs. On the other platforms zip_read() immediately returns with a result < 0, so it's easy to catch the error there.

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181

0 Answers0