Releases: zombocoder/bfc
Release list
v1.4.0 — reader correctness fixes and usable Debug builds on macOS
Three correctness fixes in the reader, one of them security-relevant, plus build
changes that make Debug builds usable on current macOS.
Fixed
bfc_read returned ciphertext for encrypted, uncompressed entries. Decryption
only ever ran inside the compressed branch. Reading an encrypted entry that was
not compressed handed back the raw stored bytes and reported success, and because
the AEAD tag was never checked, a wrong key went unnoticed. Silent, and worse than
an error: callers had no way to tell the data was unusable.
bfc_list did not report encryption. It built its bfc_entry_t with a
designated initializer that omitted enc, so the field was silently zero and every
listed entry claimed BFC_ENC_NONE — while bfc_stat reported the truth for the
same entry.
bfc_verify(deep) reported corruption on healthy archives. It checksummed the
raw stored bytes against the checksum of the original content. For anything
compressed or encrypted those differ by definition, so deep verification failed on
every such archive, including ones the tool had just written itself. It also read
orig_size bytes where the stored object is obj_size, so for compressed entries
it could read past the object.
Entries stored as-is are still streamed and checksummed without being held in
memory. Compressed or encrypted entries are now decoded first. When an entry is
encrypted and no key has been supplied, verification returns BFC_E_PERM rather
than claiming corruption — it could not be checked, which is a different statement.
Build
Sanitizers are now separately controllable: BFC_ASAN and BFC_UBSAN, both
applying to Debug builds. AddressSanitizer defaults to off on macOS: as of
macOS 26 its runtime deadlocks inside its own initialisation — it calls into dyld,
dyld allocates, ASan intercepts that allocation and re-enters its initialiser, then
spins forever on a lock it already holds. Every binary built with
-fsanitize=address hangs before reaching main(), bfc --help included. This is
not specific to this project and a newer compiler-rt does not help.
UndefinedBehaviorSanitizer is unaffected and stays on. Re-enable with
cmake -DBFC_ASAN=ON once the platform is fixed.
Duplicate library linking removed. The CLI, tests, benchmarks and examples each
linked zstd and libsodium a second time on top of what bfc already propagates,
producing ld: warning: ignoring duplicate libraries on every link step. Builds are
now warning-free.
Version numbers agree. project(bfc VERSION ...) was still 1.0.0 while the tags
had reached 1.3.x, and bfc --version printed a hardcoded literal that had drifted
three minor versions behind. The CLI string now comes from the project version, so
bfc --version, bfc.pc and the shared library SOVERSION cannot diverge again.
Tests
Regression coverage for all three fixes: decryption of encrypted uncompressed
entries including rejection of a wrong key, agreement between bfc_list and
bfc_stat on compression and encryption, and deep verification across stored-as-is,
compressed, and encrypted-with-and-without-key cases. Each test was confirmed to
fail against the unfixed code before the fix landed.
v1.3.0 - Windows / MSVC Build Support
This release adds first-class Windows support (MSVC 2019+ and MinGW-w64), a unified cross-platform CI matrix, a Windows release artifact, and several correctness and security fixes uncovered along the way.
What's New
- Windows Build Support: BFC now builds and runs on Windows under MSVC 2019+ (cl.exe) and MinGW-w64
- Unified CI Matrix:
windows-latestadded to GitHub Actions alongside Linux and macOS, in both Debug and Release - Windows Release Artifact:
bfc-<version>-windows-x86_64.zippublished withbfc.exe,bfc.lib, optionalbfc.dll, headers, andinstall.bat - Windows Memory Mapping: Real
mmap/munmapimplementation viaCreateFileMapping/MapViewOfFile(previously stubbed) - Security: TOCTOU Hardening: Atomic
O_EXCL/O_NOFOLLOW/O_DIRECTORYopens replace prior stat-then-act patterns inextract_fileandextract_directory - Proper Monotonic Clock on Windows:
clock_gettime(CLOCK_MONOTONIC)shim now usesQueryPerformanceCounter - Clean MSVC Build: Compiles with
/W4 /WX(warnings as errors), zero warnings
Changes
Build System
- Add MSVC compiler block to
CMakeLists.txt(/W4 /WX /wd4996,_CRT_SECURE_NO_WARNINGS,/RTC1Debug,/O2 /DNDEBUGRelease) - Gate
-msse4.2 -mcrc32to non-MSVC; MSVC uses<intrin.h>intrinsics directly - Link
bcrypton Windows in place ofm(math is in the C runtime on Windows) - Move Linux-only
_GNU_SOURCEfrom per-file#defineto a singletarget_compile_definitionsguarded byCMAKE_SYSTEM_NAME STREQUAL "Linux" - Add Windows release packaging step (PowerShell-based ZIP creation with install.bat)
- Update CI workflow to use
aminya/setup-cpp@v1and vcpkg for Windows dependency management
New Compatibility Headers
src/lib/bfc_win32_compat.h— POSIX surface for the library:timespec,ssize_t,S_IF*/S_IS*/S_I[RWX]*,F_OK,usleep,clock_gettime, and macro mappings formkdir,fseeko/ftello,fileno,getpidsrc/cli/cli_win32_compat.h— CLI-level shim addingdirname(), adirent.h-equivalent overFindFirstFile,chdir → _chdir,lstat = stat,chmod → _chmod, and stubs forsymlink/lutimes/futimens/utimensat/fchmod
Library
bfc_os.c: real Windowsmmap/munmap;bfc_os_syncusesfsyncon macOS (wherefdatasyncis unreliable)bfc_crc32c.c: MSVC SSE4.2 detection via__cpuid; non-MSVC continues with__get_cpuid. Branching keyed on_MSC_VERso MinGW correctly takes the GCC pathbfc_reader.c: narrowing casts to satisfy MSVC C4244/C4267; innerresultshadow renamed toenc_errto kill C4456bfc_format.c/bfc_os.h: includebfc_win32_compat.hinstead of<windows.h>directly so all Windows includes flow through one header- Removed unused
bfc_iter.cplaceholder
CLI
cmd_extract.c: atomicopen(O_EXCL|O_NOFOLLOW)for files; atomicopen(O_DIRECTORY|O_NOFOLLOW)probe for directories on POSIXcmd_create.c: directory walk skips symlinks on Windows; uses the dirent shimcmd_verify.c: removed unusedverify_entry_callback(was dead code with MSVC C4505 / GCC__attribute__((unused))workarounds)
Tests
- All
/tmp/...paths replaced with relative paths so the suite runs from any working directory on Windows - File I/O uses
"wb"/"rb"andO_BINARYconsistently to avoid CRLF translation test_main.ccalls_CrtSetReportModeon Windows so failed asserts print to stderr instead of opening a modal dialog (which would hang CI)test_os.cexercises the new Windows mmap implementation- Pre-existing
assertbug intest_reader.c's symlink partial-read test fixed
Bug Fixes
- Eliminate stat+open TOCTOU race in
extract_directory(POSIX path) - Eliminate stat+open TOCTOU race in
extract_file - Fix
_GNU_SOURCEredefinition warnings on Linux glibc - Fix Windows Debug
test_encryptfailure caused by modal assert dialog hang - Apply
clang-formatconsistently to all C/H source files
Documentation
- Update README with Windows build instructions and prerequisites
- Document Windows symlink limitation (requires Developer Mode / not extracted by default)
- Mention FUSE mount is not supported on Windows
- Add Windows to the cross-platform support list
Platform Support
- Linux (tested)
- macOS (tested)
- FreeBSD 14.x (tested)
- Windows 10/11 with MSVC 2019+ (tested)
- Windows with MinGW-w64 (supported)
Installation on Windows
# Install dependencies via vcpkg
vcpkg install zstd:x64-windows libsodium:x64-windows
# Configure with vcpkg toolchain
cmake -B build `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
-DVCPKG_TARGET_TRIPLET=x64-windows `
-DBFC_WITH_ZSTD=ON `
-DBFC_WITH_SODIUM=ON
# Build
cmake --build build --config Release
# Run
.\build\bin\Release\bfc.exe create archive.bfc path\to\files\Or extract the prebuilt bfc-1.3.0-windows-x86_64.zip and run install.bat.
Tested On
- Windows 10 / Windows 11 with MSVC 19.x (Visual Studio 2019/2022)
- x86_64 architecture
- 10/10 unit tests passing under
ctest -C Debugandctest -C Release - Clean build under
/W4 /WX(zero warnings)
Known Limitations on Windows
- Symlinks: creation requires Developer Mode or elevated privileges; symlinks stored in containers are skipped (not extracted) on Windows
- FUSE mount (
BFC_WITH_FUSE): not supported on Windows
Compatibility
- No format changes. Containers produced or consumed by 1.3.0 are byte-identical to 1.2.2.
- Public API and ABI unchanged. Shared library SOVERSION is unaffected.
Contributors
Thanks to all contributors who helped bring BFC to Windows!
Full Changelog: v1.2.2...v1.3.0
v1.2.2 - FreeBSD Build Support and Bug Fixes
This release adds official FreeBSD build support and fixes several platform compatibility issues.
What's New
- ✅ FreeBSD Build Support: BFC now builds successfully on FreeBSD 14.x
- ✅ Hardware CRC32C on FreeBSD: Proper compiler flags for SSE4.2/CRC32 intrinsics
- ✅ Platform Detection: Support for FreeBSD's
amd64architecture identifier - ✅ API Bug Fix: Fixed encryption benchmark using incorrect reader API
Changes
Build System
- Add
-mcrc32compiler flag for CRC32 intrinsics on x86_64/amd64 - Detect FreeBSD's 'amd64' architecture (in addition to x86_64/AMD64)
- Switch from
set_source_files_propertiestotarget_compile_optionsfor better flag handling
Bug Fixes
- Fix unused parameter warning in
bfc_os_advise_nocache()on FreeBSD - Fix
benchmark_encrypt.cto use correctbfc_reader_set_encryption_password()API
Documentation
- Update README with FreeBSD installation instructions
- Add pkgconf dependency requirement for FreeBSD
- Mention FreeBSD in cross-platform support list
Platform Support
- ✅ Linux (tested)
- ✅ macOS (tested)
- ✅ FreeBSD 14.x (tested)
Installation on FreeBSD
# Install dependencies
sudo pkg install cmake pkgconf libzstd libsodium
# Build
cmake -B build -DCMAKE_BUILD_TYPE=Release -DBFC_WITH_ZSTD=ON -DBFC_WITH_SODIUM=ON
make -C build
# Install
sudo make -C build installTested On
- FreeBSD 14.3-RELEASE with Clang 19.1.7
- x86_64/amd64 architecture
- Hardware CRC32C acceleration verified working
Contributors
Thanks to all contributors who helped make BFC work on FreeBSD!
Full Changelog: v1.2.1...v1.2.2
v1.2.1 - Add comprehensive symlink support
What's New
Symlink Support
- Full symlink preservation: Create, extract, and list symbolic links with complete metadata preservation
- Cross-platform compatibility: Works on Unix-like systems (Linux, macOS, BSD)
- All symlink types supported: Relative paths, absolute paths, broken links, and directory links
- Integration with existing features: Symlinks work seamlessly with compression (ZSTD) and encryption (ChaCha20-Poly1305)
API Enhancements
- New
bfc_add_symlink()function for programmatic symlink creation - Enhanced CLI commands to handle symlinks across all operations (create, extract, list, info, verify)
- Proper symlink detection using
lstat()instead ofstat()
CLI Improvements
- Create command: Automatically detects and preserves symlinks during container creation
- Extract command: Restores symlinks with original targets and timestamps using
lutimes() - List command: Displays symlinks with 'l' prefix in file mode (e.g.,
lrwxrwxrwx) - Info command: Shows symlink count and type statistics
- Verify command: Validates symlink integrity and targets
Testing & Quality
- Comprehensive unit test coverage for both writer and reader functionality
- Integration tests covering all symlink scenarios
- CI/CD pipeline updated with symlink testing
- Cross-platform build fixes for Linux systems
Technical Details
- Symlink targets are stored as file content within the container format
- Uses existing
BFC_TYPE_SYMLINKobject type in the BFC format - Maintains backward compatibility with existing containers
- CRC32C validation ensures symlink target integrity
v1.2.0 - Bug Fix Release: CLI Extract Directory Option
🐛 Bug Fixes
Fixed -C Flag in Extract Command
- Issue: The
-C/--directoryoption inbfc extractcommand was failing with "I/O error" when using relative paths to container files - Root Cause: The CLI was changing to the output directory before opening the container file, breaking relative path resolution
- Fix: Reordered operations to open the container file before changing directories
- Impact: The
-Cflag now works correctly for extracting to specific directories
🔧 Technical Details
Problem
# This was failing with "I/O error"
bfc extract -C /tmp/output ../path/to/container.bfcThe issue occurred because:
- CLI parsed
-C /tmp/outputoption - Code executed
chdir("/tmp/output") - Code tried to open
../path/to/container.bfc(now relative to/tmp/output) - Container file not found, causing I/O error
Solution
- File:
src/cli/cmd_extract.c - Change: Moved container opening before directory change operation
- Security: Maintains proper error handling and cleanup
Before (Broken)
// Change directory first (BROKEN)
if (opts.output_dir) {
chdir(opts.output_dir); // Changes working directory
}
bfc_open(opts.container_file, &reader); // Relative path now brokenAfter (Fixed)
// Open container first (FIXED)
bfc_open(opts.container_file, &reader); // Works with original relative path
if (opts.output_dir) {
chdir(opts.output_dir); // Safe to change directory after opening
}✅ Testing
Verified fix works with various scenarios:
- Relative paths:
bfc extract -C /tmp ../container.bfc✅ - Absolute paths:
bfc extract -C /tmp /full/path/container.bfc✅ - Current directory:
bfc extract -C /tmp container.bfc✅ - All directory preservation options work:
-k,-f, etc. ✅
📋 Usage
The -C flag now works as documented:
# Extract all files to /tmp directory
bfc extract -C /tmp archive.bfc
# Extract preserving directory structure to specific location
bfc extract -k -C /tmp/restored archive.bfc
# Extract with force overwrite to specific directory
bfc extract -f -C /tmp archive.bfc🔄 Backward Compatibility
- No breaking changes: All existing functionality remains unchanged
- API compatibility: Library API unchanged - this is purely a CLI fix
- Container format: No changes to .bfc file format
📦 What's Changed
- Fixed CLI extract
-Cflag functionality insrc/cli/cmd_extract.c - No changes to library code, container format, or other features
- All tests pass, including new validation for the
-Cflag
This is a targeted bug fix release that resolves a specific issue with the CLI extraction functionality. Users who encountered the "I/O error" when using bfc extract -C should upgrade to this version.
v1.1.0 - Major Feature Release: Encryption & Compression Support + Enhanced Test Coverage
🔐 NEW: Full Encryption Support
- ChaCha20-Poly1305 AEAD encryption for secure file storage within BFC containers
- Argon2id key derivation from passwords for robust security
- Reader-specific encryption functions:
bfc_reader_set_encryption_password()andbfc_reader_set_encryption_key() - Encryption detection:
bfc_has_encryption()to check if containers use encryption - CLI integration: Password-based encryption/decryption support in command-line tools
- Encryption status display in container info summary
🗜️ NEW: Compression Support
- ZSTD compression integration for efficient file storage and reduced container sizes
- Configurable compression levels and thresholds for optimal performance
- Automatic compression/decompression handling in reader and writer APIs
- ZSTD streaming context support for large file processing
- Compression recommendations and performance optimizations
🧪 Comprehensive Test Coverage Improvements
- Enhanced overall line coverage from 74.5% to 78.6%, exceeding CI requirements
- Reader module coverage boost from 63.8% to 72.3% line coverage
- 800+ new test lines covering encryption, compression, and edge cases
- Robust edge case testing for malformed containers, corrupted data, and error conditions
- Parameter validation testing for all new encryption and compression APIs
- Integration testing for encryption + compression workflows
🔧 API Enhancements
- New encryption configuration APIs for both writer and reader contexts
- Compression configuration APIs with level and threshold controls
- Enhanced error handling with comprehensive validation across all functions
- Improved container verification with deep integrity checking
- Better CLI user experience with encryption status reporting
📊 Quality & Reliability Improvements
- CI/CD pipeline enhancements with proper coverage thresholds (75%)
- Extensive parameter validation for all new APIs
- Memory safety improvements in encryption and compression code paths
- Better error propagation and handling throughout the library
- Code formatting consistency and improved documentation
🚀 Performance & Security
- Hardware-accelerated encryption where available
- Efficient compression algorithms with streaming support
- Secure key management with proper cleanup and memory protection
- Optimized file I/O for compressed and encrypted content
- Minimal performance overhead for encryption/compression operations
📈 Development Experience
- Enhanced build system with optional dependency management
- Comprehensive examples for encryption and compression workflows
- Improved debugging support with better error messages
- Updated CI/CD workflows with artifact publishing permissions
Breaking Changes
Requirements
- Optional: libsodium for encryption support (
-DBFC_WITH_SODIUM=ON) - Optional: libzstd for compression support (
-DBFC_WITH_ZSTD=ON)
Summary
This major feature release transforms BFC from a basic container format into a comprehensive, secure, and efficient file archival solution with enterprise-grade encryption and compression capabilities.
BFC v1.0.0 - High-Performance Binary File Container
🚀 BFC v1.0.0 - Initial Release
We're excited to announce the first stable release of BFC (Binary File Container), a high-performance, single-file container format for storing files and directories with complete POSIX metadata preservation.
✨ Key Features
- Single-file containers - Everything stored in one
.bfcfile - POSIX metadata preservation - Full permissions, timestamps, and file types
- Fast random access - O(log N) file lookup with sorted index
- Integrity validation - CRC32C checksums with hardware acceleration
- Cross-platform support - Linux, macOS, and other Unix systems
- Crash-safe writes - Atomic container creation with index at EOF
- Memory efficient - Optimized for large containers and small memory footprint
📦 Installation
Linux
# Debian/Ubuntu
sudo dpkg -i bfc_1.0.0_x86_64.deb
# RHEL/Fedora/CentOS
sudo rpm -i bfc-1.0.0-1.x86_64.rpm
# Manual installation
tar -xzf bfc-1.0.0-linux-x86_64.tar.gz
cd bfc-1.0.0-linux-x86_64
sudo ./install.shmacOS
# Install from DMG (recommended)
# Download and mount bfc-1.0.0-macos-{arch}.dmg
# Drag BFC.app to Applications or run CLI installer
# Manual installation
tar -xzf bfc-1.0.0-macos-{arch}.tar.gz
cd bfc-1.0.0-macos-{arch}
sudo ./install.sh🔧 Quick Start
# Create a container
bfc create archive.bfc /path/to/files/
# List contents
bfc list archive.bfc
# Extract files
bfc extract archive.bfc
# Verify integrity
bfc verify --deep archive.bfc
# Get detailed information
bfc info archive.bfc📊 Performance Targets
- Write: ≥300 MB/s for 1 MiB files
- Read: ≥1 GB/s sequential, ≥50 MB/s random 4 KiB
- List: ≤1 ms for directories with ≤1024 entries
- Index load: ≤5 ms for 100K entries on NVMe SSD
🛡️ Security
- Path traversal prevention with strict normalization
- Safe extraction using
O_NOFOLLOWand parent directory validation - CRC32C validation on all read operations
- Bounds checking on all buffer operations
- No arbitrary code execution - pure data format
📚 Documentation
🏗️ Technical Details
- Language: C17
- Build System: CMake 3.10+
- Compiler: GCC 7+ or Clang 6+
- Dependencies: POSIX-compliant system
- Test Coverage: 80%+ lines, 98%+ functions
- Static Analysis: cppcheck + CodeQL integration
📋 What's Included
Linux Packages
bfc-1.0.0-linux-x86_64.tar.gz- Portable archivebfc_1.0.0_x86_64.deb- Debian/Ubuntu packagebfc-1.0.0-1.x86_64.rpm- RHEL/Fedora package
macOS Packages
bfc-1.0.0-macos-x86_64.tar.gz/.dmg- Intel Macbfc-1.0.0-macos-arm64.tar.gz/.dmg- Apple Silicon
Each package includes:
bfc- CLI toollibbfc.{a,so,dylib}- Static and shared librariesbfc.h- C API header- Installation scripts and documentation
🙏 Acknowledgments
Built with modern C17, CMake, and GitHub Actions CI/CD. Thanks to the open source community for tools and inspiration.
🐛 Reporting Issues
Found a bug? Please open an issue with:
- BFC version
- Operating system and version
- Steps to reproduce
- Expected vs actual behavior
Full Changelog: https://github.com/zombocoder/bfc/commits/v1.0.0