Skip to content

Commit

Permalink
Fix new csv_encoder fuzzer issue
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Jan 26, 2025
1 parent ae3c018 commit b6c0920
Showing 1 changed file with 123 additions and 3 deletions.
126 changes: 123 additions & 3 deletions include/jsoncons_ext/csv/csv_encoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,18 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
enum class stack_item_kind
{
flat_row_mapping,
stream_flat_row_mapping,
row_mapping,
flat_object,
flat_row,
stream_flat_row,
unmapped,
object,
row,
column_mapping,
column,
multivalued_field,
stream_multivalued_field,
column_multivalued_field
};

Expand Down Expand Up @@ -309,6 +312,9 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
case stack_item_kind::flat_row_mapping:
stack_.emplace_back(stack_item_kind::flat_object);
break;
case stack_item_kind::stream_flat_row_mapping:
stack_.emplace_back(stack_item_kind::flat_object);
break;
case stack_item_kind::row_mapping:
stack_.emplace_back(stack_item_kind::object);
return true;
Expand Down Expand Up @@ -348,7 +354,7 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
{
case stack_item_kind::flat_object:
case stack_item_kind::object:
if (parent(stack_).item_kind_ == stack_item_kind::row_mapping || parent(stack_).item_kind_ == stack_item_kind::flat_row_mapping)
if (parent(stack_).item_kind_ == stack_item_kind::row_mapping || parent(stack_).item_kind_ == stack_item_kind::flat_row_mapping || parent(stack_).item_kind_ == stack_item_kind::stream_flat_row_mapping)
{
if (stack_[0].count_ == 0)
{
Expand Down Expand Up @@ -497,7 +503,14 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
{
if (flat_)
{
stack_.emplace_back(stack_item_kind::flat_row_mapping);
if (has_column_mapping_ || has_column_names_)
{
stack_.emplace_back(stack_item_kind::flat_row_mapping);
}
else
{
stack_.emplace_back(stack_item_kind::stream_flat_row_mapping);
}
}
else
{
Expand Down Expand Up @@ -537,6 +550,9 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
case stack_item_kind::flat_row_mapping:
stack_.emplace_back(stack_item_kind::flat_row);
break;
case stack_item_kind::stream_flat_row_mapping:
stack_.emplace_back(stack_item_kind::stream_flat_row);
break;
case stack_item_kind::row_mapping:
stack_.emplace_back(stack_item_kind::row);
break;
Expand All @@ -558,6 +574,17 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
stack_.emplace_back(stack_item_kind::multivalued_field);
}
break;
case stack_item_kind::stream_flat_row:
if (subfield_delimiter_ == char_type())
{
stack_.emplace_back(stack_item_kind::unmapped);
}
else
{
value_buffer_.clear();
stack_.emplace_back(stack_item_kind::stream_multivalued_field);
}
break;
case stack_item_kind::flat_object:
if (subfield_delimiter_ == char_type())
{
Expand All @@ -579,6 +606,7 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
}
break;
case stack_item_kind::multivalued_field:
case stack_item_kind::stream_multivalued_field:
stack_.emplace_back(stack_item_kind::unmapped);
break;
case stack_item_kind::column_mapping:
Expand Down Expand Up @@ -612,6 +640,7 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
{
case stack_item_kind::row_mapping:
case stack_item_kind::flat_row_mapping:
case stack_item_kind::stream_flat_row_mapping:
break;
case stack_item_kind::flat_row:
if (parent(stack_).item_kind_ == stack_item_kind::flat_row_mapping)
Expand Down Expand Up @@ -651,15 +680,30 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
sink_.append(line_delimiter_.data(), line_delimiter_.length());
}
break;
case stack_item_kind::stream_flat_row:
if (parent(stack_).item_kind_ == stack_item_kind::stream_flat_row_mapping)
{
sink_.append(line_delimiter_.data(), line_delimiter_.length());
}
break;
case stack_item_kind::multivalued_field:
{
auto it = column_path_value_map_.find(stack_[stack_.size() - 2].column_path_);
auto it = column_path_value_map_.find(parent(stack_).column_path_);
if (it != column_path_value_map_.end())
{
it->second = value_buffer_;
}
break;
}
case stack_item_kind::stream_multivalued_field:
{
if (parent(stack_).count_ > 0)
{
sink_.push_back(field_delimiter_);
}
sink_.append(value_buffer_.data(), value_buffer_.size());
break;
}
case stack_item_kind::row:
if (parent(stack_).item_kind_ == stack_item_kind::row_mapping)
{
Expand Down Expand Up @@ -819,8 +863,20 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
}
break;
}
case stack_item_kind::stream_flat_row:
{
if (stack_.back().count_ > 0)
{
sink_.push_back(field_delimiter_);
}
value_buffer_.clear();
write_null_value(value_buffer_);
sink_.append(value_buffer_.data(), value_buffer_.size());
break;
}
case stack_item_kind::column_multivalued_field:
case stack_item_kind::multivalued_field:
case stack_item_kind::stream_multivalued_field:
{
if (!value_buffer_.empty())
{
Expand Down Expand Up @@ -877,8 +933,20 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
}
break;
}
case stack_item_kind::stream_flat_row:
{
if (stack_.back().count_ > 0)
{
sink_.push_back(field_delimiter_);
}
value_buffer_.clear();
write_string_value(sv, value_buffer_);
sink_.append(value_buffer_.data(), value_buffer_.size());
break;
}
case stack_item_kind::column_multivalued_field:
case stack_item_kind::multivalued_field:
case stack_item_kind::stream_multivalued_field:
{
if (!value_buffer_.empty())
{
Expand Down Expand Up @@ -992,8 +1060,24 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
}
break;
}
case stack_item_kind::stream_flat_row:
{
if (stack_.back().count_ > 0)
{
sink_.push_back(field_delimiter_);
}
value_buffer_.clear();
write_double_value(val, context, value_buffer_, ec);
if (ec)
{
return false;
}
sink_.append(value_buffer_.data(), value_buffer_.size());
break;
}
case stack_item_kind::multivalued_field:
case stack_item_kind::column_multivalued_field:
case stack_item_kind::stream_multivalued_field:
{
if (!value_buffer_.empty())
{
Expand Down Expand Up @@ -1052,8 +1136,20 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
}
break;
}
case stack_item_kind::stream_flat_row:
{
if (stack_.back().count_ > 0)
{
sink_.push_back(field_delimiter_);
}
value_buffer_.clear();
write_int64_value(val, value_buffer_);
sink_.append(value_buffer_.data(), value_buffer_.size());
break;
}
case stack_item_kind::column_multivalued_field:
case stack_item_kind::multivalued_field:
case stack_item_kind::stream_multivalued_field:
{
if (!value_buffer_.empty())
{
Expand Down Expand Up @@ -1112,8 +1208,20 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
}
break;
}
case stack_item_kind::stream_flat_row:
{
if (stack_.back().count_ > 0)
{
sink_.push_back(field_delimiter_);
}
value_buffer_.clear();
write_uint64_value(val, value_buffer_);
sink_.append(value_buffer_.data(), value_buffer_.size());
break;
}
case stack_item_kind::multivalued_field:
case stack_item_kind::column_multivalued_field:
case stack_item_kind::stream_multivalued_field:
{
if (!value_buffer_.empty())
{
Expand Down Expand Up @@ -1169,8 +1277,20 @@ class basic_csv_encoder final : public basic_json_visitor<CharT>
}
break;
}
case stack_item_kind::stream_flat_row:
{
if (stack_.back().count_ > 0)
{
sink_.push_back(field_delimiter_);
}
value_buffer_.clear();
write_bool_value(val, value_buffer_);
sink_.append(value_buffer_.data(), value_buffer_.size());
break;
}
case stack_item_kind::multivalued_field:
case stack_item_kind::column_multivalued_field:
case stack_item_kind::stream_multivalued_field:
{
if (!value_buffer_.empty())
{
Expand Down

0 comments on commit b6c0920

Please sign in to comment.