libzip не может закрыть файл

В настоящее время я использую libzip в программе на C ++ 11 для извлечения содержимого сжатого файла и сохранения его в структуре данных, которая также будет содержать метаданные, связанные с файлом.

Я использую текущий метод, чтобы взорвать ZIP-файл и получить содержимое каждого файла в нем:

void explodeArchive(const string& path, vector<ZipFileModel>& files) {
int error = 0;
zip *zip = zip_open(path.c_str(), 0, &error);
if (zip == nullptr) {
throw logic_error("Could not extract content of file " + path);
}
const zip_int64_t n_entries = zip_get_num_entries(zip, ZIP_FL_UNCHANGED);
for (zip_int64_t i = 0; i < n_entries; i++) {
const char *file_name = zip_get_name(zip, i, ZIP_FL_ENC_GUESS);
struct zip_stat st;
zip_stat_init(&st);
zip_stat(zip, file_name, ZIP_FL_NOCASE, &st);
char *content = new char[st.size];
std::cerr << file_name << std::endl;
zip_file *file = zip_fopen(zip, file_name, ZIP_FL_NOCASE);
const zip_int64_t did_read = zip_fread(file, content, st.size);
if (did_read <= 0) {
continue;
}
if (strlen(content) < st.size) {
LOG(WARNING)<< "File " << file_name << " is truncated.";
}
if (strlen(content) > st.size) {
content[st.size] = '\0';
}

ZipFileModel model;
model.name = string(file_name);
model.content = string(content);
model.order = -1;
files.push_back(model);

zip_fclose(file);
delete[] content;
}
zip_close(zip);
}

Моя проблема в том, что я получаю случайные ошибки сегментации, когда GDB указывает на zip_fclose(file);:

Program received signal SIGSEGV, Segmentation fault.
0x00000001001ef8a0 in zip_source_close (src=0x105001b00) at /Users/xxx/Projects/xxx/xxx/src/libzip/zip_source_close.c:48
48      (void)src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_CLOSE);

Какой лучший способ отладить это? Как я уже сказал, это происходит периодически, поэтому трудно точно определить причину.

0

Решение

Вы не закрываете zip_file, когда нечего читать.

Сначала вы открываете файл внутри:

zip_file *file = zip_fopen(zip, file_name, ZIP_FL_NOCASE);

Затем попробуйте прочитать что-нибудь:

  const zip_int64_t did_read = zip_fread(file, content, st.size);

и если нечего читать, продолжайте, и файл никогда не будет закрыт.

  if (did_read <= 0) {
continue;
}

Итак, просто добавьте:

if (did_read <= 0) {
zip_fclose(file);
continue;
}
1

Другие решения


По вопросам рекламы [email protected]