Skip to content

Commit

Permalink
[fix] empty scalars: fix behavior with ambiguous (non)null empty scalars
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed Jul 4, 2022
1 parent 01502fd commit ee77ea0
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 11 deletions.
6 changes: 6 additions & 0 deletions src/c4/yml/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ class RYML_EXPORT NodeRef
m_tree->_set_val(m_id, s);
return s.len;
}
size_t set_val_serialized(std::nullptr_t)
{
_C4RV();
m_tree->_set_val(m_id, csubstr{});
return 0;
}

/** encode a blob as base64, then assign the result to the node's key
* @return the size of base64-encoded blob */
Expand Down
51 changes: 41 additions & 10 deletions src/c4/yml/tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,24 +968,53 @@ class RYML_EXPORT Tree
{
substr rem(m_arena.sub(m_arena_pos));
size_t num = to_chars(rem, a);

if(num == 0 && m_arena.str == nullptr)
if(num > rem.len)
{
// Arena is empty and we want to store a zero-length string.
// Even though the string has zero length, we need some "memory" to
// store a non-nullptr string
rem = _grow_arena(1);
rem = _grow_arena(num);
num = to_chars(rem, a);
RYML_ASSERT(num <= rem.len);
}
else if(num > rem.len)
rem = _request_span(num);
return rem;
}

/** serialize the given csubstr to the tree's arena, growing the arena as
* needed to accomodate the serialization.
* @note Growing the arena may cause relocation of the entire
* existing arena, and thus change the contents of existing individual nodes.
* @see alloc_arena() */
csubstr to_arena(csubstr a)
{
substr rem(m_arena.sub(m_arena_pos));
size_t num = to_chars(rem, a);
if(num > rem.len)
{
rem = _grow_arena(num);
num = to_chars(rem, a);
RYML_ASSERT(num <= rem.len);
}

else if(num == 0u)
{
if(a.str != nullptr && m_arena.str == nullptr)
{
// Arena is empty and we want to store a non-null
// zero-length string.
// Even though the string has zero length, we need
// some "memory" to store a non-nullptr string
rem = _grow_arena(1);
}
else if(a.str == nullptr)
{
return csubstr{};
}
}
rem = _request_span(num);
return rem;
}
csubstr to_arena(std::nullptr_t)
{
return csubstr{};
}

/** serialize the given floating-point variable to the tree's arena, growing it as
* needed to accomodate the serialization.
Expand Down Expand Up @@ -1031,7 +1060,8 @@ class RYML_EXPORT Tree

/** grow the tree's string arena by the given size and return a substr
* of the added portion
* @note Growing the arena may cause relocation of the entire
* @note This operation has a potential complexity of O(numNodes).
* Growing the arena may cause relocation of the entire
* existing arena, and thus change the contents of individual nodes. */
substr alloc_arena(size_t sz)
{
Expand All @@ -1042,7 +1072,8 @@ class RYML_EXPORT Tree
}

/** ensure the tree's internal string arena is at least the given capacity
* @note Growing the arena may cause relocation of the entire
* @note This operation has a potential complexity of O(numNodes).
* Growing the arena may cause relocation of the entire
* existing arena, and thus change the contents of individual nodes. */
void reserve_arena(size_t arena_cap)
{
Expand Down
4 changes: 3 additions & 1 deletion test/test_empty_scalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
namespace c4 {
namespace yml {

// See also issue 263: https://github.com/biojppm/rapidyaml/issues/263
// See also:
// https://github.com/biojppm/rapidyaml/issues/263
// https://github.com/biojppm/rapidyaml/pulls/264

C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wuseless-cast")

Expand Down

0 comments on commit ee77ea0

Please sign in to comment.