简体   繁体   中英

libzip with zip_source_buffer causes data corruption and/or segfaults

I am trying to use libzip with zip_source_buffer , to write data from local buffers to a zipfile.

std::vector<uchar> buf;
struct zip * z = zip_open(zipfilename.c_str(),ZIP_CREATE | ZIP_EXCL,NULL);
if (!z) {
    messagelabel->setText("failed to open zip file "+QString::fromStdString(zipfilename));
    return "";
}
//messagelabel->setText(QString::fromStdString(zipfilename));
//messagelabel->setText(QString::number(ulong(z)));
int errors = 0;
for (int i=0;i<16;i++) {
    imencode(format, frame[i],buf);
    struct zip_source *s;
    s = zip_source_buffer(z,buf.data(),buf.size(),0);
    std::string nameinzip = ("band"+to_string(i)+format);
    if (zip_add(z,nameinzip.c_str(),s) < 0) {
            messagelabel->setText("failed to add "+QString::fromStdString(nameinzip)+" to zip file");
            errors++;
            break;
    }
}
if (errors == 0) {
    struct zip_source *s;
    std::string caltext = caltotext(calfile);
    cout << caltext;
    s = zip_source_buffer(z,caltext.data(),caltext.size(),0);
    std::string nameinzip = "calinfo.csv";
    if (zip_add(z,nameinzip.c_str(),s) < 0) {
            messagelabel->setText("failed to add "+QString::fromStdString(nameinzip)+" to zip file");
            errors++;
    }
}
if (zip_close(z) < 0) {
    messagelabel->setText("failed to close zip file "+QString::fromStdString(zipfilename));
    errors++;
}

Unfortunately, I discovered corrupt data inside my zip file and while trying to debug the results my program segfaulted in apparently unrelated code (that had worked before).

I then tried running my program in valgrind and got memory errors from zip_close . What am I doing wrong?

It seems that the libzip documentation is misleading, zip_add does not actually read the data from the source and put it in the zip, it merely queues it up to be put in the zip. So each of the buffers must be independent and you must ensure it's lifetime will last until after the zip is closed.

In this case that meant changing buf from a single std::vector to an array of std::vectors (one for each image) and moving the declarations of caltext out to a higher scope.

The segfault in unrelated code turned out to be an unrelated bug (an array was too small).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM