Skip to content

Commit 021db4f

Browse files
committed
Ensure parse error on nested maps opening on the same line
1 parent 0bfb286 commit 021db4f

6 files changed

Lines changed: 138 additions & 3 deletions

File tree

changelog/current.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
## Fixes
33

4-
- [PR#501](https://github.com/biojppm/rapidyaml/pull/501): fix missing tag in `- !!seq []`
4+
- [PR#503](https://github.com/biojppm/rapidyaml/pull/503): ensure parse error on `a: b: c` and similar cases containing nested maps opening on the same line.
55
- [PR#502](https://github.com/biojppm/rapidyaml/pull/502): fix parse errors or missing tags:
66
- missing tags in empty documents:
77
```yaml
@@ -26,3 +26,4 @@
2626
:
2727
!tag : !tag
2828
```
29+
- [PR#501](https://github.com/biojppm/rapidyaml/pull/501): fix missing tag in `- !!seq []`.

src/c4/yml/parse_engine.def.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ ParseEngine<EventHandler>::ParseEngine(EventHandler *evt_handler, ParserOptions
263263
, m_pending_tags()
264264
, m_was_inside_qmrk(false)
265265
, m_doc_empty(false)
266+
, m_prev_colon(npos)
266267
, m_encoding(NOBOM)
267268
, m_newline_offsets()
268269
, m_newline_offsets_size(0)
@@ -282,6 +283,7 @@ ParseEngine<EventHandler>::ParseEngine(ParseEngine &&that) noexcept
282283
, m_pending_tags(that.m_pending_tags)
283284
, m_was_inside_qmrk(false)
284285
, m_doc_empty(false)
286+
, m_prev_colon(npos)
285287
, m_encoding(NOBOM)
286288
, m_newline_offsets(that.m_newline_offsets)
287289
, m_newline_offsets_size(that.m_newline_offsets_size)
@@ -301,6 +303,7 @@ ParseEngine<EventHandler>::ParseEngine(ParseEngine const& that)
301303
, m_pending_tags(that.m_pending_tags)
302304
, m_was_inside_qmrk(false)
303305
, m_doc_empty(false)
306+
, m_prev_colon(npos)
304307
, m_encoding(NOBOM)
305308
, m_newline_offsets()
306309
, m_newline_offsets_size()
@@ -328,6 +331,7 @@ ParseEngine<EventHandler>& ParseEngine<EventHandler>::operator=(ParseEngine &&th
328331
m_pending_tags = that.m_pending_tags;
329332
m_was_inside_qmrk = that.m_was_inside_qmrk;
330333
m_doc_empty = that.m_doc_empty;
334+
m_prev_colon = that.m_prev_colon;
331335
m_encoding = that.m_encoding;
332336
m_newline_offsets = (that.m_newline_offsets);
333337
m_newline_offsets_size = (that.m_newline_offsets_size);
@@ -351,6 +355,7 @@ ParseEngine<EventHandler>& ParseEngine<EventHandler>::operator=(ParseEngine cons
351355
m_pending_tags = that.m_pending_tags;
352356
m_was_inside_qmrk = that.m_was_inside_qmrk;
353357
m_doc_empty = that.m_doc_empty;
358+
m_prev_colon = that.m_prev_colon;
354359
m_encoding = that.m_encoding;
355360
if(that.m_newline_offsets_capacity > m_newline_offsets_capacity)
356361
_resize_locations(that.m_newline_offsets_capacity);
@@ -374,6 +379,7 @@ void ParseEngine<EventHandler>::_clr()
374379
m_pending_tags = {};
375380
m_was_inside_qmrk = false;
376381
m_doc_empty = true;
382+
m_prev_colon = npos;
377383
m_encoding = NOBOM;
378384
m_newline_offsets = {};
379385
m_newline_offsets_size = {};
@@ -404,6 +410,7 @@ void ParseEngine<EventHandler>::_reset()
404410
m_pending_tags = {};
405411
m_doc_empty = true;
406412
m_was_inside_qmrk = false;
413+
m_prev_colon = npos;
407414
m_encoding = NOBOM;
408415
if(m_options.locations())
409416
{
@@ -4116,6 +4123,18 @@ void ParseEngine<EventHandler>::_handle_flow_skip_whitespace()
41164123
//-----------------------------------------------------------------------------
41174124

41184125

4126+
template<class EventHandler>
4127+
void ParseEngine<EventHandler>::_handle_colon()
4128+
{
4129+
size_t curr = m_evt_handler->m_curr->pos.line;
4130+
if(m_prev_colon != npos)
4131+
{
4132+
if(curr == m_prev_colon)
4133+
_c4err("two colons on same line");
4134+
}
4135+
m_prev_colon = curr;
4136+
}
4137+
41194138
template<class EventHandler>
41204139
void ParseEngine<EventHandler>::_add_annotation(Annotation *C4_RESTRICT dst, csubstr str, size_t indentation, size_t line)
41214140
{
@@ -5705,6 +5724,7 @@ void ParseEngine<EventHandler>::_handle_seq_block()
57055724
_c4dbgp("seqblck[RVAL]: start mapblck, set scalar as key");
57065725
addrem_flags(RNXT, RVAL);
57075726
_handle_annotations_before_start_mapblck(startline);
5727+
_handle_colon();
57085728
m_evt_handler->begin_map_val_block();
57095729
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
57105730
csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc); // KEY!
@@ -5731,6 +5751,7 @@ void ParseEngine<EventHandler>::_handle_seq_block()
57315751
_c4dbgp("seqblck[RVAL]: start mapblck, set scalar as key");
57325752
addrem_flags(RNXT, RVAL);
57335753
_handle_annotations_before_start_mapblck(startline);
5754+
_handle_colon();
57345755
m_evt_handler->begin_map_val_block();
57355756
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
57365757
csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc); // KEY!
@@ -5781,6 +5802,7 @@ void ParseEngine<EventHandler>::_handle_seq_block()
57815802
_c4dbgp("seqblck[RVAL]: start mapblck, set scalar as key");
57825803
addrem_flags(RNXT, RVAL);
57835804
_handle_annotations_before_start_mapblck(startline);
5805+
_handle_colon();
57845806
m_evt_handler->begin_map_val_block();
57855807
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
57865808
csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref); // KEY!
@@ -5858,6 +5880,7 @@ void ParseEngine<EventHandler>::_handle_seq_block()
58585880
_c4dbgp("seqblck[RVAL]: start child mapblck with empty key");
58595881
addrem_flags(RNXT, RVAL);
58605882
_handle_annotations_before_start_mapblck(startline);
5883+
_handle_colon();
58615884
m_evt_handler->begin_map_val_block();
58625885
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
58635886
m_evt_handler->set_key_scalar_plain_empty();
@@ -6534,6 +6557,7 @@ void ParseEngine<EventHandler>::_handle_map_block()
65346557
_c4dbgp("mapblck[RVAL]: start new block map, set scalar as key");
65356558
_handle_annotations_before_start_mapblck(startline);
65366559
addrem_flags(RNXT, RVAL);
6560+
_handle_colon();
65376561
m_evt_handler->begin_map_val_block();
65386562
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
65396563
csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc); // KEY!
@@ -6574,6 +6598,7 @@ void ParseEngine<EventHandler>::_handle_map_block()
65746598
_c4dbgp("mapblck[RVAL]: start new block map, set scalar as key");
65756599
_handle_annotations_before_start_mapblck(startline);
65766600
addrem_flags(RNXT, RVAL);
6601+
_handle_colon();
65776602
m_evt_handler->begin_map_val_block();
65786603
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
65796604
csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc); // KEY!
@@ -6635,6 +6660,7 @@ void ParseEngine<EventHandler>::_handle_map_block()
66356660
_c4dbgpf("mapblck[RVAL]: start new block map, set scalar as key {}", m_evt_handler->m_curr->indref);
66366661
addrem_flags(RNXT, RVAL);
66376662
_handle_annotations_before_start_mapblck(startline);
6663+
_handle_colon();
66386664
m_evt_handler->begin_map_val_block();
66396665
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
66406666
csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref); // KEY!
@@ -6816,6 +6842,7 @@ void ParseEngine<EventHandler>::_handle_map_block()
68166842
_c4dbgp("mapblck[RVAL]: start val mapblck");
68176843
addrem_flags(RNXT, RVAL);
68186844
_handle_annotations_before_start_mapblck(startline);
6845+
_handle_colon();
68196846
m_evt_handler->begin_map_val_block();
68206847
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
68216848
m_evt_handler->set_key_scalar_plain_empty();
@@ -7549,6 +7576,7 @@ void ParseEngine<EventHandler>::_handle_unk()
75497576
m_evt_handler->check_trailing_doc_token();
75507577
_maybe_begin_doc();
75517578
_handle_annotations_before_start_mapblck(startline);
7579+
_handle_colon();
75527580
m_evt_handler->begin_map_val_block();
75537581
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
75547582
m_evt_handler->set_key_scalar_plain_empty();
@@ -7645,6 +7673,7 @@ void ParseEngine<EventHandler>::_handle_unk()
76457673
{
76467674
_c4dbgp("runk: start new block map, set scalar as key");
76477675
_handle_annotations_before_start_mapblck(startline);
7676+
_handle_colon();
76487677
m_evt_handler->begin_map_val_block();
76497678
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
76507679
csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
@@ -7674,6 +7703,7 @@ void ParseEngine<EventHandler>::_handle_unk()
76747703
_c4dbgp("runk: start new block map, set double-quoted scalar as key");
76757704
_handle_annotations_before_start_mapblck(startline);
76767705
m_evt_handler->begin_map_val_block();
7706+
_handle_colon();
76777707
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
76787708
csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
76797709
m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
@@ -7742,6 +7772,7 @@ void ParseEngine<EventHandler>::_handle_unk()
77427772
{
77437773
_c4dbgp("runk: start new block map, set scalar as key");
77447774
_handle_annotations_before_start_mapblck(startline);
7775+
_handle_colon();
77457776
m_evt_handler->begin_map_val_block();
77467777
_handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
77477778
csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, startindent);

src/c4/yml/parse_engine.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ class ParseEngine
704704
size_t num_entries;
705705
};
706706

707+
void _handle_colon();
707708
void _add_annotation(Annotation *C4_RESTRICT dst, csubstr str, size_t indentation, size_t line);
708709
void _clear_annotations(Annotation *C4_RESTRICT dst);
709710
bool _has_pending_annotations() const { return m_pending_tags.num_entries || m_pending_anchors.num_entries; }
@@ -743,6 +744,7 @@ class ParseEngine
743744

744745
bool m_was_inside_qmrk;
745746
bool m_doc_empty = true;
747+
size_t m_prev_colon = npos;
746748

747749
Encoding_e m_encoding = UTF8;
748750

test/test_parse_engine_2_map.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,55 @@ ENGINE_TEST_ERRLOC(SimpleMapFlowErr0, Location(1,1,2), "{")
130130
ENGINE_TEST_ERRLOC(SimpleMapFlowErr1, Location(5,1,6), "{a: b")
131131

132132

133+
//-----------------------------------------------------------------------------
134+
135+
ENGINE_TEST_ERRLOC(SimpleMapBlockSameLine0Err, Location(5,1,6), "a: b: c")
136+
ENGINE_TEST_ERRLOC(SimpleMapBlockSameLine1Err, Location(5,1,6), "a: b: ")
137+
ENGINE_TEST_ERRLOC(SimpleMapBlockSameLine2Err, Location(5,1,6), "a: b:")
138+
ENGINE_TEST_ERRLOC(SimpleMapBlockSameLine3Err, Location(2,1,3), ": : :")
139+
ENGINE_TEST_ERRLOC(SimpleMapBlockSameLine4Err, Location(2,1,3), ": : : :")
140+
ENGINE_TEST_ERRLOC(SimpleMapBlockSameLine5Err, Location(9,1,10), "'a': 'b': 'c'")
141+
ENGINE_TEST_ERRLOC(SimpleMapBlockSameLine6Err, Location(9,1,10), "\"a\": \"b\": \"c\"")
142+
ENGINE_TEST(SimpleMapBlockSameLine7, (HAS_MULTILINE_SCALAR,
143+
""
144+
"? |-\n"
145+
" a\n"
146+
": b: c\n"
147+
"",
148+
""
149+
"? |-\n"
150+
" a\n"
151+
":\n"
152+
" b: c\n"
153+
""
154+
),
155+
""
156+
"+STR\n"
157+
"+DOC\n"
158+
"+MAP\n"
159+
"=VAL |a\n"
160+
"+MAP\n"
161+
"=VAL :b\n"
162+
"=VAL :c\n"
163+
"-MAP\n"
164+
"-MAP\n"
165+
"-DOC\n"
166+
"-STR\n")
167+
{
168+
___(ps.begin_stream());
169+
___(ps.begin_doc());
170+
___(ps.begin_map_val_block());
171+
___(ps.set_key_scalar_literal("a"));
172+
___(ps.begin_map_val_block());
173+
___(ps.set_key_scalar_plain("b"));
174+
___(ps.set_val_scalar_plain("c"));
175+
___(ps.end_map());
176+
___(ps.end_map());
177+
___(ps.end_doc());
178+
___(ps.end_stream());
179+
}
180+
181+
133182
//-----------------------------------------------------------------------------
134183

135184
ENGINE_TEST(SimpleMapBlock,

test/test_parse_engine_3_seq.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,60 @@ ENGINE_TEST(SeqSeqFlow,
444444
}
445445

446446

447+
ENGINE_TEST(SeqBlockSpace, (HAS_MULTILINE_SCALAR,
448+
""
449+
"- a\n"
450+
" - b\n"
451+
""
452+
,
453+
""
454+
"- a - b\n"
455+
""
456+
),
457+
"+STR\n"
458+
"+DOC\n"
459+
"+SEQ\n"
460+
"=VAL :a - b\n"
461+
"-SEQ\n"
462+
"-DOC\n"
463+
"-STR\n")
464+
{
465+
___(ps.begin_stream());
466+
___(ps.begin_doc());
467+
___(ps.begin_seq_val_block());
468+
___(ps.set_val_scalar_plain("a - b"));
469+
___(ps.end_seq());
470+
___(ps.end_doc());
471+
___(ps.end_stream());
472+
}
473+
474+
#ifdef RYML_FIX_THIS
475+
ENGINE_TEST(SeqBlockTab,
476+
(HAS_MULTILINE_SCALAR,
477+
""
478+
"- a\n"
479+
"\t- b\n"
480+
""
481+
),
482+
"+STR\n"
483+
"+DOC\n"
484+
"+SEQ\n"
485+
"=VAL :a - b\n"
486+
"-SEQ\n"
487+
"-DOC\n"
488+
"-STR\n")
489+
{
490+
___(ps.begin_stream());
491+
___(ps.begin_doc());
492+
___(ps.begin_seq_val_block());
493+
___(ps.set_val_scalar_plain("a - b"));
494+
___(ps.end_seq());
495+
___(ps.end_doc());
496+
___(ps.end_stream());
497+
}
498+
#endif
499+
500+
447501
//-----------------------------------------------------------------------------
448502

449503
ENGINE_TEST(SeqSeqBlock,

test/test_suite/test_suite_parts.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ constexpr const AllowedFailure allowed_failures[] = {
5454
_("Y79Y_008-error" , "TBD"),
5555
_("Y79Y_009-error" , "should not accept tab after ?"),
5656
_("YJV2-error" , "should not accept [-]"),
57-
_("ZCZ6-error" , "should not accept invalid mapping in plain single line value"),
58-
_("ZL4Z-error" , "TBD"),
5957
_("ZXT5-error" , "TBD"),
6058

6159

0 commit comments

Comments
 (0)