No description
  • Scheme 62.2%
  • Shell 15.6%
  • C 14.7%
  • Makefile 7.3%
  • Common Lisp 0.2%
Find a file
2026-07-30 15:46:54 -06:00
.builds ci: set umask 022 in package/verify tasks too (jerbuild creates group-writable cache dirs during pkg operations) 2026-07-22 13:10:57 -06:00
.jerboa Security hardening and release readiness 2026-06-23 10:50:42 -06:00
docs Resolve security audit findings 2026-07-11 17:22:32 -06:00
scripts Resolve security audit findings 2026-07-11 17:22:32 -06:00
src/jerboa-pcre2 Skip substring copy in pregexp-match for unanchored patterns 2026-07-22 15:49:02 -06:00
support Fail closed on match-limit exhaustion (P1 #28) 2026-07-21 18:01:45 -06:00
tests Skip substring copy in pregexp-match for unanchored patterns 2026-07-22 15:49:02 -06:00
.gitignore Security hardening and release readiness 2026-06-23 10:50:42 -06:00
AGENTS.md docs: remove jerboa-emacs restriction 2026-07-30 15:46:54 -06:00
jerboa_pcre2_shim.c Cache one match context per thread in the PCRE2 shim 2026-07-22 14:12:45 -06:00
jpkg.sexp Add jpkg packaging 2026-07-21 15:09:25 -06:00
LICENSE Switch to MIT license 2026-07-21 13:42:18 -06:00
Makefile build: add lint target 2026-07-21 11:56:17 -06:00
README.md Resolve security audit findings 2026-07-11 17:22:32 -06:00
SECURITY.md Resolve security audit findings 2026-07-11 17:22:32 -06:00

jerboa-pcre2

PCRE2 bindings for Jerboa.

Status: experimental. Treat this repository as a native FFI and hostile-input regular expression component until the release gates in SECURITY.md and docs/ffi-boundary.md are complete.

Requirements

  • Jerboa jerbuild
  • C compiler
  • libpcre2-8 development headers and library
  • pkg-config recommended

On Debian/Ubuntu:

sudo apt-get install build-essential pkg-config libpcre2-dev

Build And Test

make test
make native-sanitizer-test
make hostile-regex-corpus
make audit
make pcre2-advisory-check
make reproducibility-report
make target-evidence
make release-evidence

make test builds jerboa_pcre2_shim, transpiles the Jerboa libraries, and runs the PCRE2 regression, concurrent lifecycle, and native-loader policy tests. If jerbuild is not installed, the Makefile bootstraps the pinned Jerboa release into .jerboa/bin.

Dynamic development builds must explicitly set JERBOA_PCRE2_DEV_NATIVE=1 and set JERBOA_PCRE2_LIB to an absolute trusted directory containing jerboa_pcre2_shim.so or jerboa_pcre2_shim.dylib. Relative paths, symlinked directory components, unexpected owners, world-writable paths, disallowed group-writable paths, current-directory lookup, and bare-name lookup are rejected by the shared (std native-loader) policy. Explicit development mode permits group-write only for components owned by the same unprivileged user. Privileged processes ignore both development variables. Production builds should statically link the shim; statically linked hosts are detected from their registered PCRE2 shim symbol and do not need either environment variable.

make native-sanitizer-test runs UBSan everywhere and ASan/TSan on Linux. The current Apple sanitizer runtimes do not enter main reliably on this macOS release, so Darwin builds compile those instrumented binaries and print an explicit skip; Linux CI remains the required ASan/TSan execution gate.

make hostile-regex-corpus runs an expanded deterministic adversarial-pattern corpus under low PCRE2 match/depth limits and records fail-closed behavior for backtracking-heavy and quoted-literal shapes.

make audit records the PCRE2 version and native linkage for release notes. make release-evidence writes the local release artifact bundle under dist/release-evidence/, including toolchain identity, native linkage, a minimal SBOM manifest, hostile-regex corpus output, PCRE2 advisory status, source inputs, hashes, and a two-clean-build reproducibility report that also compares repeated corpus output.

Production support is blocked until make target-evidence records a marker-complete proof through JPCRE2_TARGET_PROOF_FILE; production release hosts should set JPCRE2_REQUIRE_TARGET_PROOF=1. The proof covers target PCRE2 advisory/linkage review, platform CVE/backport review, hostile-regex soak, downstream consumer integration, external regex/FFI review, and cross-platform smoke. It must not contain private pattern corpora, secrets, private paths, hostnames, or raw command output.

Usage

(import (jerboa-pcre2 pcre2))

(define rx (pcre2-compile "(?P<year>\\d{4})-(?P<month>\\d{2})"))
(define m (pcre2-search rx "Today is 2026-06"))

(pcre-match-group m 0)      ; => "2026-06"
(pcre-match-named m "year") ; => "2026"

(pcre2-release! rx)

PCRE2 is a backtracking engine. For untrusted patterns, set conservative match limits with (pcre2-set-match-limits! match-limit depth-limit) and use an admission/review step before running user-authored regular expressions. Compiled regex objects may be shared between threads: match data and substitution results are per operation, and pcre2-release! synchronizes with in-flight native calls. New calls fail after release.

API

Function Description
(pcre2-compile pattern [options] [jit?]) Compile a PCRE2 pattern
(pcre2-regex pattern keyword: value ...) Compile with named options
(pcre2-match rx subject [start]) Full anchored match
(pcre2-search rx subject [start]) Unanchored search
(pcre2-matches? rx subject [start]) Boolean search
(pcre-match-group m [n]) Return group string or #f
(pcre-match-named m name) Return named group
(pcre-match-positions m [n]) Return (start . end)
(pcre2-replace rx subject replacement [start] [extended?]) Replace first match
(pcre2-replace-all rx subject replacement [start] [extended?]) Replace all matches
(pcre2-find-all rx subject [start]) Return all match objects
(pcre2-extract rx subject [start]) Return matched strings
(pcre2-fold rx kons knil subject [start]) Fold over matches
(pcre2-split rx subject [limit]) Split by pattern
(pcre2-partition rx subject) Alternating non-match/match list
(pcre2-set-match-limits! match depth) Set per-thread PCRE2 match/depth limits
(pcre2-quote str) Escape metacharacters
(pcre2-release! rx) Free native resources

Pregexp-compatible helpers are also provided: pcre2-pregexp-match, pcre2-pregexp-match-positions, pcre2-pregexp-replace, pcre2-pregexp-replace*, and pcre2-pregexp-quote.

Security

See SECURITY.md, docs/ffi-boundary.md, docs/pcre2-advisory-review.md, and docs/release-evidence.md.