* Guard ExpressionParser initialization with sync.Once
The evaluators call InitExpressionParser on every Evaluate, so two goroutines
could construct a parser at the same time. newParticipleLexer also fills in the
ParticipleTokenType field on each shared participleYqRules entry as it builds
the lexer, which another goroutine could be reading through getYqDefinition.
These are pointer and struct field writes rather than map writes, so the
runtime does not stop the process; it corrupts quietly instead.
The nil check stays inside the Once so a caller that assigns ExpressionParser
itself is still respected.
Fixes#2788
* docs: use UK spelling for initialised in new comments
Matches the existing prose convention in pkg/yqlib (operator_reduce.go,
decoder_ini.go, operator_alternative_test.go). Review feedback on #2789.
recurseNodeObjectEqual and containsObject both used findInArray to
locate keys in a MappingNode's Content array. findInArray steps by 1,
so it matches against both keys (even indices) and values (odd indices).
In recurseNodeObjectEqual, when a null key in the LHS matched a null
value in the RHS at the last position, rhs.Content[indexInRHS+1]
accessed an out-of-bounds index, causing a panic.
In containsObject, a %2 guard prevented the panic but introduced false
negatives: when a null value appeared before the actual null key,
findInArray returned the value's odd index, the guard rejected it, and
the function reported the key as missing.
Both functions now use findKeyInMap, which steps by 2 and compares only
key positions. The %2 guard in containsObject is removed.
Reproducer for the panic (recurseNodeObjectEqual):
echo '? [{~: ~}]
: v1
? [{2: ~}]
: v2' | yq '. += .'
Reproducer for the false negative (containsObject):
printf '? 1\n: ~\n? ~\n: x\n' | yq 'contains({~: "x"})'
Found by OSS-Fuzz via the lima project's FuzzEvaluateExpression target.
https://issues.oss-fuzz.com/issues/383860504
Signed-off-by: Jan Dubois <jan@jandubois.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move data_navigator, json_converter, merge, and path_parser to pkg/yqlib
- Extract yamlToString from yq to pkg/yqlib/yaml_converter
- Move utils_test to test/utils