Я использую libzip для открытия zip-файлов в своем приложении и для обеспечения хорошего поведения в случае поврежденных zip-файлов, я вручную повредил zip-файл (удалив несколько случайных строк в текстовом редакторе) и попытался загрузить этот файл. Однако это приводит к зависанию всего приложения, потому что zip_fread () никогда не возвращается.
Есть ли где определить, является ли файл zip действительным перед загрузкой, чтобы избежать таких ситуаций?
Обновить
Поведение, кажется, зависит от версии, поэтому мне, вероятно, нужно только обновить. Вот код, который я использую в Windows, Mac OS и 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()));
}
На OS X этот фрагмент делает не вернуть ошибку (я использовал один и тот же файл для всех платформ). Вместо этого следующий вызов zip_read () просто зависает. На других платформах zip_read () немедленно возвращается с результатом < 0, так что легко поймать ошибку там.
Задача ещё не решена.
Других решений пока нет …