Files
vdm/core/CMakeLists.txt
T
samiandClaude Sonnet 5 092e99f7a0 core: meta/veloxpart — resume sidecar, reader first + fuzzed (stage 5)
util/crc32.hpp — header-only CRC-32 (zlib polynomial, reflected), used to
integrity-check the sidecar.

meta/veloxpart — the <name>.veloxpart.meta resume file (docs/04 §5).
Little-endian, versioned, CRC-32 over the whole record. Layout: magic,
version, flags, total_size, downloaded, url set (original/effective/
mirrors), etag/last-modified/content-type, segment records (start, end
INCLUSIVE, completed), optional sha256 streaming-hash blob.

parse_veloxpart() is the attacker-facing surface (the file sits in a
world-writable-ish download dir) and is total on any byte string: CRC
checked before any field is interpreted; magic, a version it understands,
every count and length bounded by a hard cap AND checked against the
remaining buffer; ByteReader latches on overrun; trailing bytes rejected.
Every malformation is meta_corrupt / meta_version_unsupported, never a
crash or an unbounded allocation. serialize_veloxpart() is deterministic
(unchanged sidecar isn't rewritten). File helpers write atomically
(temp + rename) and fdatasync the file and its directory.

Tests: crc32 known vector; full + minimal round-trips; deterministic
serialize; file round-trip; and a truncation/corruption table — bad
magic, CRC mismatch (payload and CRC-field flips), future version,
truncation at every stage, hostile url_count / segment_count / lp_string
length (the case the brief singles out), trailing bytes, impossible
segment.completed.

tools/fuzz/fuzz_veloxpart — feeds raw bytes and bytes-with-valid-CRC
(so the field parser and ByteReader bounds checks are actually reached),
and round-trip-stability-checks anything accepted. Ran 1.1M execs clean
under ASan+UBSan+libFuzzer (clang++-21); fuzz_content_disposition and
fuzz_url likewise re-run to 1.1M. tools/fuzz gains a -runs=0 seed-replay
CTest smoke per target (regression tripwire; the campaign stays manual).

Fuzz-found and fixed: parse_content_disposition could emit a filename
containing NUL / control bytes from a mangled filename* ext-value —
strip_path only removed path separators. Now sanitize_leaf() also drops
C0 controls and DEL (rules/ still owns the authoritative sanitize; `..`
and printable-unsafe content pass through as before).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HPPSGhiArbvQgwC2DNiURS
2026-09-10 13:52:34 +04:00

77 lines
3.1 KiB
CMake

# core/ produces TWO targets (ADR 0009):
# veloxcore — the download engine. No JSON, no SQL, no Qt, no RPC. Ever (CLAUDE.md §3).
# veloxproto — the generated wire types, which ARE JSON. NOT linked by veloxcore.
# The `no JSON in core/` rule constrains core/src/ and core/include/; core/generated/ is
# the sanctioned exception. Wired in by PKG via add_subdirectory(core) in the root file.
find_package(Threads REQUIRED)
find_package(CURL 8.0 REQUIRED)
add_library(veloxcore STATIC
src/util/error.cpp
src/util/log.cpp
src/util/thread_pool.cpp
src/net/curl_error.cpp
src/net/http_client.cpp
src/net/text_codec.cpp
src/net/content_disposition.cpp
src/net/url.cpp
src/net/probe.cpp
src/io/sparse_file.cpp
src/io/write_buffer.cpp
src/meta/veloxpart.cpp
)
add_library(velox::core ALIAS veloxcore)
target_include_directories(veloxcore
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src # net/*.cpp -> "net/curl_error.hpp"
)
target_compile_features(veloxcore PUBLIC cxx_std_23)
# Warnings are set at target scope, not via CMAKE_CXX_FLAGS: the dev/tsan presets
# overwrite that cache variable wholesale (see core/docs/pkg-requests-m1.md P4).
target_compile_options(veloxcore PRIVATE
-Wall -Wextra -Wpedantic -Werror
)
target_link_libraries(veloxcore PUBLIC Threads::Threads CURL::libcurl)
# Later stages add: find_package(OpenSSL) for meta/ (streaming SHA-256 + resume CRC).
# --- libveloxproto — generated wire code (ADR 0009) --------------------------------------
# Its own target so libveloxcore stays JSON-free. Consumed by veloxd, the CLI, the GUI and
# the conformance runner. The root CMakeLists only find_package(nlohmann_json)'s when
# daemon/ has landed, so find it here too — this must build even if core is the only lane.
if(NOT TARGET nlohmann_json::nlohmann_json)
find_package(nlohmann_json 3.11 REQUIRED)
endif()
add_library(veloxproto STATIC generated/velox_proto.cpp)
add_library(velox::proto ALIAS veloxproto)
target_include_directories(veloxproto PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/generated)
target_compile_features(veloxproto PUBLIC cxx_std_23)
target_link_libraries(veloxproto PUBLIC nlohmann_json::nlohmann_json)
# Generated code is committed and never hand-edited (CLAUDE.md §2); do not fail the build
# on a codegen quirk that trips -Werror. Warnings stay on for visibility.
target_compile_options(veloxproto PRIVATE -Wall -Wextra -Wno-error)
# A build-time tripwire for the split ADR 0009 exists to protect: veloxcore must never end
# up linking veloxproto.
get_target_property(_core_links veloxcore LINK_LIBRARIES)
if(_core_links AND "veloxproto" IN_LIST _core_links)
message(FATAL_ERROR "veloxcore links veloxproto — ADR 0009 violation (engine sees JSON).")
endif()
if(VELOX_BUILD_TESTS)
add_subdirectory(tests)
endif()
# Fuzz targets live in ${CMAKE_SOURCE_DIR}/tools/fuzz (lane CORE) and are wired in by the
# top-level CMakeLists.txt, which add_subdirectory()s every tools/* with a CMakeLists.
# tools/fuzz/CMakeLists.txt self-guards on VELOX_BUILD_FUZZ + a Clang compiler.
# Present: Content-Disposition, URL (stage 3). Coming: .veloxpart.meta (stage 5).