c++c++17libzip

libzip zip_source_t buffer is freed even tho I told libzip not to


I face an issue with libzip and I don't know if I did something wrong of if it's a bug in the library.

First I create an archive with zip_source_buffer_create() from a zip file on disk (don't ask why I don't open the file directly).

I set the freep flag to 0 which is supposed to mean I will handle the buffer freeing myself and it's not lipzip's job.

It works if I don't add a file to the archive.

If I add a file to the archive, when I delete the buffer libzip has already free'd it and my application crashes. Is that a bug in the library ?

I wrote this self-explanatory mcve. With AUTO_FREE_BUF=0 and ADD_FILE=1, the application crashes. Every other (3) cases work.

libzip version: 1.7.3

#include <zip.h>
#include <string>
#include <filesystem>
#include <fstream>
#include <iostream>

#define AUTO_FREE_BUF 0 //1-0
#define ADD_FILE 1 //1-0

int main(int argc, char** argv) {

    const std::string add_file = "file.txt";
    const std::string zip_file = "zipfile.zip";

    size_t sz = std::filesystem::file_size(zip_file);
    char* buf = new char[sz];
    {
        std::ifstream ifs{ zip_file, std::ios::binary };
        ifs.read(buf, sz);
        ifs.close();

        zip_error_t ze;
        zip_error_init(&ze);
        zip_source_t* zs = zip_source_buffer_create(buf, sz, AUTO_FREE_BUF, &ze);
        if (zs == nullptr) {
            zip_error_fini(&ze);
            return -1;
        }

        zip_error_init(&ze);
        zip_t* z = zip_open_from_source(zs, NULL, &ze);
        if (z == nullptr) {
            zip_error_fini(&ze);
            return -1;
        }
#if ADD_FILE == 1
        //add file
        {
            zip_source_t* file = zip_source_file(z, add_file.c_str(), 0, -1);
            if (file == nullptr)
                return -1;

            zip_int64_t add = zip_file_add(z, add_file.c_str(), file, ZIP_FL_ENC_GUESS);
            if (add == -1)
                return -1;
        }
#endif
        zip_error_fini(&ze);
        zip_source_keep(zs);
        int close = zip_close(z);
        if (close == -1)
            return -1;

        //write back archive to disk
        //..

#if AUTO_FREE_BUF == 1
        zip_source_free(zs);
#else
        zip_source_free(zs); //<-is supposed to NOT free the buffer (with freep=0) but sometimes does
        delete[] buf;
#endif
    }

    return 0;
}

Solution

  • Don't handle zip archives created with WinRar with libzip............... (create them with libzip)