Skip to content

Conversation

@cataphract
Copy link
Contributor

The default allocator argument caused runtime exceptions "emplace: incompatible allocators" (from writable_object::emplace/emplace_back in src/object.hpp:1179, 1216) when converting a dynamic_string to an object with a mismatched allocator.

By making the allocator parameter required, such bugs will be caught at compile time instead of causing runtime exceptions.

This change fixes two instances in fingerprint.cpp where the allocator was not being passed, which triggered these allocator mismatch exceptions, and updates tests to explicitly pass allocators.

The default allocator argument caused runtime exceptions "emplace: incompatible
allocators" (from writable_object::emplace/emplace_back in src/object.hpp:1179,
1216) when converting a dynamic_string to an object with a mismatched allocator.

By making the allocator parameter required, such bugs will be caught at compile
time instead of causing runtime exceptions.

This change fixes two instances in fingerprint.cpp where the allocator was not
being passed, which triggered these allocator mismatch exceptions, and updates
tests to explicitly pass allocators.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@cataphract cataphract had a problem deploying to dd-protected-coverage December 24, 2025 10:07 — with GitHub Actions Failure
@github-actions
Copy link

github-actions bot commented Dec 24, 2025

Dynamic Artifact Size Comparison 📦

Artifact Previous Release This PR Difference
darwin-arm64::libddwaf.dylib 2027984 2004032 -1.18%
darwin-universal::libddwaf.dylib 4256208 4215872 -0.94%
darwin-x86_64::libddwaf.dylib 2213736 2191616 -0.99%
linux-aarch64::libddwaf.so 2463376 2374048 -3.62%
linux-armv7::libddwaf.so 2148940 2041016 -5.02%
linux-i386::libddwaf.so 2392980 2297052 -4.00%
linux-x86_64::libddwaf.so 2660256 2567024 -3.50%
windows-arm64::ddwaf.dll 4790272 4766720 -0.49%
windows-win32::ddwaf.dll 3368960 3317760 -1.51%
windows-x64::ddwaf.dll 4102656 4042752 -1.46%

Static Artifact Size Comparison 📦

Artifact Previous Release This PR Difference
darwin-arm64::libddwaf.a 91537528 92215408 0.74%
darwin-arm64::libddwaf.a.stripped 4582760 4683176 2.19%
darwin-universal::libddwaf.a 184432872 185960912 0.82%
darwin-universal::libddwaf.a.stripped 9776864 9978504 2.06%
darwin-x86_64::libddwaf.a 92895296 93745456 0.91%
darwin-x86_64::libddwaf.a.stripped 5194056 5295280 1.94%
linux-aarch64::libddwaf.a 73173714 75125862 2.66%
linux-aarch64::libddwaf.a.stripped 11851494 12116122 2.23%
linux-armv7::libddwaf.a 64732098 66377096 2.54%
linux-armv7::libddwaf.a.stripped 10852278 11133916 2.59%
linux-i386::libddwaf.a 62858558 64573188 2.72%
linux-i386::libddwaf.a.stripped 9379838 9635756 2.72%
linux-x86_64::libddwaf.a 73660850 75621592 2.66%
linux-x86_64::libddwaf.a.stripped 11670798 11923620 2.16%
windows-arm64::ddwaf.lib 11698 16410 40.27%
windows-arm64::ddwaf_static.lib 57964164 55605256 -4.06%
windows-win32::ddwaf.lib 11922 16726 40.29%
windows-win32::ddwaf_static.lib 49576448 47563822 -4.05%
windows-x64::ddwaf.lib 11698 16410 40.27%
windows-x64::ddwaf_static.lib 57456080 55345218 -3.67%

@pr-commenter
Copy link

pr-commenter bot commented Dec 24, 2025

Benchmarks clang-pgo

Benchmark execution time: 2026-01-01 23:04:02

Comparing candidate commit a9635e6 in PR branch glopes/fix-incompatible-allocators with baseline commit 3a06266 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 1 metrics, 0 unstable metrics.

This change extends the allocator refactoring to comprehensively prevent
allocator mismatch bugs by:

1. **Remove default allocators from owned_object constructors**
   - String constructors now require explicit allocator parameter
   - Prevents implicit use of default allocator when specific one needed
   - Compile-time enforcement of correct allocator usage

2. **Privatize raw constructor, expose via create_unchecked()**
   - `owned_object(detail::object, alloc)` now private
   - Added `create_unchecked()` static factory to make danger explicit
   - Updated call sites in interface.cpp and elsewhere

3. **Use null allocator for primitives**
   - Primitives (null, boolean, numbers) use memory::get_default_null_resource()
   - Null allocator throws if allocation attempted, catching bugs early

4. **Rename unsafe methods for clarity**
   - `make_string_nocopy` → `unsafe_make_string_nocopy`
   - Explicit naming indicates caller must ensure memory ownership

5. **Template improvements using std::constructible_from**
   - attribute_collector insert() overloads use concept constraints
   - writable_object emplace/emplace_back use std::constructible_from
   - Cleaner distinction between allocating and non-allocating types

6. **Test infrastructure improvements**
   - Added tests/common/ddwaf_object_da.hpp for test allocator utilities
   - Updated all test files to use new constructor signatures

7. **Fix examples and benchmarks for current API**
   - examples/example.cpp: Updated to use ddwaf_object_set_* functions
   - tools/ip_match_benchmark.cpp: Fixed deprecated API and IPv6 code
   - tools/infer_schema_bench.cpp: Updated include path (still needs API rewrite)

All 1,513 tests pass with zero memory leaks (51,813 allocs/deallocs balanced).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@cataphract cataphract changed the title Remove default allocator argument from dynamic_string::to_object() Remove default allocator arguments Dec 30, 2025
@cataphract
Copy link
Contributor Author

There were more similar bugs. Added another commit to remove more default allocator parameters

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request removes default allocator arguments from the owned_object API to enforce compile-time checking of allocator compatibility, preventing runtime "incompatible allocators" exceptions. The change makes allocator parameters required for operations that need memory management, ensuring that allocator mismatches are caught during compilation rather than at runtime.

  • Fixed two bugs in fingerprint.cpp where allocators were not being passed to dynamic_string::to_object()
  • Introduced a test helper class ddwaf_object_da that provides convenience wrappers with default allocators for test code
  • Updated all production code to explicitly pass allocators where required

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/object.hpp Removed default allocator parameters from constructors and factory methods; added create_unchecked() for unsafe operations; updated template constraints to use std::constructible_from
src/dynamic_string.hpp Made allocator parameter required in to_object() method signature
src/dynamic_string.cpp Updated to_object() implementation to use required allocator parameter with proper safety comments
src/processor/fingerprint.cpp Fixed two instances where allocator was missing from buffer.to_object() calls
src/serializer.cpp Added allocator parameter to collect_attributes() and passed through to collector.insert()
src/ruleset_info.hpp Updated section_info and to_object() to explicitly pass default resource allocator
src/ruleset_info.cpp Updated to pass allocator when creating arrays in add_failed()
src/json_utils.cpp Updated string creation to pass allocator explicitly
src/interface.cpp Updated to use create_unchecked() for unsafe operations; added safety comments
src/attribute_collector.hpp Added overload for inserting values that require allocators
tests/common/ddwaf_object_da.hpp New test helper class providing factory methods with default allocators
tests/common/yaml_utils.cpp Updated YAML conversion to use test helper methods
tests/unit/*.cpp Updated all test files to use test::ddwaf_object_da helper methods instead of direct constructors
tools/ip_match_benchmark.cpp Updated to explicitly pass allocators and use new API functions
tools/infer_schema_bench.cpp Added allocator variable and updated namespace reference
examples/example.cpp Updated example to use new API with explicit allocators and pointer-based insert functions
fuzzer/**/src/main.cpp Updated all fuzzers to explicitly obtain and pass default allocator

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@cataphract cataphract had a problem deploying to dd-protected-coverage December 30, 2025 18:50 — with GitHub Actions Failure
@cataphract cataphract force-pushed the glopes/fix-incompatible-allocators branch from 358fa45 to 617ff3d Compare December 30, 2025 19:17
@cataphract cataphract had a problem deploying to dd-protected-coverage December 30, 2025 19:25 — with GitHub Actions Failure
@cataphract cataphract force-pushed the glopes/fix-incompatible-allocators branch from 617ff3d to 998f840 Compare January 1, 2026 18:00
@cataphract cataphract had a problem deploying to dd-protected-coverage January 1, 2026 18:08 — with GitHub Actions Failure
* Remove public constructors from owned_object, as these just duplicate
  ddwaf_object::make_* factory methods and may have confusing affects
  around some implicit conversions.
* make borrowed objects destroy the current value when they're assigned
  to from an owned_object&&. This prevents some usages of
  to_borrowed(x), where x is uninitialized memory.
* remove more implicit usages of the default allocator, causing runtime
  errors.
@cataphract cataphract force-pushed the glopes/fix-incompatible-allocators branch from 998f840 to a9635e6 Compare January 1, 2026 22:27
@cataphract cataphract had a problem deploying to dd-protected-coverage January 1, 2026 22:35 — with GitHub Actions Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants