I try to create a compressed file and insert an xml file in it using two libraries (pugixml / libzip), everything goes without error, but when I open the xml file, the encoding at the beginning of the file is weird :
Main.cpp :
#include <iostream>
#include <sstream>
#include <zip.h>
#include <pugixml.hpp>
#include <memory>
using namespace std;
int main()
{
auto document = std::unique_ptr<pugi::xml_document>(new pugi::xml_document);
pugi::xml_node declNode = document->prepend_child(pugi::node_declaration);
declNode.append_attribute("version") = "1.0";
declNode.append_attribute("encoding") = "UTF-8";
declNode.append_attribute("standalone") = "yes";
pugi::xml_node rootNode = document->append_child("Document");
rootNode.append_child("Files");
int err = 0;
zip_t* zip = zip_open("test.zip", ZIP_CREATE, &err);
{
{
std::stringstream ss;
document->save(ss, " ");
std::string buffer = ss.str();
auto src = zip_source_buffer_create(buffer.c_str(),buffer.length(),0,0);
zip_file_add(zip,"Document.xml",src,ZIP_FL_ENC_UTF_8);
}
}
zip_close(zip);
return 0;
}
Document.xml :
~U Ä U rsion="1.0" encoding="UTF-8" standalone="yes"?>
<Document>
<Files />
</Document>

The posted program has undefined behaviour due to reading already freed memory.
In the example you posted the
zip_source_tgets creatd withfreep = 0, so you need to make sure that the provided buffer remains valid for the entire lifetime of thezip_source_tobject:zip_source_buffer
zip_file_add()(if successfull) will take ownership of the source you give it, but note that it is not required to free the source immediately - it could for example store it within thezip_t.As it is currently implemented
zip_file_add()does not free thezip_source_t- it instead hangs onto it and writes it out once you callzip_close(). So your buffer needs to remain valid for the entire remaining lifetime of thezip_tobject - in this case this is until the call tozip_close().If you rewrite your example to keep the
std::string buffer;alive until after you've closed thezip_tthe resulting file should be correct:Recommendation
There is no way to know how long the
zip_source_twill be alive (it's reference-counted), and so it's not easy to know for how long exactly you need to keep your buffer alive.So I would recommend allocating the memory for the
zip_source_tseparately withmalloc()and passingfreep=1tozip_source_buffer_create().That way the buffer will remain valid as long as the
zip_source_tis alive.