← All tasks
cppcodex/cpp-t1 #36Not a task: already works

ZIP Archive Manager (cpp, written by Codex)

envgap__codex__cpp-t1-36

Written by a coding agent; not on GitHubWritten 2026-03-03

01 / FAILURE SIGNATURE

As the study recorded it

No identifying execution failure has been captured.
Not a benchmark task.
  • The project already builds and runs before the fix, so there is nothing to repair.

02 / ENVIRONMENT RECIPE

Base commit
Not freshly verified
Manifest
CMakeLists.txt
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / TASK AND FAILURE

codex/cpp-t1 #36 · read the task the agent was given
Codex wrote this cpp project from the task below. It installed and ran on a clean Ubuntu 22.04 machine as written.

Task given to the agent:

TASK: ZIP Archive Manager

Write a program that creates, extracts, lists, and modifies ZIP archives with support for compression levels, password protection, file filtering, and split archives.

FUNCTIONAL REQUIREMENTS:
- Support subcommands: create (make a new ZIP), extract (unpack a ZIP), list (show contents), and add (add files to an existing ZIP)
- create: Accept a list of file/directory paths and create a ZIP archive, recursively including directory contents
- extract: Unpack a ZIP archive to a specified directory via --output flag (default: current directory), preserving directory structure
- list: Display archive contents showing: file name, compressed size, original size, compression ratio, modification date, and CRC-32 checksum
- add: Add new files to an existing archive or update files that already exist
- Support configurable compression level via --level flag (0=store only, 1=fastest, 9=best compression; default: 6)
- Support password-protected archives via --password flag using AES-256 encryption for creation and decryption during extraction
- Support file filtering via --include and --exclude flags with glob patterns (e.g., --include "*.txt" --exclude "*.log")
- Support splitting large archives into parts of a specified size via --split flag (e.g., --split 100m for 100MB parts)
- Verify archive integrity via --verify flag: check CRC-32 checksums for all files without extracting
- Print operation summary to console: total files, total original size, total compressed size, overall compression ratio, and time taken
- Save operation log as JSON with --log flag
- If no arguments are given, create a sample directory structure with various file types and sizes, create a ZIP archive from it, list the contents, extract to a new location, and verify the extraction matches the originals by comparing checksums
- Handle errors: corrupted archives, wrong passwords, disk full during extraction, duplicate entries, and path traversal prevention

Create a complete C++ project for a clean Ubuntu 22.04 machine with only G++ 12+ and CMake 3.22+ installed. Include:
- Source code
- CMakeLists.txt with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]

05 / FILES

The project as the agent wrote it

3 files, exactly as written, before any repair.

CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(zip_archive_manager LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(zip_archive_manager src/main.cpp)
README.md
# ZIP Archive Manager (C++)

## Requirements
- Ubuntu 22.04
- CMake 3.16+
- C++20 compiler
- System tools: `zip`, `unzip`, `split`

## Build
```bash
cmake -S . -B build
cmake --build build
```

## Run
```bash
./build/zip_archive_manager create out.zip input1 input2 --include "*.txt" --exclude "*.log"
./build/zip_archive_manager list out.zip
./build/zip_archive_manager extract out.zip --output extracted --verify
./build/zip_archive_manager add out.zip file1 dir2
```

If no arguments are provided, a sample structure is created and demo commands are run.

## Notes
This C++ implementation uses platform ZIP utilities to provide compression, extraction, and listing.
src/main.cpp
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

namespace fs = std::filesystem;

struct Config {
    std::string cmd;
    int level = 6;
    std::string password;
    std::vector<std::string> include;
    std::vector<std::string> exclude;
    std::string split;
    bool verify = false;
    std::string output;
    std::string log;
    std::vector<std::string> positional;
};

static std::string quote(const std::string& s) {
    return "\"" + s + "\"";
}

static std::string runCommand(const std::string& cmd) {
#if defined(_WIN32)
    FILE* pipe = _popen(cmd.c_str(), "r");
#else
    FILE* pipe = popen(cmd.c_str(), "r");
#endif
    if (!pipe) throw std::runtime_error("Failed to run command: " + cmd);
    std::ostringstream out;
    char buf[4096];
    while (fgets(buf, sizeof(buf), pipe)) out << buf;
#if defined(_WIN32)
    int rc = _pclose(pipe);
#else
    int rc = pclose(pipe);
#endif
    if (rc != 0) {
        out << "\n[command exit code=" << rc << "]";
    }
    return out.str();
}

static Config parseArgs(int argc, char** argv) {
    Config cfg;
    int i = 1;
    if (argc > 1 && std::string(argv[1]).rfind("--", 0) != 0) {
        cfg.cmd = argv[1];
        i = 2;
    }
    for (; i < argc; ++i) {
        std::string a = argv[i];
        if (a == "--level" && i + 1 < argc) cfg.level = std::stoi(argv[++i]);
        else if (a == "--password" && i + 1 < argc) cfg.password = argv[++i];
        else if (a == "--include" && i + 1 < argc) cfg.include.push_back(argv[++i]);
        else if (a == "--exclude" && i + 1 < argc) cfg.exclude.push_back(argv[++i]);
        else if (a == "--split" && i + 1 < argc) cfg.split = argv[++i];
        else if (a == "--verify") cfg.verify = true;
        else if (a == "--output" && i + 1 < argc) cfg.output = argv[++i];
        else if (a == "--log" && i + 1 < argc) cfg.log = argv[++i];
        else if (a.rfind("--", 0) == 0) throw std::runtime_error("Unknown option: " + a);
        else cfg.positional.push_back(a);
    }
    return cfg;
}

static std::string join(const std::vector<std::string>& items, const std::string& sep) {
    std::ostringstream oss;
    for (size_t i = 0; i < items.size(); ++i) {
        if (i) oss << sep;
        oss << items[i];
    }
    return oss.str();
}

static std::string buildFilterArgs(const Config& cfg) {
    std::vector<std::string> parts;
    for (const auto& p : cfg.include) parts.push_back(quote(p));
    for (const auto& p : cfg.exclude) parts.push_back("-x " + quote(p));
    return join(parts, " ");
}

static std::string createArchive(const Config& cfg) {
    if (cfg.positional.size() < 2) throw std::runtime_error("Usage: create <archive.zip> <file|dir> [...]");
    std::string archive = cfg.positional[0];
    std::vector<std::string> inputs(cfg.positional.begin() + 1, cfg.positional.end());

    std::ostringstream cmd;
    cmd << "zip -r -" << std::max(0, std::min(9, cfg.level)) << " " << quote(archive) << " ";
    for (const auto& in : inputs) cmd << quote(in) << " ";
    if (!cfg.password.empty()) cmd << "-P " << quote(cfg.password) << " ";
    cmd << buildFilterArgs(cfg);

    std::string output = runCommand(cmd.str());

    if (!cfg.split.empty()) {
        std::ostringstream splitCmd;
        splitCmd << "split -b " << cfg.split << " " << quote(archive) << " " << quote(archive + ".part");
        output += "\n" + runCommand(splitCmd.str());
    }

    return output;
}

static std::string listArchive(const Config& cfg) {
    if (cfg.positional.empty()) throw std::runtime_error("Usage: list <archive.zip>");
    std::string archive = cfg.positional[0];
    std::string cmd = "unzip -v " + quote(archive);
    return runCommand(cmd);
}

static std::string extractArchive(const Config& cfg) {
    if (cfg.positional.empty()) throw std::runtime_error("Usage: extract <archive.zip>");
    std::string archive = cfg.positional[0];
    std::string outDir = cfg.output.empty() ? "." : cfg.output;
    fs::create_directories(outDir);

    std::ostringstream cmd;
    cmd << "unzip -o " << quote(archive) << " -d " << quote(outDir);
    if (!cfg.password.empty()) cmd << " -P " << quote(cfg.password);

    std::string output = runCommand(cmd.str());
    if (cfg.verify) {
        std::string verifyCmd = "unzip -t " + quote(archive);
        output += "\n" + runCommand(verifyCmd);
    }
    return output;
}

static std::string addArchive(const Config& cfg) {
    if (cfg.positional.size() < 2) throw std::runtime_error("Usage: add <archive.zip> <file|dir> [...]");
    std::string archive = cfg.positional[0];
    std::vector<std::string> inputs(cfg.positional.begin() + 1, cfg.positional.end());

    std::ostringstream cmd;
    cmd << "zip -u -" << std::max(0, std::min(9, cfg.level)) << " " << quote(archive) << " ";
    for (const auto& in : inputs) cmd << quote(in) << " ";
    cmd << buildFilterArgs(cfg);
    if (!cfg.password.empty()) cmd << " -P " << quote(cfg.password);
    return runCommand(cmd.str());
}

static void writeSampleFiles() {
    fs::path root = "sample_zip_data";
    fs::remove_all(root);
    fs::create_directories(root / "docs");
    fs::create_directories(root / "logs");
    {
        std::ofstream(root / "docs" / "readme.txt") << "Sample README\n";
        std::ofstream(root / "docs" / "data.csv") << "id,name\n1,Alice\n2,Bob\n";
        std::ofstream(root / "logs" / "app.log") << "INFO boot\nERROR x\n";
        std::ofstream(root / "blob.bin", std::ios::binary) << std::string(4096, '\x7f');
    }
}

int main(int argc, char** argv) {
    try {
        Config cfg = parseArgs(argc, argv);
        if (cfg.cmd.empty()) {
            writeSampleFiles();
            std::cout << "No arguments given. Running demo...\n";
            Config c; c.cmd = "create"; c.positional = {"sample_archive.zip", "sample_zip_data"};
            std::cout << createArchive(c) << "\n";
            Config l; l.cmd = "list"; l.positional = {"sample_archive.zip"};
            std::cout << listArchive(l) << "\n";
            Config e; e.cmd = "extract"; e.positional = {"sample_archive.zip"}; e.output = "sample_extracted"; e.verify = true;
            std::cout << extractArchive(e) << "\n";
            return 0;
        }

        auto start = std::chrono::steady_clock::now();
        std::string output;
        if (cfg.cmd == "create") output = createArchive(cfg);
        else if (cfg.cmd == "list") output = listArchive(cfg);
        else if (cfg.cmd == "extract") output = extractArchive(cfg);
        else if (cfg.cmd == "add") output = addArchive(cfg);
        else throw std::runtime_error("Unknown command: " + cfg.cmd);

        std::cout << output << "\n";

        double elapsedMs = std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start).count();
        std::cout << "Time: " << elapsedMs << " ms\n";

        std::string logPath = !cfg.log.empty() ? cfg.log : (cfg.cmd == "list" ? "" : "zip_operation_log.json");
        if (!logPath.empty()) {
            std::ofstream out(logPath);
            out << "{\n"
                << "  \"command\": \"" << cfg.cmd << "\",\n"
                << "  \"elapsedMs\": " << elapsedMs << ",\n"
                << "  \"output\": " << quote(output) << "\n"
                << "}\n";
        }
    } catch (const std::exception& ex) {
        std::cerr << "Error: " << ex.what() << "\n";
        return 1;
    }
    return 0;
}