From 3af3f1a00c57d3bf7b90d770316a8f2114d9826c Mon Sep 17 00:00:00 2001 From: Easton97-Jens <66330090+Easton97-Jens@users.noreply.github.com> Date: Fri, 3 Apr 2026 12:06:25 +0200 Subject: [PATCH 1/3] doc: add C++20 migration assessment for libmodsecurity --- doc/cpp20-migration-assessment.md | 443 ++++++++++++++++++++++++++++++ 1 file changed, 443 insertions(+) create mode 100644 doc/cpp20-migration-assessment.md diff --git a/doc/cpp20-migration-assessment.md b/doc/cpp20-migration-assessment.md new file mode 100644 index 0000000000..c915dd5035 --- /dev/null +++ b/doc/cpp20-migration-assessment.md @@ -0,0 +1,443 @@ +# Bewertung: Migration von ModSecurity (libmodsecurity) von C++17 auf C++20 + +## 1. Executive Summary + +**Urteil:** **bedingt empfohlen**. + +### Wichtigste 5 Gründe +1. **Build-Systeme sind bereits explizit auf C++17 verdrahtet** (Autotools, Windows/CMake, vcbuild/Conan) – ein Flag-Wechsel ist nicht nur ein Compiler-Schalter, sondern ein koordinierter Toolchain-Wechsel über mehrere Pfade. +2. **Öffentliche C- und C++-API existieren parallel**, damit steigt das ABI/API-Risiko bei unkontrollierter Modernisierung, v. a. wenn öffentliche Header verändert werden. +3. **Plattform- und Paketierungsrealität** (Linux/macOS/Windows, optionale Dependencies, Distributionspakete) ist der dominante Risikofaktor, nicht fehlende C++20-Features. +4. **Einige C++20-Features bringen echten, sicherheitsrelevanten Mehrwert** (insb. `std::span`, `std::string_view`, `std::source_location`, gezielte `constexpr`), aber selektiv und nur mit harten Guardrails. +5. **Hochrisiko-Features (Modules, Coroutines, flächige Ranges/`std::format`)** liefern hier kurzfristig wenig Nutzen bei überproportionalem Build-/Portabilitäts- und Wartungsrisiko. + +### Zeithorizont +- **Kurzfristig (0–2 Monate):** Keine Vollmigration; erst CI-/Toolchain-Härtung + C++20-Compile-Probe ohne Feature-Rollout. +- **Mittelfristig (2–6 Monate):** Selektive C++20-Nutzung in internen, nicht-ABI-exponierten Pfaden. +- **Langfristig (6+ Monate):** C++20 als Default realistisch, wenn Distribution-/Consumer-Kompatibilität und Regressionen stabil nachgewiesen sind. + +--- + +## 2. Repository- und Architekturverständnis + +### Fakten aus dem Repository +- Projekt ist **libmodsecurity** als Bibliothek, getrennt von Connectoren; explizit als Bibliothekskern für verschiedene Webserver-Connectoren beschrieben. +- Quellstruktur zeigt große Kernbereiche: `src/` (Engine, Operatoren, Aktionen, Variablen, Parser, Collections), `headers/` (öffentliche API), `test/` (unit/regression/benchmark/fuzzer), `examples/`, `tools/`. +- Öffentliche API-Header liegen unter `headers/modsecurity/` und umfassen sowohl C++-Klassen-Header als auch C-API-Funktionen (`extern "C"`). +- Parser-Anteile sind klar vorhanden (`src/parser/*.yy`, `*.ll`, generierte `*.cc/*.hh`) plus optionale Parser-Generierung via Build-Option. +- Benchmark- und Optimierungs-Targets sind vorhanden (`test/benchmark/benchmark.cc`, `test/optimization/optimization.cc`). + +### Fundierte Annahmen +- Das Projekt ist **ABI-/API-sensitiv**, weil es als dynamische Bibliothek (`libmodsecurity`) von externen Connectoren konsumiert wird. +- Parser- und Regel-Engine-Pfade sind correctness-kritisch; kleine semantische Änderungen können funktionale/security-relevante Auswirkungen haben. + +### Besonders sensible Bereiche für Sprachstandardmigration +1. **Öffentliche Header** (`headers/modsecurity/*.h`) wegen API/ABI-Exposition. +2. **Transaktions- und Regelverarbeitung** (`src/transaction.cc`, `src/rules_set.cc`, Operator-/Action-Pfade) wegen Laufzeit- und Security-Semantik. +3. **Parser/Gene­rator-Pipeline** (`src/parser`) wegen Tool-Versionen, deterministischer Artefakt-Erzeugung und möglicher ABI-/Diagnostik-Unterschiede. +4. **Windows-Buildpfad (CMake+Conan+vcbuild)** wegen separater Toolchain-Logik gegenüber Autotools. + +--- + +## 3. Ist-Zustand der Toolchain + +### Fakten aus dem Repository +- **C++17 ist explizit erzwungen**: + - Autotools: `AX_CXX_COMPILE_STDCXX(17, noext, mandatory)`. + - Windows CMake: `set(CMAKE_CXX_STANDARD 17)`. + - `vcbuild.bat` setzt Conan-Profil mit `-s compiler.cppstd=17`. + - `cppcheck` wird mit `--std=c++17` gefahren. +- **Build-Systeme**: + - Unix/macOS: Autotools (`build.sh`, `configure`, `make`). + - Windows: CMake + Conan + Visual Studio 2022 via `vcbuild.bat`. +- **CI-Matrix** (zwei Workflows `ci.yml`, `ci_new.yml`): + - Linux GCC+Clang, macOS, Windows. + - Verschiedene Optional-Dependency-Kombinationen (`--without-*`, `--with-*`). + - 32-bit war im älteren Workflow noch teilweise enthalten, im neueren Linux-Workflow entfernt. + - Separate cppcheck-Jobs. +- **Plattform-/Dependency-Hinweise**: + - Viele optionale Dependencies (LUA, LMDB, libxml2, curl, maxmind, ssdeep, pcre/pcre2). + - Windows-Doku nennt VS2022 und Conan 2.x. + +### Bewertung C++20-Realismus +- **Technisch machbar**, da moderne CI-Umgebungen und VS2022 genutzt werden. +- **Operativ risikobehaftet**, weil C++17 hart in mehreren Build-Pfaden kodiert ist (Autotools+CMake+Conan+Static Analysis). +- Höchstes Risiko liegt **nicht im Core-Code allein**, sondern in: + - inkonsistenten Toolchain-Settings über Build-Systeme, + - Packager-/Distribution-Kompatibilität, + - unterschiedlichen Standardbibliotheksimplementierungen (libstdc++, libc++, MSVC STL). + +### Mögliche Probleme +- **GCC/Clang/MSVC Divergenzen** bei Corner Cases (Concepts, Ranges, `format`, constexpr-Auswertung, Diagnostics). +- **Windows/Conan-Profil** bleibt bei `cppstd=17`, wenn nicht bewusst migriert. +- **Distributionen** mit konservativen Toolchains könnten C++20-Baseline verzögern. +- **ABI-Nebenwirkungen** durch Header-Signaturen (z. B. `string_view`-Umstellungen in Public APIs). + +--- + +## 4. Detaillierte Nutzenanalyse von C++20 + +> Klassifikation: **hoher Nutzen / mittlerer Nutzen / geringer Nutzen / vermeiden** + +### `concepts` – **mittlerer Nutzen** +- **Sinnvoll wo:** interne Template-Utilities (falls vorhanden/neu), generische Hilfsfunktionen in `utils`/Parser-nahem Code. +- **Nutzen:** klarere Compile-Fehler, explizite Template-Verträge. +- **Risiko:** Compiler-Diagnostik-Uneinheitlichkeit, potenziell höhere Komplexität im Contributor-Onboarding. +- **Bewertung:** selektiv intern, nicht in breit genutzter Public API einführen. + +### `ranges` – **geringer bis mittlerer Nutzen** +- **Sinnvoll wo:** interne Datenaufbereitung, Filter-/Transform-Pipelines in nicht-hot Paths. +- **Nutzen:** Lesbarkeit bei klaren Pipelines. +- **Risiko:** Compile-Zeit, potenziell intransparente Performance, höhere Template-Komplexität. +- **Bewertung:** nur punktuell; in Hot Paths eher klassische Schleifen bevorzugen. + +### `std::span` – **hoher Nutzen** +- **Sinnvoll wo:** Buffer-/Body-/Header-Verarbeitung, Funktionen mit `(ptr, len)`-Signaturen. +- **Nutzen:** Bounds-semantik expliziter, API robuster, weniger Pointer+Längen-Fehler. +- **Risiko:** Public-API-Änderungen wären ABI/API-sensitiv. +- **Bewertung:** intern stark empfohlen; Public API nur mit sauberem Übergangspfad. + +### `std::string_view` – **hoher Nutzen (selektiv)** +- **Sinnvoll wo:** read-only String-Parameter in internen APIs. +- **Nutzen:** weniger unnötige Kopien, klarere Intent-Semantik. +- **Risiko:** Lifetime-Footguns, besonders gefährlich in Security-Code wenn Views persistiert werden. +- **Bewertung:** empfohlen mit strikten Review-Regeln (keine persistierten dangling views). + +### `std::format` – **geringer Nutzen / vorsichtig** +- **Sinnvoll wo:** Logging/Diagnostics. +- **Nutzen:** klarere Formatierung als Streams/printf-Mix. +- **Risiko:** historisch uneinheitliche STL-Unterstützung/Performance; Binärgröße. +- **Bewertung:** eher später prüfen; kein früher Migrations-Treiber. + +### `std::source_location` – **mittlerer bis hoher Nutzen** +- **Sinnvoll wo:** Debug-/Error-Logging, Assertions, Diagnosepfade. +- **Nutzen:** bessere Diagnostik ohne Makro-Overhead, schnellere Incident-Analyse. +- **Risiko:** geringe Portabilitätsrisiken bei modernen Compilern. +- **Bewertung:** empfohlen für interne Logging-Utilities. + +### Designated Initializers (C++20) – **geringer Nutzen** +- **Sinnvoll wo:** klar strukturierte POD-Initialisierung in Testcode. +- **Nutzen:** Lesbarkeit. +- **Risiko:** begrenzter realer Mehrwert; potenzielle Konsistenzprobleme mit C/C++-gemischten Strukturen. +- **Bewertung:** optional, niedrige Priorität. + +### `constexpr`-Erweiterungen – **mittlerer Nutzen** +- **Sinnvoll wo:** statische Tabellen, Token-/Mapping-Hilfen, kleine Parser-Hilfsfunktionen. +- **Nutzen:** potenziell weniger Runtime-Overhead, klarere Immutability. +- **Risiko:** Compile-Zeit-Anstieg, komplexeres Debugging. +- **Bewertung:** gezielt einsetzen. + +### `consteval` – **geringer Nutzen** +- **Sinnvoll wo:** sehr spezielle Compile-Time-Prüfungen. +- **Nutzen:** harte Compile-Time-Garantien. +- **Risiko:** unnötige Komplexität. +- **Bewertung:** derzeit vermeiden außer klarer Spezialfall. + +### Coroutines – **vermeiden** +- **Nutzen hier:** gering; ModSecurity-Kern ist nicht erkennbar coroutine-zentriert. +- **Risiko:** enorme Komplexitäts-/Debug-/Portabilitätskosten. +- **Bewertung:** nicht als Migrationsthema. + +### Modules – **vermeiden (vorerst)** +- **Nutzen:** potenziell Compile-Time langfristig. +- **Risiko:** inkompatibel mit bestehender Build-/Generator-/Ökosystemstruktur (Autotools, generated parser sources). +- **Bewertung:** klar später, nicht im C++17→20-Programm. + +### Calendar/Time Zone – **geringer Nutzen** +- **Sinnvoll wo:** Zeitvariablen/Logging. +- **Nutzen:** sauberere Zeitabstraktionen. +- **Risiko:** gering, aber wenig strategischer Hebel. +- **Bewertung:** optional. + +### Atomic smart pointers / Sync-Verbesserungen – **geringer bis mittlerer Nutzen** +- **Sinnvoll wo:** Shared-State/Log-Writer, falls contention-kritisch. +- **Nutzen:** sichere Patterns möglich. +- **Risiko:** keine gratis Performance; lock-free-Annahmen oft falsch. +- **Bewertung:** nur nach Profiling. + +### `[[likely]]` / `[[unlikely]]` – **geringer Nutzen** +- **Sinnvoll wo:** klar dominierte Branches in Hot Paths. +- **Nutzen:** ggf. Mikro-Optimierung. +- **Risiko:** falsch gesetzte Hinweise verschlechtern Performance. +- **Bewertung:** nur benchmarkgetrieben. + +### Dreiwegevergleich (`<=>`) – **geringer Nutzen** +- **Sinnvoll wo:** value types mit vielen Vergleichen. +- **Nutzen:** weniger Boilerplate. +- **Risiko:** API-/Semantikänderungen ohne großen Gewinn. +- **Bewertung:** niedrige Priorität. + +--- + +## 5. Risikoanalyse + +### a) Build-/Compiler-Risiko +- **Beschreibung:** inkonsistente C++-Standardumschaltung über Autotools/CMake/Conan/cppcheck. +- **Wahrscheinlichkeit:** hoch +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** zentraler Migrations-Check, alle Pfade auf C++20 umstellen, CI-Gate auf alle Build-Systeme. + +### b) ABI-/API-Risiko +- **Beschreibung:** Änderung öffentlicher Header-Signaturen (z. B. `string_view`, `span`) kann Consumer brechen. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** Public API freeze, ABI-Reports, C-API stabil halten, Adapter-Overloads statt Breaking Changes. + +### c) Plattform-Risiko +- **Beschreibung:** unterschiedliche Compiler/STL-Verhalten (Linux/macOS/Windows). +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** erweiterte Matrix, explizite Compiler-Minima, Plattform-spezifische Regression-Suites. + +### d) Dependency-Risiko +- **Beschreibung:** optionale Dependencies + Paketmanager (Conan, distro packages) können C++20-Kompatibilitätskanten haben. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** mittel-hoch +- **Gegenmaßnahmen:** Feature-Matrix je Dependency, known-good Versionen, Fallback-Pfade testen. + +### e) Test-/Regression-Risiko +- **Beschreibung:** Funktionale Regressions trotz erfolgreichem Build. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** volle Regression-Suite, Cross-OS-Tests, Parser-Roundtrip-/Golden-Tests. + +### f) Performance-Risiko +- **Beschreibung:** Modernisierung ohne Profiling kann compile time/binary size/runtime verschlechtern. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** mittel-hoch +- **Gegenmaßnahmen:** Benchmark-Baselines, Budget-Schwellen, Hot-path-Regeln. + +### g) Security-Risiko +- **Beschreibung:** neue Sprachmittel können neue Lifetime-/UB-Footguns freilegen (z. B. `string_view` dangling). +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** secure-coding-Guidelines für C++20, ASan/UBSan-Gates, gezielte Code-Reviews. + +### h) Contributor-/Maintainer-Risiko +- **Beschreibung:** höhere Komplexität bei stark template-lastigen Features. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** mittel +- **Gegenmaßnahmen:** Feature-Policy (was erlaubt/verboten), Stilguide, Reviewer-Checklisten. + +--- + +## 6. Codebasierte Migrationschancen + +### Geeignete Bereiche +- **String-/Buffer-Handhabung:** `std::span` intern für Body-/Header-Pfade. +- **Parsing-nahe Logik:** compile-time Konstanten/Tabellen via `constexpr` dort, wo stabil. +- **Container-Nutzung:** gezielte API-Signaturverbesserungen intern mit `string_view`. +- **Fehlerbehandlung/Diagnostics:** `source_location` in Logging/Debug-Makro-Ersatz. +- **Threading/Concurrency:** nur nach Nachweis von Contention. +- **Performance-Hot-Paths:** konservativ, benchmark-first. + +### Konkrete Refactoring-Muster +1. `const char* + size_t` → `std::span`/`std::span` (intern). +2. `const std::string&` (read-only) → `std::string_view` (intern, nicht persistieren). +3. Logging-Helfer um `std::source_location` ergänzen. +4. Template-Utilities mit `concepts` absichern (nur intern). +5. Kleine, häufige Utility-Funktionen auf `constexpr` prüfen. + +### Wo moderne Features eher schaden +- Flächige Einführung von Ranges in performance-kritischen Schleifen. +- Coroutines/Modules ohne harte Notwendigkeit. +- Public-Header-Umbau auf neue Typen ohne ABI-Plan. + +--- + +## 7. C++20-Feature-Matrix für ModSecurity + +| Feature | Potenzieller Einsatz im Projekt | Nutzen | Risiko | Migrationsaufwand | Empfehlung | +|---|---|---|---|---|---| +| `std::span` | Buffer-/Body-APIs intern | Hoch (Sicherheit/Lesbarkeit) | Mittel (API-Lifetime) | Mittel | **einführen** | +| `std::string_view` | Read-only String-Parameter intern | Hoch | Mittel (dangling) | Mittel | **einführen** | +| `std::source_location` | Logging/Diagnostics | Mittel-Hoch | Niedrig | Klein | **einführen** | +| `constexpr`-Erweiterungen | Tabellen/Utility | Mittel | Niedrig-Mittel | Klein-Mittel | **einführen** | +| `concepts` | Interne Templates | Mittel | Mittel | Mittel | **später prüfen** | +| `ranges` | Interne Transform-Pipelines | Mittel | Mittel-Hoch | Mittel | **später prüfen** | +| `std::format` | Logging/Textformat | Niedrig-Mittel | Mittel | Mittel | **später prüfen** | +| `[[likely]]`/`[[unlikely]]` | Hot-Path-Branches | Niedrig | Mittel (Fehlhint) | Klein | **später prüfen** | +| `<=>` | Value-type Vergleiche | Niedrig | Niedrig-Mittel | Klein | **später prüfen** | +| Designated Initializers | Test-/POD-Init | Niedrig | Niedrig | Klein | **später prüfen** | +| Coroutines | Async-Flow | Niedrig | Hoch | Groß | **vermeiden** | +| Modules | Build-Organisation | Niedrig (kurzfristig) | Hoch | Sehr groß | **vermeiden** | +| `consteval` | Spezial-Compile-Time Checks | Niedrig | Mittel | Mittel | **vermeiden** (vorerst) | +| Calendar/Time zone | Zeit-Handling | Niedrig | Niedrig | Klein-Mittel | **später prüfen** | + +--- + +## 8. Toolchain- und CI-Readiness + +### Zwingend vor Umstellung +1. C++20-Build in **allen** Build-Pfaden (Autotools, CMake/Windows, Conan profile, cppcheck mode). +2. Matrix mit GCC/Clang/MSVC in Debug+Release. +3. Sanitizer-Jobs (mind. Linux ASan+UBSan; TSan selektiv, da ggf. flaky/teuer). +4. Vollständige Unit+Regression-Suite auf Linux/macOS/Windows. +5. Optional-Dependency-Matrix (ON/OFF-Kombinationen der kritischen Features). +6. Benchmark-Vergleich als verpflichtendes Gate für definierte Hot Paths. + +### Ziel-CI-Matrix (Mindestziel) +- **Linux:** GCC (2 Versionen), Clang (2 Versionen), Debug+Release, ASan+UBSan, optional 32-bit wenn support-claim besteht. +- **macOS:** Apple Clang (mind. 2 Runner-Generationen), Debug+Release. +- **Windows:** VS2022 (MSVC), Debug+Release (+ ggf. RelWithDebInfo), ASan wo stabil. +- **Static Analysis:** cppcheck + optional clang-tidy-Subset. +- **Performance:** nightly benchmark job mit Baseline-Vergleich. + +--- + +## 9. Performance-Betrachtung + +### Erwartung +- **Compile Time:** tendenziell eher schlechter bei stärkerer Template-/Ranges-/Concepts-Nutzung. +- **Binary Size:** kann steigen (insb. generische Abstraktionen, `format`). +- **Runtime:** neutral bis leicht besser/schlechter je Refactoring; keine automatische Verbesserung durch C++20. +- **Memory Footprint:** meist neutral; abhängig von konkreten Datenstrukturen/APIs. + +> Moderne Syntax = **kein** automatischer Performancegewinn. + +### Benchmark-Designs +- **Zu messen:** + 1. End-to-end Transaction-Pfad (Request/Response-Phasen). + 2. Regel-Ladezeit + Parser-Durchsatz. + 3. Operator-lastige Pfade (Regex, String-Operatoren). + 4. Logging-/Audit-Overhead. +- **Baselines:** C++17-Release-Build als Referenz je Plattform/Compiler. +- **Regressionsschwellen (Vorschlag):** + - Runtime: >3% Verschlechterung = Blocker (Hot Paths). + - Binary size: >5% = Review erforderlich. + - Compile time: >10% = akzeptabel nur mit klarer Begründung. + +--- + +## 10. Security-Betrachtung + +### Potenzielle Sicherheitsgewinne +- `span` kann Boundaries expliziter machen und Pointer+Length-Fehler reduzieren. +- `string_view` kann unnötige Kopien reduzieren (weniger transienter Speicher), **wenn** Lifetimes korrekt bleiben. +- `source_location` verbessert Incident-Diagnostik und Forensik-Tiefe. + +### Potenzielle neue Risiken +- `string_view`/`span`-Lifetime-Missbrauch erzeugt subtile UAF-/Dangling-Probleme. +- Höhere Ausdrucksstärke (Ranges/Concepts) kann Review-Aufwand und Fehlerentdeckungszeit erhöhen. +- Toolchain-/Supply-Chain-Risiken steigen, wenn Mindestcompiler und Packaging nicht synchron angehoben werden. + +### Gesamtbewertung Security +- C++20 kann Sicherheit **selektiv real verbessern**, primär durch robustere API-Formen (`span`, disziplinierte `string_view`-Nutzung) und bessere Diagnostik. +- Ein pauschaler "Modernisierungsgewinn" ohne Governance ist sicherheitstechnisch nicht belastbar. + +--- + +## 11. Aufwandsschätzung + +| Teilbereich | Qualitativ | T-Shirt-Size | Kommentar | +|---|---|---|---| +| Voranalyse | mittel | M | API/ABI-Inventur, Consumer-Impact | +| Prototyping | mittel | M | C++20-Flag-only Builds + Smoke | +| CI-/Toolchain-Anpassung | groß | L | Mehrere Build-Systeme + Matrix | +| Code-Refactoring | mittel bis groß | M-L | Selektive, review-intensive Umstellungen | +| Testanpassung | mittel | M | Regression + neue Edge-Cases | +| Dokumentation | klein bis mittel | S-M | Build-Anforderungen, Policy | +| Release-/Packaging-Folgen | groß | L | Distro-/Conan-/Consumer-Kompatibilität | + +**Gesamt:** **groß (L)** für sichere, produktionsreife Migration. + +--- + +## 12. Migrationsstrategie + +### Phase 0: Assessment +- **Ziel:** belastbare Ist-Aufnahme (Toolchains, APIs, ABI). +- **Aufgaben:** API/ABI-Inventur, Consumer-Liste, Compiler-/Distro-Mindeststände dokumentieren. +- **Erfolg:** vollständige Kompatibilitätsmatrix + Risiko-Backlog. +- **Abbruchkriterien:** unbekannte kritische Consumer/Plattformanforderungen. +- **Risiken:** unterschätzte Downstream-Abhängigkeiten. + +### Phase 1: Toolchain/CI Readiness +- **Ziel:** C++20 buildbar in allen Pfaden. +- **Aufgaben:** Flags in Autotools/CMake/Conan/cppcheck auf C++20 umstellbar machen; Matrix erweitern; Sanitizer-Jobs. +- **Erfolg:** grünes CI in C++17 und C++20 parallel. +- **Abbruchkriterien:** reproduzierbare Plattformfehler ohne kurzfristigen Fix. +- **Risiken:** Windows-/Conan-Drift, flaky Tests. + +### Phase 2: Build-Flag-Umstellung ohne Feature-Nutzung +- **Ziel:** Sprachstandardwechsel als Infrastrukturänderung isolieren. +- **Aufgaben:** Default auf C++20, Code semantisch unverändert; Regression+Benchmark. +- **Erfolg:** keine signifikanten Regressionen, ABI stabil. +- **Abbruchkriterien:** Performance-/ABI-Regressions über Schwelle. +- **Risiken:** versteckte Verhaltensänderungen durch Compiler/STL. + +### Phase 3: Selektive C++20-Nutzung (geringes Risiko) +- **Ziel:** sichere Quick Wins. +- **Aufgaben:** intern `span`, `string_view` (regelbasiert), `source_location`; keine Public ABI-Brüche. +- **Erfolg:** messbare Qualität/Diagnostikgewinne, keine neuen Crashes. +- **Abbruchkriterien:** Lifetime-Bugs, erhöhte Incident-Rate. +- **Risiken:** inkonsistente Coding-Patterns. + +### Phase 4: Gezielte Refactorings +- **Ziel:** strukturelle Verbesserungen in ausgewählten Modulen. +- **Aufgaben:** benchmark-gesteuerte Hot-Path-Optimierungen, ggf. `constexpr`/Concepts punktuell. +- **Erfolg:** Performance mindestens parity, Wartbarkeit steigt. +- **Abbruchkriterien:** Compile-time/Binary-size explodiert, Review-Stau. +- **Risiken:** Over-engineering. + +### Phase 5: Release-Härtung +- **Ziel:** releasefähige Migration inklusive Downstream-Sicherheit. +- **Aufgaben:** Release-Candidates, Packaging-Tests, Migrationshinweise, Fallback-Plan. +- **Erfolg:** stabile RC-Zyklen ohne kritische Regressions. +- **Abbruchkriterien:** kritische Consumer-Inkompatibilitäten. +- **Risiken:** unterschätzte Distributionseffekte. + +--- + +## 13. Empfehlung für Maintainer + +**Empfehlung:** **erst CI/Compiler modernisieren, dann umstellen**. + +Technisch-pragmatische Begründung: +1. Aktuell ist C++17 in mehreren Build-Ebenen fest verankert; ein isolierter Codewechsel reicht nicht. +2. Sicherheitskritischer Bibliothekscharakter verlangt konservative, regressionsarme Migration. +3. Höchster Hebel liegt in Toolchain- und Qualitäts-Gates, nicht in frühzeitiger Feature-Adoption. +4. Selektive C++20-Nutzung liefert den besten Nutzen-Risiko-Quotienten. + +--- + +## 14. Konkrete nächste Schritte (Top 15) + +1. **Build-/Toolchain-Inventur finalisieren** – Priorität: hoch – Nutzen: klare Entscheidungsbasis. +2. **C++20-Schalter in allen Buildsystemen parametrisieren** – hoch – verhindert Drift. +3. **Dual-Standard-CI (C++17 + C++20) temporär einführen** – hoch – risikoarme Transition. +4. **Windows `vcbuild.bat`/Conan auf umschaltbares `cppstd` erweitern** – hoch – plattformparität. +5. **cppcheck-Konfiguration C++20-fähig machen** – hoch – statische Analyse konsistent. +6. **Compiler-/Runner-Minimalversionen dokumentieren** – hoch – klare Support-Grenzen. +7. **Sanitizer-Gates (ASan/UBSan) für C++20 verpflichtend machen** – hoch – Security-Härtung. +8. **ABI-Check-Workflow etablieren** – hoch – Public-API-Schutz. +9. **Performance-Baselines je Plattform erfassen** – hoch – objektive Regressionserkennung. +10. **Policy für erlaubte C++20-Features definieren** – mittel-hoch – verhindert Overuse. +11. **Pilot-Refactor in internem Modul (`span`/`string_view`)** – mittel – schneller Nutzenbeweis. +12. **Review-Checkliste für Lifetime-/UB-Risiken ergänzen** – mittel-hoch – weniger Security-Footguns. +13. **Public-Header-Freeze während Initialmigration** – mittel-hoch – ABI-Sicherheit. +14. **Downstream/Connector-Feedback-Runde vor Default-Switch** – mittel – Integrationssicherheit. +15. **Release-Plan mit Stop/Go-Gates publizieren** – hoch – transparente Steuerung. + +--- + +## Abschluss + +**A) Gesamturteil in einem Satz:** +Eine Migration auf C++20 ist für ModSecurity **sinnvoll, aber nur schrittweise und toolchain-getrieben**, nicht als schnelle Vollmodernisierung. + +**B) Risikoampel:** +- **Build/Toolchain:** 🔴 +- **ABI/API:** 🟠 +- **Plattform/Packaging:** 🔴 +- **Performance:** 🟠 +- **Security (bei disziplinierter Einführung):** 🟠 → 🟢 + +**C) Was ich als Maintainer morgen tun würde:** +Ich würde sofort eine **C++20-Shadow-CI** (parallel zu C++17) aufsetzen, alle Buildpfade umschaltbar machen und erst danach einen kleinen internen `span`/`string_view`-Pilot mergen. + +**D) Was auf keinen Fall vorschnell getan werden sollte:** +1. Public Header ohne ABI-Plan auf neue Typen umstellen. +2. Coroutines/Modules als Modernisierungsziel aufnehmen. +3. C++20 als Default setzen, bevor Windows/Conan und Distribution-Story stabil sind. +4. Performance-/Security-Baselines vor der Umstellung nicht messen. From ac2d7de1213a0a887dcf2531ed85bc9d30a97082 Mon Sep 17 00:00:00 2001 From: Easton97-Jens <66330090+Easton97-Jens@users.noreply.github.com> Date: Fri, 3 Apr 2026 19:48:19 +0200 Subject: [PATCH 2/3] doc: add C++23 follow-up migration assessment --- doc/cpp23-follow-up-assessment.md | 515 ++++++++++++++++++++++++++++++ 1 file changed, 515 insertions(+) create mode 100644 doc/cpp23-follow-up-assessment.md diff --git a/doc/cpp23-follow-up-assessment.md b/doc/cpp23-follow-up-assessment.md new file mode 100644 index 0000000000..d9fd890216 --- /dev/null +++ b/doc/cpp23-follow-up-assessment.md @@ -0,0 +1,515 @@ +# Anschlussanalyse: C++23 nach/zusätzlich zu C++20 für ModSecurity (libmodsecurity) + +## 1. Executive Summary + +**Urteil:** **bedingt empfohlen**. + +### 5 wichtigste Gründe +1. **C++20 liefert bereits den Großteil des realen Nutzens** für dieses Repository (API-Robustheit, Diagnostics, selektive Modernisierung) – C++23 ist überwiegend Feintuning, nicht strategischer Hebel. +2. **Für ein plattformübergreifendes Security-Projekt ist C++23-Feature-Reife uneinheitlich** (insb. Sprachmodus vs. Standardbibliotheks-Reife vs. Packaging). +3. **"Mit `-std=c++23` bauen" ist nicht gleichbedeutend mit "C++23 aktiv nutzen"**; letzteres erhöht Review-, Portabilitäts- und ABI-Risiken deutlich. +4. **Einige C++23-Features sind wertvoll (v. a. `std::expected`, `std::to_underlying`, `std::byteswap`, `std::unreachable`)**, aber nur selektiv in internen Pfaden. +5. **Die größten Hürden bleiben Toolchain/CI/Distributionen und ABI/API-Governance**, nicht fehlende Sprachfeatures. + +### Klare Aussage +- **Reicht C++20 aus?** Ja, für den Großteil der operativen und sicherheitsrelevanten Verbesserungen. +- **Bringt C++23 echten Zusatznutzen?** Ja, aber punktuell (vor allem Fehlerpfad-Modellierung via `expected` und einige Utility-Features). +- **Ist C++23 eher Toolchain-Experiment oder praxisreifer Mehrwert?** Für ModSecurity aktuell **primär Toolchain-Experiment mit selektiven produktiven Inseln**. + +--- + +## 2. Einordnung relativ zu C++20 + +### Was C++20 bereits ausreichend abdeckt +- Robuste API-Muster (`span`, `string_view`) und bessere Diagnostik (`source_location`) als Hauptgewinn. +- Solide Grundlage für inkrementelle Refactorings ohne exotische Sprachexperimente. +- Gute Balance aus Lesbarkeit, Performance-Kontrolle und Toolchain-Verfügbarkeit. + +### Welche Probleme nach C++20 noch offen bleiben +- Explizite, typisierte Fehlerketten statt verstreuter Fehlercodes/Status-Werte. +- Teilweise uneinheitliche API-Verträge zwischen C-/C++-Grenzen. +- Weitere Reduktion von Utility-Boilerplate in Low-level-Code. + +### Welche davon C++23 sinnvoll verbessern könnte +- `std::expected` (inkl. monadischer Operationen) für explizitere Fehlerpfade. +- Kleine Sicherheits-/Klarheitsgewinne mit `to_underlying`, `byteswap`, `unreachable`. +- Gewisse Standardbibliotheksverbesserungen (z. B. constexpr-Erweiterungen) selektiv. + +### Unrealistische Erwartungen an C++23 +- Kein automatischer Performancegewinn. +- Kein "einfaches" Ende von Komplexität in Parser-/Regel-Engine-Pfaden. +- Keine kurzfristig robuste Baseline für alle Distributionen/Toolchains nur durch Sprachmodus-Wechsel. + +--- + +## 3. Toolchain- und Plattform-Reife für C++23 + +> Entscheidender Punkt: **Compiler-Sprachmodus** und **Standardbibliotheks-Feature-Reife** müssen getrennt bewertet werden. + +### GCC / libstdc++ +- Sprachmodus `-std=c++23` ist vorhanden; GCC selbst kennzeichnet C++23-Support weiterhin als "experimental" in seiner Statusdarstellung. +- libstdc++ dokumentiert C++23-Bibliotheksfeatures fortlaufend; Reife ist featureweise unterschiedlich und nicht als einheitlicher "alles fertig"-Zustand zu interpretieren. +- Für Maintainer heißt das: Feature-Test-Makros und konkrete Compiler-/Lib-Versionen sind Pflicht. + +### Clang / libc++ +- Clang führt C++23 als "partial" und listet Feature-Stand proposalweise. +- libc++ führt einen sehr granularen C++23-Status pro Feature/Paper, inkl. "Complete"/"In Progress". +- Praktisch: einige Features sind gut nutzbar, andere hängen von exakter Clang+libc++-Kombination ab. + +### MSVC / Windows +- In den offiziellen Optionen ist C++23 als `/std:c++23preview` beschrieben; explizit mit Hinweis auf Preview-/ABI-Themen. +- Zusätzlich bleibt `/std:c++latest` als Sammelschalter für fortlaufende Features. +- Für ein Security-Projekt ist das ein klares Signal: C++23 auf Windows nur kontrolliert/experimentell als Baseline. + +### Unix/Autotools, CI-Matrix, Distributionen +- Im Repository sind Autotools/CMake/Conan/cppcheck derzeit auf C++17 zentriert; C++20 ist bereits ein eigener Migrationsschritt. +- C++23 als Baseline setzt voraus: C++20 bereits stabil auf Linux/macOS/Windows + tragfähige CI + Packaging-Abstimmung. +- Distributionen liefern häufig konservative Compiler-/STL-Kombinationen; C++23-Featureeinsatz kann dort schneller brechen als der reine Sprachmodus. + +### Tragfähigkeit als Baseline heute +- **Als projektweite Baseline für ein plattformübergreifendes Security-Projekt: derzeit nur bedingt tragfähig.** +- **Als zusätzlicher Build-Modus (experimentell) plus selektive Feature-Nutzung: realistisch.** + +--- + +## 4. Detaillierte C++23-Feature-Bewertung für dieses Repository + +### 4.1 `std::expected` (+ monadic operations) +- **Einsatz:** interne Fehlerpfade in Parser-/Rule-Load-/IO-nahen APIs. +- **Nutzen:** explizite, typisierte Fehlerbehandlung; weniger versteckte Kontrollflüsse. +- **Risiken:** API-Drift, wenn in öffentlichen Headern unkontrolliert eingeführt. +- **Portabilität/Reife:** mittel (abhängig von STL-Version). +- **Aufwand:** mittel. +- **Empfehlung:** **mittlerer bis hoher Nutzen**, selektiv intern einführen. + +### 4.2 `if consteval` +- **Einsatz:** Compile-Time-Utilities/Meta-Helfer (falls nötig). +- **Nutzen:** sauberere compile-time branching-Semantik. +- **Risiken:** begrenzter Mehrwert für Kernlogik. +- **Reife:** gut in modernen Compilern. +- **Aufwand:** klein. +- **Empfehlung:** **geringer Nutzen**. + +### 4.3 deducing this / explicit object parameter +- **Einsatz:** API-Design für member-/fluent-orientierte Utilities. +- **Nutzen:** potenziell elegantere Overload-Strukturen. +- **Risiken:** deutlich höhere Verständniskosten für Contributor. +- **Reife:** uneinheitlich in Toolchains. +- **Aufwand:** mittel bis groß. +- **Empfehlung:** **vermeiden** (vorerst). + +### 4.4 multidimensional subscript operator +- **Einsatz:** nur relevant bei mehrdimensionalen Datenstrukturen. +- **Nutzen:** für ModSecurity gering. +- **Risiken:** praktisch kein ROI. +- **Reife:** mittel. +- **Aufwand:** klein. +- **Empfehlung:** **geringer Nutzen**. + +### 4.5 static `operator()` / static `operator[]` +- **Einsatz:** spezielle Functor-/Proxy-Muster. +- **Nutzen:** niedrig im Projektkontext. +- **Risiken:** Lesbarkeits-/Style-Kosten ohne echten Gewinn. +- **Reife:** mittel. +- **Aufwand:** klein. +- **Empfehlung:** **vermeiden**. + +### 4.6 size_t literal suffix (`z` / `uz`) +- **Einsatz:** klarere Literal-Typisierung in Low-level-Code. +- **Nutzen:** kleine Correctness-/Lesbarkeitsgewinne. +- **Risiken:** minimal. +- **Reife:** gut. +- **Aufwand:** klein. +- **Empfehlung:** **geringer Nutzen**. + +### 4.7 constexpr-Erweiterungen in der Standardbibliothek +- **Einsatz:** statische Tabellen/Hilfsroutinen. +- **Nutzen:** potenziell bessere Immutability/Precomputation. +- **Risiken:** compile-time-Kosten. +- **Reife:** featureabhängig. +- **Aufwand:** klein bis mittel. +- **Empfehlung:** **mittlerer Nutzen** (gezielt). + +### 4.8 neue string/ranges/view-Verbesserungen +- **Einsatz:** interne Transform-/Parsing-Hilfen. +- **Nutzen:** bessere Ausdruckskraft. +- **Risiken:** template-bedingte Komplexität, mögliche Runtime-Unklarheit. +- **Reife:** unterschiedlich je STL. +- **Aufwand:** mittel. +- **Empfehlung:** **geringer bis mittlerer Nutzen**, sparsam. + +### 4.9 print/formatting-nahe Verbesserungen (`print`) +- **Einsatz:** Logging/CLI-Tools/Tests. +- **Nutzen:** komfortabelere Ausgabe. +- **Risiken:** Verfügbarkeits-/ABI-/Binary-Size-Themen je STL. +- **Reife:** uneinheitlich. +- **Aufwand:** klein bis mittel. +- **Empfehlung:** **noch nicht reif genug** als Standardansatz. + +### 4.10 `stacktrace` +- **Einsatz:** Diagnostik bei Fehlerfällen. +- **Nutzen:** forensischer Mehrwert theoretisch hoch. +- **Risiken:** sehr uneinheitliche Plattform-/Toolchain-Reife. +- **Reife:** niedrig bis mittel. +- **Aufwand:** mittel. +- **Empfehlung:** **noch nicht reif genug**. + +### 4.11 `mdspan` +- **Einsatz:** nur relevant bei numerischen/mehrdimensionalen Speicherlayouts. +- **Nutzen:** im ModSecurity-Kern gering. +- **Risiken:** zusätzliche Abstraktion ohne klaren Bedarf. +- **Reife:** unterschiedlich. +- **Aufwand:** mittel. +- **Empfehlung:** **vermeiden**. + +### 4.12 `flat_map` / `flat_set` +- **Einsatz:** read-heavy, cache-freundliche Lookups in ausgewählten Pfaden. +- **Nutzen:** potenziell Performance in speziellen Workloads. +- **Risiken:** Reife/Verfügbarkeit abhängig von STL-Stand. +- **Reife:** noch nicht durchgängig als sichere Basis. +- **Aufwand:** mittel. +- **Empfehlung:** **noch nicht reif genug** (pilotierbar nur lokal). + +### 4.13 `std::to_underlying` +- **Einsatz:** enum→Integer-Konvertierungen in Flags/Bitmask/Interops. +- **Nutzen:** safer than casts, weniger Boilerplate. +- **Risiken:** minimal. +- **Reife:** gut. +- **Aufwand:** klein. +- **Empfehlung:** **mittlerer Nutzen**. + +### 4.14 `std::unreachable` +- **Einsatz:** intern an nachweislich unerreichbaren Stellen. +- **Nutzen:** Optimierungshinweis + explizite Invariante. +- **Risiken:** UB-Footgun bei falscher Nutzung. +- **Reife:** gut. +- **Aufwand:** klein. +- **Empfehlung:** **mittlerer Nutzen** mit strikter Policy. + +### 4.15 `std::byteswap` +- **Einsatz:** Netzwerk-/Endian-Konvertierungen in Utils/Parsernähe. +- **Nutzen:** klarere, portable Low-level-Operation. +- **Risiken:** minimal. +- **Reife:** gut. +- **Aufwand:** klein. +- **Empfehlung:** **mittlerer Nutzen**. + +### 4.16 `spanstream` +- **Einsatz:** In-memory-Stream-Verarbeitung in Tests/Tools. +- **Nutzen:** begrenzt. +- **Risiken:** geringe Relevanz für Kern. +- **Reife:** unterschiedlich. +- **Aufwand:** klein. +- **Empfehlung:** **geringer Nutzen**. + +### 4.17 `move_only_function` +- **Einsatz:** Callback-Pfade, wo Move-only-Callables sinnvoll sind. +- **Nutzen:** präzisere Ownership-Semantik. +- **Risiken:** STL-Reife + API-Komplexität. +- **Reife:** mittel. +- **Aufwand:** mittel. +- **Empfehlung:** **mittlerer Nutzen** (selektiv intern). + +### 4.18 generator / coroutine-nahe Ergänzungen +- **Einsatz:** nur bei klaren Streaming-Use-Cases. +- **Nutzen:** im aktuellen Kern gering. +- **Risiken:** hohe Komplexität/Debugkosten. +- **Reife:** noch nicht ideal für konservative Baseline. +- **Aufwand:** groß. +- **Empfehlung:** **vermeiden**. + +### 4.19 import/std::modules-nahe Entwicklungen +- **Einsatz:** Build/Compile-Organisation. +- **Nutzen:** theoretisch compile-time. +- **Risiken:** Tooling-/Buildsystem-/Ökosystem-Komplexität sehr hoch. +- **Reife:** für dieses Projekt (Autotools, Generatorfiles, Multi-OS) nicht robust genug. +- **Aufwand:** sehr groß. +- **Empfehlung:** **vermeiden**. + +--- + +## 5. Spezifischer Mehrwert gegenüber C++20 + +### Realer Zusatznutzen +- `std::expected` (+ monadische Operationen) als klarster funktionaler Mehrwert gegenüber C++20-Alternativen. +- `to_underlying`, `byteswap`, `unreachable` als kleine, aber saubere Verbesserungen mit gutem Nutzen/Risiko-Verhältnis. + +### Spürbare Verbesserungen möglich bei +- API-Design interner Fehlerpfade (Expected statt ad-hoc Status + Out-Parameter). +- Diagnostik-Qualität in kontrollierten Utility-Layern. +- Sicherheit indirekt durch explizitere Kontrollflüsse und weniger Cast-/Endian-Boilerplate. + +### Eher kosmetisch/operativ schwach +- Viele Syntax-/Template-Neuerungen (deducing this, static operators, etc.) ohne klare Projekthebel. +- Große Themen wie Modules/Coroutine-Ökosystem liefern hier kurzfristig mehr Risiko als Nutzen. + +--- + +## 6. Risikoanalyse + +### a) Toolchain-/Compiler-Risiko +- **Beschreibung:** C++23-Sprachfeatures unterschiedlich implementiert. +- **Wahrscheinlichkeit:** mittel-hoch +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** C++23 nur experimentell in CI, feature-test-macro Gates. + +### b) Standardbibliotheks-Risiko +- **Beschreibung:** library feature gaps/inkonsistente Reife. +- **Wahrscheinlichkeit:** hoch +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** explizite Min-Versionen + Fallbacks + feature probing. + +### c) ABI-/API-Risiko +- **Beschreibung:** neue Typen in Public Headers brechen Downstream. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** Public API freeze, Adapter-Overloads, ABI-Checks. + +### d) Plattform-Risiko +- **Beschreibung:** Linux/macOS/Windows verhalten sich divergierend. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** Multi-OS-Matrix, Release-Candidate-Zyklen. + +### e) Packaging-/Distributions-Risiko +- **Beschreibung:** konservative Distros bremsen C++23-Featureeinsatz. +- **Wahrscheinlichkeit:** hoch +- **Auswirkung:** mittel-hoch +- **Gegenmaßnahmen:** Baseline konservativ halten, C++23 feature-guarded. + +### f) Test-/Regression-Risiko +- **Beschreibung:** neue Fehlerpfad-/Template-Semantik erzeugt subtile Regressions. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** erweiterte Regressionen + Sanitizer + differential benchmarks. + +### g) Security-/Review-Risiko +- **Beschreibung:** höhere Sprachkomplexität erschwert Audits. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** hoch +- **Gegenmaßnahmen:** klare Feature-Policy, Review-Checklisten, kleine PRs. + +### h) Maintainer-/Contributor-Risiko +- **Beschreibung:** Einstiegshürde steigt, Review-Latenz steigt. +- **Wahrscheinlichkeit:** mittel +- **Auswirkung:** mittel +- **Gegenmaßnahmen:** style guide, begrenzte erlaubte Featureliste, Schulung via Beispiele. + +--- + +## 7. C++23-Feature-Matrix + +| Feature | möglicher Einsatz im Projekt | Nutzen gegenüber C++20 | Toolchain-Reife | Risiko | Aufwand | Empfehlung | +|---|---|---|---|---|---|---| +| `std::expected` | interne Fehlerpfade | Hoch | Mittel | Mittel | Mittel | **einführen (selektiv)** | +| Monadic ops für `expected` | Fehlerketten | Mittel-Hoch | Mittel | Mittel | Mittel | **einführen (selektiv)** | +| `std::to_underlying` | enum-Interops | Mittel | Hoch | Niedrig | Klein | **einführen** | +| `std::byteswap` | Endian-Utilities | Mittel | Hoch | Niedrig | Klein | **einführen** | +| `std::unreachable` | Invarianten/Hot paths | Mittel | Hoch | Mittel (UB bei Missbrauch) | Klein | **einführen mit Guardrails** | +| constexpr-lib Erweiterungen | statische Utilities | Mittel | Mittel | Niedrig-Mittel | Klein-Mittel | **später prüfen** | +| `move_only_function` | Callback-APIs intern | Mittel | Mittel | Mittel | Mittel | **später prüfen** | +| string/ranges/view additions | interne Pipelines | Gering-Mittel | Mittel | Mittel | Mittel | **später prüfen** | +| size_t literal suffix | Low-level literals | Gering | Hoch | Niedrig | Klein | **optional** | +| `print`/format improvements | tooling/logging | Gering-Mittel | Mittel | Mittel | Klein-Mittel | **noch nicht reif genug** | +| `stacktrace` | Diagnostics | Mittel (theoretisch) | Niedrig-Mittel | Mittel-Hoch | Mittel | **noch nicht reif genug** | +| `flat_map`/`flat_set` | Spezial-Container | Mittel (nischig) | Niedrig-Mittel | Mittel | Mittel | **noch nicht reif genug** | +| `spanstream` | Tests/Tools | Gering | Mittel | Niedrig | Klein | **optional** | +| deducing this / explicit object parameter | API-Design | Gering | Mittel | Mittel-Hoch | Mittel-Groß | **vermeiden** | +| multidimensional subscript | numerische Datenstrukturen | Gering | Mittel | Niedrig | Klein | **vermeiden** | +| static `operator()`/`operator[]` | Spezialmuster | Gering | Mittel | Mittel | Klein | **vermeiden** | +| generator/coroutine additions | streaming abstractions | Gering-Mittel | Niedrig-Mittel | Hoch | Groß | **vermeiden** | +| import `std` / modules-nahe Nutzung | Build-Struktur | Gering (kurzfristig) | Niedrig-Mittel | Hoch | Sehr groß | **vermeiden** | + +--- + +## 8. Security-Betrachtung + +### Positiv +- `std::expected` kann Fehlerpfade expliziter machen und implizite Fehlerzustände reduzieren. +- `to_underlying`/`byteswap` reduzieren fragile low-level Cast-/Byteorder-Muster. +- Bessere API-Modellierung kann Reviewbarkeit erhöhen, wenn Featureeinsatz diszipliniert bleibt. + +### Negativ +- Zusätzliche Sprachkomplexität kann Security-Reviews erschweren. +- Falsch eingesetztes `unreachable` erzeugt UB-Risiken. +- Bei zu früher Breiteinführung steigen Angriffsflächen durch Portabilitäts-/Semantikabweichungen. + +### Ehrliche Bewertung +- **Verbessert C++23 die Sicherheit?** Selektiv ja (vor allem via `expected` und robuste Utility-APIs). +- **Oder steigt primär Komplexität?** Ohne strikte Governance überwiegt die Komplexität. + +--- + +## 9. Performance- und Ressourcenbetrachtung + +- **Runtime:** keine automatische Verbesserung; `expected` kann in manchen Pfaden klarer und ähnlich performant wie Statuscodes sein, muss aber gemessen werden. +- **Compile time:** tendenziell eher steigend bei mehr Template-/Metaprogrammierung. +- **Binary size:** kann leicht steigen (zusätzliche Template-Instanziierungen, neue Bibliothekskomponenten). +- **Memory footprint:** meist neutral; abhängig von konkreten Datentypen und Fehlerobjekten. + +Klarstellung: **Modernerer Sprachstandard bedeutet nicht automatisch schnelleren Code.** + +--- + +## 10. Aufwandsschätzung + +### Nur Build auf C++23 umstellen +- **Qualitativ:** mittel bis groß +- **T-Shirt:** M-L +- Grund: Buildsysteme/CI/Conan/Packaging konsistent anpassen. + +### Selektive Nutzung einzelner Features +- **Qualitativ:** mittel +- **T-Shirt:** M +- Grund: gezielte interne Refactorings + Tests + Review-Policy. + +### Breitere Refactorings mit C++23-Idiomen +- **Qualitativ:** groß bis sehr groß +- **T-Shirt:** L-XL +- Grund: hoher Reviewaufwand, Portabilitäts-/Regressionstests, potenzielle API-Auswirkungen. + +--- + +## 11. Empfohlene Strategie + +### Phase A: C++20 stabilisieren +- **Ziel:** robuste C++20-Baseline auf allen Zielplattformen. +- **Aufgaben:** CI-Matrix vervollständigen, Sanitizer/Benchmarks/ABI-Checks etablieren. +- **Erfolgskriterien:** dauerhaft grüne C++20-Pipeline + stabile Releases. +- **Abbruchkriterien:** anhaltende Plattform-/ABI-Regressions. +- **Risiken:** C++20-Baustellen werden unterschätzt. + +### Phase B: C++23-Toolchain experimentell in CI aufnehmen +- **Ziel:** Kompatibilitäts-Transparenz ohne Produktivzwang. +- **Aufgaben:** zusätzliche non-blocking C++23-Jobs für GCC/Clang/MSVC. +- **Erfolgskriterien:** reproduzierbare Ergebnisse, dokumentierte Gaps. +- **Abbruchkriterien:** unwartbar hohe Flake-/False-Positive-Rate. +- **Risiken:** erhöhte CI-Kosten. + +### Phase C: Build-Kompatibilität mit C++23 bewerten +- **Ziel:** klären, ob "builds with C++23" stabil genug ist. +- **Aufgaben:** alle optionalen Dependency-Kombinationen testen. +- **Erfolgskriterien:** definierte Mindesttoolchain + belastbare Erfolgsrate. +- **Abbruchkriterien:** kritische Plattform/Dependency-Lücken. +- **Risiken:** distro-spezifische Brüche. + +### Phase D: 1–3 risikoarme C++23-Features pilotieren +- **Ziel:** realen Mehrwert nachweisen. +- **Aufgaben:** Pilot mit `expected`, `to_underlying`, `byteswap` in internen Modulen. +- **Erfolgskriterien:** bessere Lesbarkeit/Fehlerbehandlung ohne Regression. +- **Abbruchkriterien:** Performance-/Stabilitätsverschlechterung. +- **Risiken:** schleichende Ausweitung ohne Policy. + +### Phase E: Entscheidung über breitere Nutzung +- **Ziel:** datengetriebene Produktiventscheidung. +- **Aufgaben:** Pilot auswerten, Downstream-/Packaging-Feedback einholen. +- **Erfolgskriterien:** klarer Nutzen > Risiko, stabile Toolchain-Breite. +- **Abbruchkriterien:** kein messbarer Mehrwert. +- **Risiken:** vorschneller Baseline-Wechsel. + +--- + +## 12. Konkrete Empfehlung für Maintainer + +**Empfehlung:** **erst C++20 stabilisieren, C++23 nur experimentell prüfen; anschließend selektiv wenige C++23-Features übernehmen.** + +Technisch-pragmatische Begründung: +1. C++20 adressiert bereits den Großteil der relevanten Modernisierung. +2. C++23-Reife ist für ein Multi-Plattform-Security-Projekt nicht homogen genug für sofortige Baseline. +3. Höchster ROI liegt in selektiven Features (`expected`, `to_underlying`, `byteswap`) statt Vollumstieg. +4. Stabilität, ABI/API-Kontrolle und Packaging sind aktuell wichtiger als Sprachversions-Branding. + +--- + +## 13. Konkrete nächste Schritte (12 Maßnahmen) + +1. **C++20-Stabilitäts-Gate formal definieren** + - Zweck: Spezialregel absichern. + - Priorität: hoch. + - Nutzen: klare Voraussetzung für C++23-Schritte. + +2. **C++23-Shadow-Jobs in CI hinzufügen (non-blocking)** + - Zweck: reale Kompatibilitätsdaten sammeln. + - Priorität: hoch. + - Nutzen: faktenbasierte Entscheidung statt Annahmen. + +3. **Feature-Test-Makro-Policy verbindlich machen** + - Zweck: library feature drift beherrschen. + - Priorität: hoch. + - Nutzen: weniger Portabilitätsbrüche. + +4. **Toolchain-Minimum pro Plattform dokumentieren** + - Zweck: klare Supportgrenzen. + - Priorität: hoch. + - Nutzen: planbare Releases. + +5. **`std::expected` Pilot in internem Modul starten** + - Zweck: praktischen Mehrwert validieren. + - Priorität: hoch. + - Nutzen: bessere Fehlerpfade. + +6. **`to_underlying` und `byteswap` als Low-risk Cleanups einführen** + - Zweck: Utility-Code robuster machen. + - Priorität: mittel-hoch. + - Nutzen: sichere Kleingewinne. + +7. **`unreachable`-Nutzungsrichtlinie definieren** + - Zweck: UB-Risiko begrenzen. + - Priorität: mittel-hoch. + - Nutzen: kontrollierter Einsatz. + +8. **Packaging-Check mit Ziel-Distros durchführen** + - Zweck: Realitätsabgleich außerhalb CI. + - Priorität: hoch. + - Nutzen: weniger Überraschungen downstream. + +9. **ABI/API-Überwachung für C++23-Pilots aktivieren** + - Zweck: Public-Surface schützen. + - Priorität: hoch. + - Nutzen: connector-sichere Evolution. + +10. **Benchmark-Baselines für Pilotpfade erfassen** + - Zweck: Performance-Neutralität belegen. + - Priorität: mittel-hoch. + - Nutzen: datengetriebene Entscheidungen. + +11. **Security-Review-Checklist um C++23-Footguns erweitern** + - Zweck: Reviewqualität sichern. + - Priorität: mittel-hoch. + - Nutzen: geringeres Introduktionsrisiko. + +12. **Go/No-Go-Entscheidung nach 1–2 Releasezyklen treffen** + - Zweck: keine Dauer-Experimente. + - Priorität: hoch. + - Nutzen: klare Roadmap. + +--- + +## Abschluss + +**A) Gesamturteil in einem Satz:** +C++23 ist für ModSecurity **als experimenteller Buildmodus mit selektiver Feature-Nutzung sinnvoll**, aber **nicht als sofortige produktive Baseline**. + +**B) Risikoampel:** +- Toolchain-/Compiler-Reife: 🟠 +- Standardbibliothek/Feature-Reife: 🔴 +- ABI/API: 🟠 +- Plattform/Packaging: 🔴 +- Security/Review-Komplexität: 🟠 + +**C) Was ich als Maintainer als Nächstes tun würde:** +Ich würde zuerst die C++20-Baseline verbindlich stabilisieren, parallel C++23 als non-blocking CI-Modus laufen lassen und nur `expected` + `to_underlying` + `byteswap` pilotieren. + +**D) Welche C++23-Themen ich ausdrücklich noch nicht produktiv einführen würde:** +- Modules / `import std` +- coroutine-/generator-basierte Architekturänderungen +- breite Nutzung von deducing-this/explicit-object-Parametern +- `stacktrace` als plattformübergreifende Pflichtdiagnostik + +**Spezialregel-Entscheidung für dieses Repository:** +Solange nicht nachweislich gilt, dass +1) C++20 auf allen Zielplattformen stabil läuft, +2) die CI-Matrix tragfähig ist, +3) öffentliche API-/ABI-Risiken verstanden und überwacht sind, und +4) Downstream-Packaging realistisch abgesichert ist, +empfehle ich explizit: **erst C++20 stabilisieren, C++23 nur experimentell prüfen**. From a609fe31faf2184d98eb3a190fd44127829f91ea Mon Sep 17 00:00:00 2001 From: Easton97-Jens <66330090+Easton97-Jens@users.noreply.github.com> Date: Fri, 10 Apr 2026 19:38:27 +0200 Subject: [PATCH 3/3] Create t.md --- doc/t.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 doc/t.md diff --git a/doc/t.md b/doc/t.md new file mode 100644 index 0000000000..d3c6d0fd70 --- /dev/null +++ b/doc/t.md @@ -0,0 +1,67 @@ +1. Konkrete YAJL-Verwendungsstellen + + configure.ac: führt YAJL-Konfiguration über PROG_YAJL aus und setzt ein AM_CONDITIONAL dafür. + + build/yajl.m4: definiert PROG_YAJL, prüft Header/Lib (yajl/yajl_parse.h) und setzt YAJL-Flags (YAJL_CFLAGS, YAJL_LDADD). + + src/request_body_processor/json.h: kompiliert den JSON-Processor nur unter #ifdef WITH_YAJL, inkludiert , nutzt YAJL-Typen (yajl_handle, yajl_status). + + src/request_body_processor/json.cc: implementiert JSON-Parsing mit YAJL (yajl_alloc, yajl_parse, yajl_complete_parse, Error-Handling über YAJL-APIs). + + headers/modsecurity/transaction.h: nutzt YAJL-Generatorfunktionen in Makros (yajl_gen_string, yajl_gen_number, yajl_gen_integer). + + src/Makefile.am: bindet request_body_processor/json.cc in BODY_PROCESSORS ein und nutzt $(YAJL_CFLAGS) beim Build der Hauptbibliothek libmodsecurity.la. + + build/win32/CMakeLists.txt: setzt HAVE_YAJL auf 1 und verknüpft libModSecurity sowie Tests mit yajl::yajl (WITH_YAJL). + + build/win32/conanfile.txt: enthält YAJL als Conan-Abhängigkeit (yajl/2.1.0). + + README.md: beschreibt YAJL als (laut Dokumentation) mandatory dependency für JSON-Logs und Testframework. + +2. Technische Einordnung + + Die YAJL-Nutzung liegt im nativen C/C++-Kernpfad des Projekts (Autotools/CMake, Kernbibliothek libmodsecurity, Request-Body-JSON-Parser, Transaktions-Logging-Makros). + + Ein klar belegter „austauschbarer Java-Randbereich“ für diese YAJL-Stellen ist im Repository nicht belegt. + + Dass YAJL nur in einem leicht isolierbaren Nebenmodul liegt, ist durch die gezeigten Build- und Source-Verknüpfungen nicht belegt. + +3. Voraussetzungen für einen Ersatz durch Jackson + +Für einen echten Ersatz YAJL → Jackson wären zusätzlich nötig: + + Eine Integrationsschicht zwischen C/C++-Kern und Java (z. B. JNI, IPC oder andere Brücke), weil Jackson eine Java-Bibliothek ist und YAJL hier nativ in C/C++ verwendet wird. + + Ein solcher Mechanismus ist im Repository nicht belegt (kein vorhandener JNI/JNA-/Java-Buildpfad im Repo nachweisbar). + + Ein definierter Java-Build/Dependency-Pfad (z. B. Maven-Modul) für Jackson. + + Im Repository sind entsprechende Java-/Maven-Dateien nicht belegt (Dateisuche ohne Treffer). + + Anpassungen der nativen Aufrufstellen, die heute direkt YAJL-APIs verwenden (json.cc, transaction.h). + +4. Belastbare Antwort auf die Kernfrage + +YAJL könnte eventuell ersetzbar sein, aber nur mit zusätzlicher Integrationsschicht + +Begründung (nur Repository-Evidenz): + + YAJL ist direkt im nativen Kern und in den nativen Buildpfaden verdrahtet (Autotools/CMake/Conan + C/C++-Code). + + Konkrete YAJL-API-Nutzung im Kerncode ist vorhanden (yajl_parse, yajl_gen_*). + + Ein vorhandener Java-Bridge-Mechanismus, der „kleinen Ersatzaufwand“ stützen würde, ist im Repository nicht belegt. + +5. Was dafür fehlen würde + + Nachweisbarer bestehender Java/JVM-Integrationspfad im Repository: im Repository nicht belegt. + + Nachweisbare vorhandene JNI/JNA/IPC-Brücke vom C/C++-Kern zu Java: im Repository nicht belegt. + + Nachweisbarer Maven-/Java-Modulpfad im Repository: im Repository nicht belegt. + + Nachweis, dass die YAJL-Aufrufe in json.cc/transaction.h ohne wesentliche Kernanpassung austauschbar sind: im Repository nicht belegt. + +Explizite Antwort auf die Zusatzfrage: +„Ist Jackson hier ein echter Ersatz für YAJL oder nur ein zusätzlicher Java-Baustein, der eine neue Integrationsschicht erfordern würde?“ +→ Auf Basis des Repositorys ist Jackson nicht als direkter kleiner Ersatz von YAJL belegt; belastbar erscheint Jackson hier nur als zusätzlicher Java-Baustein mit neuer Integrationsschicht.