From 3696529f87bd5bf11c9a97ba0ca08c8b74624c61 Mon Sep 17 00:00:00 2001 From: sxrzh Date: Fri, 7 Aug 2026 21:18:59 +0800 Subject: [PATCH 1/5] fix indent-stack underflow for literal scalar with tag --- src/scanner.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/scanner.cpp b/src/scanner.cpp index 211e19697..3f8e7c03f 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -177,7 +177,15 @@ void Scanner::ScanNextToken() { // scalar if (!m_simpleKeys.empty() && m_simpleKeys.top().pKey->status == Token::UNVERIFIED) { + // if the top of the indents does not match the unverified simple key, + // just invalidate the simple key and do not pop indent to avoid crash. + // eg: an unverified key on a previous line, like issue #1475. + if (m_simpleKeys.top().pIndent && !m_indents.empty() && + m_indents.top() == m_simpleKeys.top().pIndent) { PopIndent(); + } else { + InvalidateSimpleKey(); + } } return ScanBlockScalar(); } From 9d342dcd2a4c990c9d3fabab07d77475cc907da6 Mon Sep 17 00:00:00 2001 From: sxrzh Date: Fri, 7 Aug 2026 21:19:16 +0800 Subject: [PATCH 2/5] add tests --- test/integration/handler_test.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/integration/handler_test.cpp b/test/integration/handler_test.cpp index fe389dbf9..3b291e889 100644 --- a/test/integration/handler_test.cpp +++ b/test/integration/handler_test.cpp @@ -73,6 +73,13 @@ TEST_F(HandlerTest, CommentOnNewlineOfMapValueWithManySpace) { Parse("key: value\n # comment"); } +// example from issue #1475: a stale simple key (from a plain scalar spanning +// a line break) must not pop an unrelated indent when parsing a block scalar +TEST_F(HandlerTest, LiteralScalarWithMultilineTag) { + EXPECT_THROW_PARSER_EXCEPTION(IgnoreParse("!\n: |\nb\n>\n|\n !\n>"), + ErrorMsg::END_OF_MAP); +} + // examples from issue #1163 TEST_F(HandlerTest, LiteralScalarWithTagAndLargeIndentation) { EXPECT_CALL(handler, OnDocumentStart(_)); From 03a1edfc97ad7aa5dfdc33ab79e2f2d7ceaa3ab2 Mon Sep 17 00:00:00 2001 From: sxrzh Date: Fri, 7 Aug 2026 22:32:33 +0800 Subject: [PATCH 3/5] correct name for the new test --- test/integration/handler_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/handler_test.cpp b/test/integration/handler_test.cpp index 3b291e889..13005df3e 100644 --- a/test/integration/handler_test.cpp +++ b/test/integration/handler_test.cpp @@ -75,7 +75,7 @@ TEST_F(HandlerTest, CommentOnNewlineOfMapValueWithManySpace) { // example from issue #1475: a stale simple key (from a plain scalar spanning // a line break) must not pop an unrelated indent when parsing a block scalar -TEST_F(HandlerTest, LiteralScalarWithMultilineTag) { +TEST_F(HandlerTest, LiteralScalarWithMultiLineUnverifiedPotentialSimpleKey) { EXPECT_THROW_PARSER_EXCEPTION(IgnoreParse("!\n: |\nb\n>\n|\n !\n>"), ErrorMsg::END_OF_MAP); } From 1516b1da69994e8a75416f26922b459ff6e5eda7 Mon Sep 17 00:00:00 2001 From: sxrzh Date: Fri, 7 Aug 2026 22:32:40 +0800 Subject: [PATCH 4/5] add guard for PopIndent --- include/yaml-cpp/exceptions.h | 2 ++ src/scanner.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/include/yaml-cpp/exceptions.h b/include/yaml-cpp/exceptions.h index 607055341..83a65d3b4 100644 --- a/include/yaml-cpp/exceptions.h +++ b/include/yaml-cpp/exceptions.h @@ -92,6 +92,8 @@ const char* const BAD_FILE = "bad file"; const char* const UNEXPECTED_TOKEN_AFTER_DOC = "unexpected token after end of document"; const char* const NON_UNIQUE_MAP_KEY = "map keys must be unique"; +const char* const INDENT_STACK_UNDERFLOW = "indentation stack underflow (please report this bug to yaml-cpp)"; + template inline const std::string KEY_NOT_FOUND_WITH_KEY( const T&, typename disable_if>::type* = 0) { diff --git a/src/scanner.cpp b/src/scanner.cpp index 3f8e7c03f..eb1dd755b 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -401,6 +401,9 @@ void Scanner::PopAllIndents() { } void Scanner::PopIndent() { + if (m_indents.empty()) { + ThrowParserException(ErrorMsg::INDENT_STACK_UNDERFLOW); + } const IndentMarker& indent = *m_indents.top(); m_indents.pop(); From 0931fc4221c2cc6d36f8c0d6a1ccf15b34d83473 Mon Sep 17 00:00:00 2001 From: sxrzh Date: Fri, 7 Aug 2026 22:39:50 +0800 Subject: [PATCH 5/5] fix comments --- src/scanner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scanner.cpp b/src/scanner.cpp index eb1dd755b..a0abd3b61 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -179,7 +179,7 @@ void Scanner::ScanNextToken() { m_simpleKeys.top().pKey->status == Token::UNVERIFIED) { // if the top of the indents does not match the unverified simple key, // just invalidate the simple key and do not pop indent to avoid crash. - // eg: an unverified key on a previous line, like issue #1475. + // eg: an unverified key crossing lines, like issue #1475. if (m_simpleKeys.top().pIndent && !m_indents.empty() && m_indents.top() == m_simpleKeys.top().pIndent) { PopIndent();