PureYAML/Tests
Mihaela Mihaljevic 20b96fbfd4 fix(parsing): reject anchor-expansion (billion-laughs) bombs
enforceNestingLimit (Parser.Events.swift) bounds PHYSICAL collection
depth in the raw event stream, since it counts sequenceStart/
mappingStart events directly. It does nothing against an
anchor-expansion bomb: a handful of shallow, small anchors each
aliased many times, each alias nested inside the next, keeps raw
event depth at a constant 2 per line while the LOGICAL tree an alias
resolves to grows exponentially in the number of alias levels. A
25-level, fan-out-9 document (~1.5KB) expands past 9^25 logical
nodes; before this fix, parse accepted it in under 2ms, and any
full-tree walk downstream (JSON representability checking, JSON
writing, validation) never terminated.

Added a total expanded-node budget, charged incrementally as the
document streams through the composer rather than by walking
anything: every scalar charges 1, every completed container charges 1
for its own wrapper (children already charged their own cost as they
completed), and every alias resolution charges the target's CACHED
expanded size -- computed once when the anchor was defined, looked up
in O(1). This makes a nested bomb's true compounded size visible
arithmetically within a few alias levels, without ever materializing
or walking the exponential tree it would otherwise produce. A
document with genuinely wide but non-exponential alias reuse (the
same small anchor referenced thousands of times at one level, no
nesting) stays comfortably inside the budget and parses normally.

Verified via the full existing test suite (674 tests, all passing,
zero regressions -- including the YAML Test Suite conformance corpus
and the tagged round-trip corpus), two new tests proving the bomb is
rejected (in under 2ms) and that wide non-exponential fan-out still
parses, and swiftformat/swiftlint --strict clean on all five touched
files.

PureYAML.Parsing.EventComposer and Tagged.EventComposer (two other,
separate composer implementations in this package, used by the
diagnostic-validation and tagged-parsing entry points respectively)
share the same architectural gap and would benefit from the same
fix, but are not reachable from the confirmed exploit path this
change closes -- disclosed, not fixed here.
2026-07-18 23:35:35 +02:00
..
Fixtures fix(parsing): reject a misindented multi-line quoted scalar continuation 2026-06-24 22:09:14 +02:00
PureYAMLJSONTests refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ACMEZephyrFixtureTests.swift feat(parser): harden diagnostics and streaming 2026-06-06 07:57:48 +02:00
AdditionalCoverageTests.swift test: cover the remaining low-level paths 2026-06-26 08:59:24 +02:00
AliasAsMappingKeyTests.swift fix(parsing): accept an alias node as an implicit mapping key 2026-06-29 03:35:56 +02:00
AliasPropertiesTests.swift fix(parsing): reject an anchor or tag on an alias node 2026-06-27 21:11:10 +02:00
AnchoredIndentedNodeParsingTests.swift feat(model): support complex mapping keys 2026-06-05 16:08:45 +02:00
AnchoredMappingKeyTests.swift fix(parsing): allow an anchor or tag on a non-first mapping key 2026-06-27 00:21:38 +02:00
AnchorOnNullValueTests.swift fix(parsing): resolve an alias to an anchor on a null value 2026-06-29 02:56:17 +02:00
ArbitraryAnyDecisionTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
BareDocumentAfterEndTests.swift fix(parsing): parse a bare document after a document-end marker 2026-06-28 04:23:06 +02:00
BlockEntryAfterFlowTests.swift fix(parsing): reject a block entry after a flow collection on a line 2026-06-28 01:34:55 +02:00
BlockScalarChompingTests.swift fix(parsing): preserve leading blank lines in block scalars 2026-06-26 08:42:16 +02:00
BlockScalarDocumentBoundaryTests.swift fix(parsing): end a root block scalar at a document marker 2026-06-29 08:57:39 +02:00
BlockScalarIndentIndicatorTests.swift fix(parsing): base an inline-mapping indent indicator on the mapping 2026-06-28 23:24:21 +02:00
BlockScalarLeadingBlankTabTests.swift fix(parsing): keep a tab on a leading blank of a block scalar 2026-06-29 01:52:58 +02:00
BlockScalarLeadingBlankTests.swift fix(parsing): reject an over-indented leading line in a block scalar 2026-06-28 00:21:57 +02:00
BlockScalarPercentContentTests.swift fix(parsing): keep a leading percent in a block scalar literal 2026-06-29 05:04:32 +02:00
BlockScalarTabContentTests.swift fix(parsing): keep tabs in block scalar content verbatim 2026-06-28 20:53:40 +02:00
BlockScalarTrailingCommentTests.swift fix(parsing): comments and over-indented blanks ending block scalars 2026-06-27 15:34:13 +02:00
BlockSequenceAfterPropertyTests.swift fix(parsing): reject a block sequence inline after a node property 2026-06-27 23:14:54 +02:00
CanonicalEventConformanceTests.swift style: bring four files back under the swiftformat gate 2026-07-12 13:29:05 +02:00
CodableCompatibilityFixtures.swift feat(codable): broaden compatibility coverage 2026-06-05 12:49:20 +02:00
CodableCompatibilityTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
CodableTypeMatrixTests.swift test: round-trip the full scalar type matrix through Codable containers 2026-06-26 09:04:54 +02:00
CodingTests.swift feat(coding): add unkeyed typed conversion 2026-06-05 12:23:52 +02:00
CollectionCompatibilityFixtures.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
CommentInPlainScalarTests.swift fix(parsing): reject a comment interrupting a multi-line plain scalar 2026-06-27 19:47:28 +02:00
CommentWhitespaceTests.swift fix(parsing): reject a comment glued to earlier content on its line 2026-06-27 15:53:16 +02:00
CompactNestedSequenceTests.swift fix(parsing): bound a block sequence to its own column for siblings 2026-06-28 22:37:36 +02:00
ComplexMappingKeyCodableTests.swift feat(model): support complex mapping keys 2026-06-05 16:08:45 +02:00
ComplexMappingKeyDumperTests.swift feat(model): support complex mapping keys 2026-06-05 16:08:45 +02:00
ComplexMappingKeyParsingTests.swift fix(parsing): an explicit key with no value maps to null 2026-06-26 22:28:13 +02:00
ComplexMappingKeyTestSupport.swift feat(model): support complex mapping keys 2026-06-05 16:08:45 +02:00
ComplexMappingKeyValidationTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
DiagnosticValidationReportTests.swift feat(parsing): route the event API through the ported libyaml engine 2026-06-24 17:32:29 +02:00
DirectiveAfterDocumentEndTests.swift fix(parsing): allow a directive after a document-end marker 2026-06-28 02:09:01 +02:00
DirectiveTests.swift fix(parsing): require an explicit document after a directive 2026-06-27 17:18:47 +02:00
DocumentationExampleTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
DocumentEndContentTests.swift fix(parsing): reject content after a document end marker 2026-06-27 17:56:37 +02:00
DocumentMarkerInScalarTests.swift fix(parsing): reject a document marker inside a multi-line scalar 2026-06-27 23:20:52 +02:00
DocumentMarkerNodeTests.swift fix(parsing): fold a document-root plain scalar across column-1 lines 2026-06-26 21:30:49 +02:00
DoubleQuotedEscapeTests.swift fix(parsing): enforce the full YAML 1.2 double-quoted escape table 2026-06-27 16:19:25 +02:00
DoubleQuotedFoldingTests.swift fix(parsing): fold line breaks in multi-line double-quoted scalars 2026-06-26 21:13:13 +02:00
DownstreamDocumentFixtures.swift test(compatibility): add downstream document fixtures 2026-06-05 13:45:23 +02:00
DownstreamDocumentTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
DumperEmptyCollectionTests.swift Add machine-readable validation reports 2026-06-05 20:39:32 +02:00
DumperTests.swift fix(emitting): escape CRLF per unicode scalar in double-quoted output 2026-06-23 22:23:40 +02:00
EmitterCanonicalAndWidthTests.swift feat(emitting): add canonical mode, document markers, and lineWidth 2026-07-12 14:13:19 +02:00
EmitterCorpusTests.swift feat(emitting): broaden literal block fixtures 2026-06-05 13:37:33 +02:00
EmitterFixRegressionTests.swift fix: correct emitter and tagged round-trip and validation bugs 2026-07-16 16:29:08 +02:00
EmitterIndentAndSortKeysTests.swift feat(emitting): add indentWidth and sortKeys emitter options 2026-07-10 17:49:44 +02:00
EmptyBlockScalarChompingTests.swift fix(parsing): chomp the blank lines of an empty block scalar 2026-06-28 22:31:09 +02:00
EmptyTaggedNodeTests.swift fix(parsing): treat a dangling anchor or tag as an empty node 2026-06-28 03:21:04 +02:00
EventStreamingParserTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ExplicitKeyMultilineFoldTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
ExplicitKeyTests.swift fix(parsing): parse a property-only explicit mapping key as an empty key 2026-06-29 08:56:58 +02:00
FlowCollectionAsMappingKeyTests.swift fix(parsing): parse a flow collection before a colon as a mapping key 2026-06-28 18:34:11 +02:00
FlowDashScalarTests.swift fix(parsing): reject a lone dash before a flow indicator 2026-06-28 01:00:57 +02:00
FlowEmptyEntryTests.swift fix(parsing): reject empty entries in flow collections 2026-06-27 16:26:46 +02:00
FlowExplicitEmptyKeyTests.swift fix(parsing): parse an empty explicit key in a flow mapping 2026-06-29 09:04:29 +02:00
FlowExplicitKeyTests.swift fix(parsing): parse an explicit key inside a flow collection 2026-06-29 01:17:26 +02:00
FlowMappingEmptyKeyTests.swift fix(parsing): allow a flow mapping entry with no value 2026-06-29 01:42:02 +02:00
FlowMappingNoValueTests.swift fix(parsing): allow a flow mapping entry with no value 2026-06-29 01:42:02 +02:00
FlowMultilineValueTests.swift fix(parsing): parse a flow mapping value on the next line 2026-06-29 21:40:12 +02:00
FlowSequenceEmptyKeyTests.swift fix(parsing): treat colon-led flow sequence element as empty-key map 2026-06-28 19:43:56 +02:00
FoldedScalarBlankLineTests.swift fix(parsing): keep both breaks at a folded blank by a more-indented line 2026-06-28 21:14:14 +02:00
ImplicitNullKeyTests.swift fix(parsing): parse a property-only block mapping key as an empty key 2026-06-29 08:26:50 +02:00
IndicatorTabBoundaryTests.swift fix(parsing): skip tabs as mid-line separation white space 2026-06-28 20:35:04 +02:00
InlineBlockSequenceValueTests.swift test(parsing): assert an explicit-key compact sequence's value 2026-06-29 07:23:57 +02:00
InlineKeyPropertyAnchorTests.swift fix(parsing): bind an inline first-key property to the key 2026-06-29 03:24:30 +02:00
InlineNestedMappingTests.swift fix(parsing): reject inline nested block mappings 2026-06-27 18:28:57 +02:00
InlineSequenceItemContinuationTests.swift fix(parsing): end an inline item value at a sibling block entry 2026-06-29 02:09:57 +02:00
InvalidControlCharacterTests.swift fix(parsing): reject raw control characters in parse(), matching libyaml 2026-07-10 11:03:27 +02:00
JSONCompatibilityTests.swift feat(parser): harden diagnostics and streaming 2026-06-06 07:57:48 +02:00
KeyedCodingTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
LibYAMLCharacterClassTests.swift feat(parsing): port libyaml character-class predicates to Swift 2026-06-24 03:00:28 +02:00
LibYAMLIndentEngineTests.swift feat(parsing): begin faithful libyaml scanner port (indent engine) 2026-06-24 02:46:29 +02:00
LibYAMLParserTests.swift feat(parsing): exact scalar end positions in the located parse 2026-06-26 02:25:01 +02:00
LibYAMLPortConformanceTests.swift fix(parsing): reject a tab where a token must start, add port differential 2026-06-24 17:12:36 +02:00
LibYAMLReaderTests.swift feat(parsing): port libyaml input reader to Swift 2026-06-24 03:04:08 +02:00
LibYAMLScannerFetchTests.swift feat(parsing): port libyaml directive scanner to Swift 2026-06-24 16:54:04 +02:00
LibYAMLSimpleKeyTests.swift fix(parsing): reject a multi-line implicit key in a flow sequence 2026-06-24 21:50:41 +02:00
LiteralBlockEmissionFixtures.swift feat(emitting): broaden literal block fixtures 2026-06-05 13:37:33 +02:00
LocatedValueConformanceTests.swift feat(parsing): opt-in located parse on the hand-rolled engine 2026-06-29 07:14:42 +02:00
MappingValueTabBoundaryTests.swift fix(parsing): accept a tab after the colon value indicator 2026-06-28 20:30:24 +02:00
MergeKeyCompatibilityTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ModelTests.swift feat(parsing): add reader scanner core 2026-06-05 07:40:23 +02:00
MultilineFlowKeyTests.swift fix(parsing): let a flow plain key span lines 2026-06-29 01:38:33 +02:00
MultilineImplicitKeyTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
MultilinePropertyIndentTests.swift fix(parsing): carry spanned properties to a deeper indented node 2026-06-29 04:05:04 +02:00
NonCoreTagScalarResolutionTests.swift fix(parsing): keep a non-core-tagged scalar as a string 2026-06-28 22:25:48 +02:00
NumericCodingLadderTests.swift test: cover numeric ladder, NaN hashing, unkeyed edges, error paths 2026-06-26 07:50:08 +02:00
ParsingAliasTests.swift fix(parsing): reject anchor-expansion (billion-laughs) bombs 2026-07-18 23:35:35 +02:00
ParsingBlockScalarIndicatorTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
ParsingCompatibilityTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ParsingErrorPathTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
ParsingErrorTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
ParsingEventTests.swift feat(parsing): opt-in located parse on the hand-rolled engine 2026-06-29 07:14:42 +02:00
ParsingIndentationRegressionTests.swift Add production validation reports 2026-06-05 20:23:20 +02:00
ParsingMultilineScalarTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
ParsingNestingLimitTests.swift fix(parsing): bound nesting depth so pathological input errors instead of crashing 2026-06-23 09:29:45 +02:00
ParsingTests.swift Harden parser against real YAML fixtures 2026-06-05 19:34:30 +02:00
PlainScalarTabCommentTests.swift fix(parsing): end a plain scalar at a tab before a comment 2026-06-28 21:24:59 +02:00
PlainScalarTabFoldingTests.swift fix(parsing): fold tabs in plain scalar continuation lines 2026-06-28 21:00:32 +02:00
PreflightScannerTests.swift feat(parser): harden diagnostics and streaming 2026-06-06 07:57:48 +02:00
PublicStreamingScannerTests.swift feat(parsing): persist mid-token suspension and expose it as a public streaming API 2026-07-10 09:10:56 +02:00
QuotedKeyTests.swift fix(parsing): allow a space before the colon of a quoted mapping key 2026-06-27 01:19:28 +02:00
RealYAMLCorpusPropertyTests.swift feat(parsing): add a resumable scanner increment and broaden the mutation suite 2026-07-09 23:38:39 +02:00
RealYAMLCorpusTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
RealYAMLFixtureTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
RepeatedDocumentEndTests.swift fix(parsing): allow a repeated document-end marker 2026-06-29 08:32:26 +02:00
RootBlockScalarIndentationTests.swift fix(parsing): fold root block scalars with column-0 content 2026-06-28 17:42:38 +02:00
RoundTripDemonstrationTests.swift test: demonstrate yaml/json parsing and generation round-trips 2026-06-08 00:13:56 +02:00
ScalarCompatibilityFixtures.swift Add scalar compatibility corpus 2026-06-05 13:07:04 +02:00
SequencePropertyIndentTests.swift fix(parsing): bind an indented property to a zero-indent sequence 2026-06-29 03:44:53 +02:00
SingleQuotedFoldingTests.swift fix(parsing): fold line breaks in multi-line single-quoted scalars 2026-06-26 21:18:55 +02:00
StreamDumpingTests.swift feat(emitting): dump YAML streams 2026-06-05 17:14:41 +02:00
StreamingScannerDifferentialTests.swift feat(parsing): persist mid-token suspension and expose it as a public streaming API 2026-07-10 09:10:56 +02:00
StreamingScannerPerformanceTests.swift feat(parsing): persist mid-token suspension and expose it as a public streaming API 2026-07-10 09:10:56 +02:00
StreamParsingTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
TaggedBuiltinScalarTests.swift feat(tagged): add typed timestamp and binary scalar accessors 2026-07-12 14:20:23 +02:00
TaggedCompatibilityTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
TaggedConstructorTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
TaggedKeyUniquenessTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
TaggedNodeCorpusRoundTripTests.swift feat(tagged): carry mapping keys as full nodes 2026-07-16 15:42:56 +02:00
TaggedNodeRoundTripTests.swift feat(tagged): carry mapping keys as full nodes 2026-07-16 15:42:56 +02:00
TaggedZeroIndentSequenceTests.swift fix(parsing): end a tagged zero-indent sequence at a sibling key 2026-06-29 04:48:47 +02:00
TagHandleDiagnosticTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
TestSupport.swift Harden parser against real YAML fixtures 2026-06-05 19:34:30 +02:00
UndefinedTagHandleTests.swift Merge conformance/yaml-test-suite-gaps: the libyaml port becomes the engine on main 2026-07-05 00:23:48 +02:00
UnkeyedCodingFixtures.swift test(coding): add sequence fixtures and contract gate 2026-06-05 12:33:09 +02:00
UnkeyedCodingTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
UnkeyedContainerEdgeTests.swift test: cover numeric ladder, NaN hashing, unkeyed edges, error paths 2026-06-26 07:50:08 +02:00
UnkeyedEncodingFixtures.swift Add machine-readable validation reports 2026-06-05 20:39:32 +02:00
UnkeyedFailureFixtures.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
UnsupportedYAMLGapsFixtures.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationBuiltinRuleTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationCheckMachineryTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationCombinatorTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationConfigurationTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationCorpusFixtures.swift feat(parser): expand YAML merge keys 2026-06-05 15:12:55 +02:00
ValidationCorpusSupport.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationCorpusTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationCoverageMetaTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationFailureFixtureTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationModelTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationModeTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationReportTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationTests.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValidationTestSupport.swift refactor(validation): rename framework to match the validation idiom 2026-07-12 18:10:00 +02:00
ValueHashableTests.swift test: cover numeric ladder, NaN hashing, unkeyed edges, error paths 2026-06-26 07:50:08 +02:00
ValuePropertyIndentationTests.swift fix(parsing): reject a later under-indented property on a mapping value 2026-06-28 01:44:48 +02:00
YAMLDirectiveTests.swift fix(parsing): accept a higher-minor %YAML version 2026-06-29 02:34:55 +02:00
YAMLTestSuiteConformanceTests.swift style: bring four files back under the swiftformat gate 2026-07-12 13:29:05 +02:00
YAMLTestSuiteGapsSupport.swift style: bring four files back under the swiftformat gate 2026-07-12 13:29:05 +02:00
YAMLTestSuiteGapsTests.swift style: bring four files back under the swiftformat gate 2026-07-12 13:29:05 +02:00