diff --git a/changelog/current.md b/changelog/current.md index 7f4e2cb1c..5c0bd0852 100644 --- a/changelog/current.md +++ b/changelog/current.md @@ -2,3 +2,15 @@ - `file_put_contents()` - `file_get_contents()` - `stdin_get_contents()` +- [PR#609](https://github.com/biojppm/rapidyaml/pull/609): fix misbuild in gcc 16. +- [PR#610](https://github.com/biojppm/rapidyaml/pull/610) fix clang warnings: `-Weverything`. Thanks @TedLyngmo ! +- [PR#613](https://github.com/biojppm/rapidyaml/pull/613) fix [#612](https://github.com/biojppm/rapidyaml/pull/612) fix parse error on whitespace-only after block scalar indicators `|` or `>`: + ```yaml + space after: >\space + tag after: >\t + ``` + + +### Thanks + +- @TedLyngmo diff --git a/src/c4/yml/parse_engine.def.hpp b/src/c4/yml/parse_engine.def.hpp index 8d6f97eee..74e42475d 100644 --- a/src/c4/yml/parse_engine.def.hpp +++ b/src/c4/yml/parse_engine.def.hpp @@ -2293,30 +2293,38 @@ void ParseEngine::_scan_block(ScannedBlock *C4_RESTRICT sb, size_t { _RYML_ASSERT_PARSE_(m_evt_handler->m_stack.m_callbacks, s.begins_with_any("|>"), m_evt_handler->m_curr->pos); csubstr t = s.sub(1); - _c4dbgpf("blck: spec is multichar: '{}'", t); + _c4dbgpf("blck: spec is multichar: {}", _prs(t)); _RYML_ASSERT_PARSE_(m_evt_handler->m_stack.m_callbacks, t.len >= 1, m_evt_handler->m_curr->pos); size_t pos = t.first_of("-+"); - _c4dbgpf("blck: spec chomp char at {}", pos); + _c4dbgpf("blck: spec chomp char: pos={}", pos); if(pos != npos) { + _c4dbgpf("blck: spec chomp char: {}", _c4prc(t[pos])); if(t[pos] == '-') + { + _c4dbgp("blck: chomp=STRIP"); chomp = CHOMP_STRIP; + } else if(t[pos] == '+') + { + _c4dbgp("blck: chomp=KEEP"); chomp = CHOMP_KEEP; + } if(pos == 0) t = t.sub(1); else t = t.first(pos); + _c4dbgpf("blck: spec is now: {}", _prs(t)); } // from here to the end, only digits are considered pos = t.first_not_of("0123456789"); - csubstr digits = t.first(pos); - if( ! digits.empty()) + csubstr rest = t.first(pos); + if( ! rest.empty()) { - if(C4_UNLIKELY(digits.len > 1)) + _c4dbgpf("blck: parse indentation digits: {}", _prs(rest)); + if(C4_UNLIKELY(rest.len > 1)) _c4err("parse error: invalid indentation"); - _c4dbgpf("blck: parse indentation digits: [{}]~~~{}~~~", digits.len, digits); - if(C4_UNLIKELY( ! c4::atou(digits, &indentation))) + if(C4_UNLIKELY( ! c4::atou(rest, &indentation))) _c4err("parse error: could not read indentation as decimal"); // LCOV_EXCL_LINE if(C4_UNLIKELY( ! indentation)) _c4err("parse error: null indentation"); @@ -2325,7 +2333,9 @@ void ParseEngine::_scan_block(ScannedBlock *C4_RESTRICT sb, size_t } else { - if(C4_UNLIKELY(t.len && (!t.begins_with_any(" \t") || !t.sub(pos).triml(" \t").begins_with('#')))) + rest = t.triml(" \t"); + _c4dbgpf("blck: digits empty. t={} trimmed={} iscomm={} t.iscomm={}", _prs(t), _prs(rest), rest.begins_with('#'), t.begins_with('#')); + if(C4_UNLIKELY(rest.len && (rest.str[0] != '#' || t.str[0] == '#'))) _c4err("parse error: invalid token"); } } diff --git a/test/test_lib/test_case.hpp b/test/test_lib/test_case.hpp index 95575fedc..af2336b13 100644 --- a/test/test_lib/test_case.hpp +++ b/test/test_lib/test_case.hpp @@ -10,6 +10,7 @@ #include "c4/format.hpp" #include #include +#include #include #endif diff --git a/test/test_scalar_literal.cpp b/test/test_scalar_literal.cpp index bb13655bd..156053cc9 100644 --- a/test/test_scalar_literal.cpp +++ b/test/test_scalar_literal.cpp @@ -1148,6 +1148,13 @@ TEST(block_literal, indentation_indicator_1) t = parse_in_arena("--- |#"); }); } + { + SCOPED_TRACE("here"); + Tree t; + ExpectError::check_error_parse(&t, [&t]{ + t = parse_in_arena("--- >#"); + }); + } { SCOPED_TRACE("here"); Tree t = parse_in_arena("--- | # comment\n a"); @@ -1249,6 +1256,25 @@ A ($api-model): } +TEST(block_literal, github612) +{ + for(const char blockchar : {'|', '>'}) + { + RYML_TRACE_FMT("blockchar={}", blockchar); + for(const char *ws : {"", " ", "\t", " ", "\t\t\t", " \t ", "\t \t", " #comment", "\t#comment"}) + { + csubstr fmt = "\n" + "- type: string" "\n" + " description: {}{}" "\n"; + std::string yaml = formatrs(fmt, blockchar, ws); + RYML_TRACE_FMT("ws={}\nyaml={}", blockchar, escaped_scalar(to_csubstr(yaml))); + const Tree t = parse_in_place(to_substr(yaml)); + EXPECT_EQ(t[0]["description"].val(), ""); + } + } +} + + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //-----------------------------------------------------------------------------