Repository navigation
Close 0002: guard the expected-lite selection, run reflected JSON iteration under ASan - #489
Merged
Merged
Conversation
…eration under ASan The 0002 segfault was an ABI mismatch, not a lifetime bug: a C++14 library (nonstd optional/variant) read by a C++17 consumer (std aliases). 2.0 removed it; Result<T>'s expected-lite selection was the remaining instance, so template.h now defaults it and rejects std::expected with #error. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01URYuQSkLMNwHqGAcDqQZjq
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01URYuQSkLMNwHqGAcDqQZjq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Ruslan · project thread
Before: task 0002 reported a segfault when iterating an
nlohmann::jsonarray passed throughReflect, with no root cause. No test iterated reflected JSON arrays, and no sanitizer job built the nlohmann bindings. A consumer compiled at C++23 without the CMake/pkg-config flag could silently getstd::expectedasjinja2::Result<T>while the library usesnonstd::expected.After: the cause is identified and its remaining instance is closed.
template.hdefaults expected-lite to its ownnonstd::expectedand stops with#errorwhenstd::expectedwas already selected in the translation unit. A new test covers iterating reflected arrays, and it runs under ASan+UBSan in CI.Root cause. This was not a lifetime bug. Before 2.0 the library was built as C++14, so optional-lite and variant-lite used their own types. The probe driver was C++17, where the same headers alias
std::optional/std::variant.CreateEnumerator()returnsoptional<ListEnumeratorPtr>, which the header-only nlohmann accessor and the compiledGenericListAdapterthen read with two different layouts. I reproduced it on f2c05c0 by linking a C++17 test object against the C++14 library: UBSan reportsload of value 64, which is not a valid value for type 'bool'innonstd/optional.hppand every loop renders empty. When both sides use the same standard the test is clean, on f2c05c0 and on master. 0071 (std vocabulary types, C++17 floor) removed the cause. Only theexpectedselection was still left open.How.
include/jinja2cpp/template.h:#ifndef nsel_CONFIG_SELECT_EXPECTEDsets it to NONSTD, then the include, then#if nsel_USES_STD_EXPECTEDtriggers the#error. Builds through the CMake target or pkg-config already pass NONSTD and are unaffected.test/binding/nlohmann_json_binding_test.cpp:NlohmannJsonTest.ArrayIterationcovers top-level, nested,if-filtered and filter-consumed (join,map) iteration. Its output matches Python Jinja2 on the same data..github/workflows/linux-build.yml: the sanitizer matrix gets abindingsaxis. The clang-18address+undefinedjob now builds with nlohmann, the gcc-14 ASan and TSan jobs stay on boost, and job names are unchanged.docs/tasks/0002: marked done with the root cause.Agent notes. Roles: verifier (1 round, no blocking findings). I applied its one nit: the test now uses
o['values'], because in Pythono.valuesisdict.values. Red pushes so far: 0. Checks run locally: full suite under clang-18 ASan+UBSan with nlohmann bindings,scripts/preflight.sh, and a gcc-14/clang-18 C++17/C++23 syntax matrix for the header guard. MSVC and the shared-library build were not run here; CI covers them.🤖 Generated with Claude Code
https://claude.ai/code/session_01URYuQSkLMNwHqGAcDqQZjq
Generated by Claude Code