The M0 Spike E recorded that Cap'n Proto two-party RPC over an AF_UNIX socketpair stalled (server processed requests, responses never reached the client). Root cause, confirmed with a standalone reproduction: EzRpcServer(int fd, ...) expects a LISTENING socket and calls accept() on it; a socketpair end is already CONNECTED, so accept() fails with EINVAL and the bootstrap never completes. Fix: server side uses the low-level path — LowLevelAsyncIoProvider::wrapSocketFd(fd) + TwoPartyVatNetwork(SIDE_SERVER) + makeRpcServer(network, bootstrap). The client uses EzRpcClient(fd), which is designed for an already-connected socket. This is the production M2 transport shape. - spike/E_sandbox/DocumentProcess.cpp: low-level TwoPartyVatNetwork server over wrapSocketFd; serves DocumentProcess::Server capability with 16 MiB payload cap (ADR-0004 bidirectional trust boundary) - spike/E_sandbox/UIProcess.cpp: EzRpcClient(fd) + parse() RPC; validates every response field. ASan caught a use-after-free (ParseResult::Reader outliving its Response) — fixed by validating inside the Response scope (validates §7.2 sanitizers-from-day-one) - spike/E_sandbox/Sandbox.cpp: allow ioctl (FIONBIO) — KJ's wrapSocketFd sets non-blocking mode via ioctl; strace identified it as the denied syscall - spike/CMakeLists.txt: Cap'n Proto via pkg-config (the Debian CMake config hard-requires libatomic via a check that fails on x86-64 where it isn't needed); schema compiled with the capnp tool + --src-prefix - docs/spike-results/0004: record the resolution; gate still MET (1000/1000 under seccomp, ~58us avg; ASan-clean with sandbox disabled — ASan's pipe2 conflicts with the seccomp allow-list, an ASan-only artefact) |
||
|---|---|---|
| .gitea/workflows | ||
| LICENSES | ||
| ci | ||
| cmake | ||
| docs | ||
| packaging | ||
| spike | ||
| src | ||
| test | ||
| .clang-format | ||
| .clang-tidy | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .gitleaks.toml | ||
| .pre-commit-config.yaml | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| CODEOWNERS | ||
| CONTRIBUTING.md | ||
| README.md | ||
| REUSE.toml | ||
| SECURITY.md | ||
| TRADEMARK.md | ||
| vcpkg-configuration.json | ||
| vcpkg.json | ||
README.md
FreePDFEditor
A cross-platform native desktop PDF editor with a true WYSIWYG interface and full content editing: edit existing text with reflow, replace images, manipulate vector objects, plus annotations, forms, signatures, and page assembly.
- Stack: C++20, Qt 6.7 (Widgets shell, custom canvas), CMake, vcpkg.
- License: GPL-3.0-or-later (see
LICENSES/GPL-3.0-or-later.txt). Qt is dynamically linked under LGPL-3.0. - Targets: Windows 10+, macOS 12+ (Intel + Apple Silicon), Linux (X11/Wayland).
This repository contains the source and build infrastructure. The full engineering plan and
roadmap live in docs/plan.md; architecture decision records are under
docs/adr/.
Status
Pre-M0. This is the initial repository scaffold described in §14 of the plan: CMake + vcpkg skeleton, governance docs, CI matrix, packaging pipeline, an empty-window application shell, the pixel-diff harness scaffolding, and the Spike A (QPDF verbatim round-trip) harness. The feasibility spikes that gate the project run on top of this scaffolding.
Building
cmake --preset default
cmake --build --preset default
ctest --preset default
See CONTRIBUTING.md for the full build setup, gate matrix, and coding
standard.
Source control
All code is developed on the project Gitea instance at https://gitea.lm.je/ai-ad4/freepdfeditor
per docs/plan.md §13. See SECURITY.md for vulnerability reporting.