SkillAgentSearch skills...

Zipper

[Lib][Version 3.0.1][Functional] C++14 wrapper around minizip compression library

Install / Use

/learn @Lecrapouille/Zipper
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Zipper

Zipper is a C++14 wrapper around the minizip compression library. Its goal is to bring the power and simplicity of minizip to a more object-oriented and C++ user-friendly library.

This project is a continuation of the original project. The original project was created out of the need for a compression library that would be reliable, simple, and flexible. By flexibility, we mean supporting various types of inputs and outputs, specifically the ability to compress into memory instead of being restricted to file compression only, and using data from memory instead of just files.

This current fork repository was created because the original project was no longer maintained by its authors, and I, Lecrapouille, encountered issues due to missing administrative rights (needed for CI, branch management, API breaking changes, etc.).

Zipper Features

  • [x] Create zip files in memory.
  • [x] Support for files, vectors, and generic streams as input for zipping.
  • [x] File mappings for replacement strategies (overwrite if exists or use alternative names from mapping).
  • [x] Password-protected zip (AES).
  • [x] Multi-platform support.
  • [x] Project compiles as both static and dynamic libraries.
  • [x] Protection flags against overwriting existing files during extraction.
  • [x] Protection against the Zip Slip attack.
  • [x] API to detect Zip Bomb attacks. Extraction is not recursive.
  • [x] Non-regression tests.

:warning: Security Notice

  • Zipper currently uses an outdated (and potentially vulnerable) version of minizip from 2017 (SHA1 0bb5afeb0d3f23149b086ccda7e4fee7d48f4fdf) with some custom modifications.

Getting Started

There are two ways to compile the project:

  • Makefile: This is the official compilation method but only supports Linux and macOS
  • CMake: Recently added, it supports all operating systems and was primarily added for Windows support

Compiling / Installing with Makefile (Linux, MacOs, not working for Windows)

This is the official way to download the project and compile it:

git clone https://github.com/lecrapouille/zipper.git --recursive
cd zipper
make download-external-libs
make compile-external-libs
make -j8

Explanations of compilation commands:

  • Git cloning requires the recursive option to install the Makefile helper and third-party libs (zlib and minizip) in the external folder. They are based on fixed SHA1. They are installed in the folder external.
  • Optionally make download-external-libs will git clone HEADs of third-party libs (zlib and minizip) in the external folder. It is optional since it was initially used instead of git submodule.
  • make compile-external-libs will compile third-party libs (zlib and minizip) but not install them on your operating system. They are compiled as static libraries and merged into this library inside the build folder.
  • make will compile this library against the third-party libs (zlib and minizip). A build folder is created with two demos inside. Note: -j8 should be adapted to your number of CPU cores.

See the README file for using the demos. To run demos, you can run them:

cd build
./unzipper-demo -h
./zipper-demo -h

To install C++ header files, shared and static libraries on your operating system, type:

sudo make install

You will see a message like:

*** Installing: doc => /usr/share/Zipper/2.0.0/doc
*** Installing: libs => /usr/lib
*** Installing: pkg-config => /usr/lib/pkgconfig
*** Installing: headers => /usr/include/Zipper-2.0.0
*** Installing: Zipper => /usr/include/Zipper-2.0.0

For developers, you can run non regression tests. They depend on:

make tests -j8

Compiling / Installing with CMake (Linux, MacOs, Windows)

As an alternative, you can also build the project using CMake:

git clone https://github.com/lecrapouille/zipper.git --recursive
cd zipper
mkdir build
cd build
cmake .. -DZIPPER_SHARED_LIB=ON -DZIPPER_BUILD_DEMOS=ON -DZIPPER_BUILD_TESTS=ON
# Either:
cmake --build . --config Release
# Or: make -j8

Optional options:

  • -DZIPPER_SHARED_LIB=ON allows creating a shared lib instead of static lib.
  • -DZIPPER_BUILD_DEMOS=ON allows compiling zipper and unzipper "hello world" demos.
  • -DZIPPER_BUILD_TESTS=ON allows compiling unit tests (if you are a developer).

Linking Zipper to your project

  • In your project, add the needed headers in your C++ files:
#include <Zipper/Unzipper.hpp>
#include <Zipper/Zipper.hpp>
  • To compile your project "as it" against Zipper, the simplest way is to use the pkg-config command:
g++ -W -Wall --std=c++14 main.cpp -o prog `pkg-config zipper --cflags --libs`
  • For Makefile:

    • set LDFLAGS to pkg-config zipper --libs
    • set CPPFLAGS to pkg-config zipper --cflags
  • For CMake:

find_package(zipper REQUIRED)
target_link_libraries(your_application zipper::zipper)

You have an example doc/demos/CMakeHelloWorld.

API

There are two classes available: Zipper and Unzipper. They behave in the same manner regarding constructors and storage parameters.

Zipping API

Header

#include <Zipper/Zipper.hpp>
using namespace zipper;

Constructor

  • Constructor without password and replace ziptest.zip if already present. The new zip archive is empty. The flag Zipper::OpenFlags::Overwrite is optional.
Zipper zipper("ziptest.zip", Zipper::OpenFlags::Overwrite);
  • Constructor without password and preserve ziptest.zip if already present. The flag Zipper::OpenFlags::Append is mandatory!
Zipper zipper("ziptest.zip", Zipper::OpenFlags::Append);
  • Constructor with password (using AES algorithm) and replace ziptest.zip if already present. The new zip archive is empty. The flag Zipper::OpenFlags::Overwrite is optional.
Zipper zipper("ziptest.zip", "my_password", Zipper::OpenFlags::Overwrite);
  • Constructor with a password and preserve ziptest.zip if already present. The flag Zipper::OpenFlags::Append is mandatory!
Zipper zipper("ziptest.zip", "my_password", Zipper::OpenFlags::Append);
  • Constructor for in-memory zip compression (storage inside std::iostream):
std::stringstream zipStream;
Zipper zipper(zipStream);
Zipper zipper(zipStream, Zipper::OpenFlags::Overwrite);
Zipper zipper(zipStream, Zipper::OpenFlags::Append);
Zipper zipper(zipStream, "my_password");
Zipper zipper(zipStream, "my_password", Zipper::OpenFlags::Overwrite);
Zipper zipper(zipStream, "my_password", Zipper::OpenFlags::Append);
  • Constructor for in-memory zip compression (storage inside std::vector):
std::vector<unsigned char> zipVector;
Zipper zipper(zipVector);
Zipper zipper(zipVector, Zipper::OpenFlags::Overwrite);
Zipper zipper(zipVector, Zipper::OpenFlags::Append);
Zipper zipper(zipVector, "my_password");
Zipper zipper(zipVector, "my_password", Zipper::OpenFlags::Overwrite);
Zipper zipper(zipVector, "my_password", Zipper::OpenFlags::Append);
  • Note: all constructors will throw a std::runtime_error exception in case of failure.
try
{
    Zipper zipper("ziptest.zip", ...);
    ...
}
catch (std::runtime_error const& e)
{
    std::cerr << e.what() << std::endl;
}
  • If this is not a desired behavior, you can choose the alternative dummy constructor followed by the open method which takes the same arguments as constructors. This method does not throw but will return false in case of error, you can get the reason by calling error().
// Dummy constructor
Zipper zipper;

// Same arguments than seen previously with constructors.
if (!zipper.open(...))
{
    std::cerr << zipper.error() << std::endl;
}

Closing / Reopening

Do not forget to call close() explicitly (it's called implicitly from the destructor) otherwise the zip will not be well-formed and Unzipper (or any unzipper application) will fail to open it, for example.

Zipper zipper("ziptest.zip", ...);
...
zipper.close(); // Now Unzipper unzipper("ziptest.zip") can work

After close() you can reopen the zip archive with open() without arguments. You can pass the same arguments than seen previously with constructors to open with new password or flags. Note: that any open method will call implicitly the close() method.

Zipper zipper("ziptest.zip", ...);
...
zipper.close();
...

zipper.open();
...
zipper.close();

Appending files or folders inside the archive

The add() method allows appending files or folders. The Zipper::ZipFlags::Better is set implicitly. Other options are (as the last argument):

  • Store only: Zipper::ZipFlags::Store.
  • Compress faster, less compressed: Zipper::ZipFlags::Faster.
  • Compress intermediate time/compression: Zipper::ZipFlags::Medium.
  • Compress better: Zipper::ZipFlags::Better.
  • To preserve directory hierarchy add | Zipper::ZipFlags::SaveHierarchy else files are only stored.

In case of success, the add() will return true; otherwise it will return false and error() should be used for getting the std::error_code.

  • Adding an entire folder to a zip:
Zipper zipper("ziptest.zip");
zipper.add("myFolder/");
zipper.close();
  • Adding a file by name:
Zipper zipper("ziptest.zip");
zipper.add("myFolder/somefile.txt");
zipper.close();
  • You can change their name in the archive:
Zipper zipper("ziptest.zip");
zipper.add("somefile.txt", "new_name_in_archive");
zipper.close();
  • Create a zip file with 2 files referred by their std::ifstream and change their name in the archive:
std:
View on GitHub
GitHub Stars96
CategoryDevelopment
Updated13d ago
Forks22

Languages

C++

Security Score

100/100

Audited on Mar 16, 2026

No findings