diff --git a/include/ss/converter.hpp b/include/ss/converter.hpp index 1977fe5..5058df5 100644 --- a/include/ss/converter.hpp +++ b/include/ss/converter.hpp @@ -269,6 +269,7 @@ private: void handle_error_multiline_limit_reached() { constexpr static auto error_msg = "multiline limit reached"; + splitter_.unterminated_quote_ = false; if constexpr (string_error) { error_.clear(); diff --git a/include/ss/parser.hpp b/include/ss/parser.hpp index 75b9267..e800593 100644 --- a/include/ss/parser.hpp +++ b/include/ss/parser.hpp @@ -789,7 +789,8 @@ private: } if (!append_next_line_to_buffer(next_line_buffer_, - next_line_size_)) { + next_line_size_, + next_line_buffer_size_)) { next_line_converter_.handle_error_unterminated_escape(); return; } @@ -807,7 +808,8 @@ private: } if (!append_next_line_to_buffer(next_line_buffer_, - next_line_size_)) { + next_line_size_, + next_line_buffer_size_)) { next_line_converter_.handle_error_unterminated_quote(); return; } @@ -818,8 +820,9 @@ private: return; } - if (!append_next_line_to_buffer(next_line_buffer_, - next_line_size_)) { + if (!append_next_line_to_buffer( + next_line_buffer_, next_line_size_, + next_line_buffer_size_)) { next_line_converter_ .handle_error_unterminated_escape(); return; @@ -863,13 +866,14 @@ private: return next_line_converter_.unterminated_quote(); } - void undo_remove_eol(char* buffer, size_t& string_end) { - if (crlf_) { - std::copy_n("\r\n", 2, buffer + string_end); - string_end += 2; - } else { - std::copy_n("\n", 1, buffer + string_end); - string_end += 1; + void undo_remove_eol(char* buffer, size_t& line_size, + size_t buffer_size) { + if (crlf_ && buffer_size >= line_size + 2) { + std::copy_n("\r\n", 2, buffer + line_size); + line_size += 2; + } else if (buffer_size > line_size) { + std::copy_n("\n", 1, buffer + line_size); + line_size += 1; } } @@ -903,8 +907,9 @@ private: first_size += second_size; } - bool append_next_line_to_buffer(char*& buffer, size_t& size) { - undo_remove_eol(buffer, size); + bool append_next_line_to_buffer(char*& buffer, size_t& line_size, + size_t buffer_size) { + undo_remove_eol(buffer, line_size, buffer_size); chars_read_ = curr_char_; auto [next_ssize, eof] = @@ -917,8 +922,8 @@ private: ++line_number_; size_t next_size = remove_eol(helper_buffer_, next_ssize); - realloc_concat(buffer, size, next_line_buffer_size_, helper_buffer_, - next_size); + realloc_concat(buffer, line_size, next_line_buffer_size_, + helper_buffer_, next_size); return true; } diff --git a/ssp.hpp b/ssp.hpp index e6b4b76..b0c4b1b 100644 --- a/ssp.hpp +++ b/ssp.hpp @@ -2021,6 +2021,7 @@ private: void handle_error_multiline_limit_reached() { constexpr static auto error_msg = "multiline limit reached"; + splitter_.unterminated_quote_ = false; if constexpr (string_error) { error_.clear(); @@ -3024,7 +3025,8 @@ private: } if (!append_next_line_to_buffer(next_line_buffer_, - next_line_size_)) { + next_line_size_, + next_line_buffer_size_)) { next_line_converter_.handle_error_unterminated_escape(); return; } @@ -3042,7 +3044,8 @@ private: } if (!append_next_line_to_buffer(next_line_buffer_, - next_line_size_)) { + next_line_size_, + next_line_buffer_size_)) { next_line_converter_.handle_error_unterminated_quote(); return; } @@ -3053,8 +3056,9 @@ private: return; } - if (!append_next_line_to_buffer(next_line_buffer_, - next_line_size_)) { + if (!append_next_line_to_buffer( + next_line_buffer_, next_line_size_, + next_line_buffer_size_)) { next_line_converter_ .handle_error_unterminated_escape(); return; @@ -3098,13 +3102,14 @@ private: return next_line_converter_.unterminated_quote(); } - void undo_remove_eol(char* buffer, size_t& string_end) { - if (crlf_) { - std::copy_n("\r\n", 2, buffer + string_end); - string_end += 2; - } else { - std::copy_n("\n", 1, buffer + string_end); - string_end += 1; + void undo_remove_eol(char* buffer, size_t& line_size, + size_t buffer_size) { + if (crlf_ && buffer_size >= line_size + 2) { + std::copy_n("\r\n", 2, buffer + line_size); + line_size += 2; + } else if (buffer_size > line_size) { + std::copy_n("\n", 1, buffer + line_size); + line_size += 1; } } @@ -3138,8 +3143,9 @@ private: first_size += second_size; } - bool append_next_line_to_buffer(char*& buffer, size_t& size) { - undo_remove_eol(buffer, size); + bool append_next_line_to_buffer(char*& buffer, size_t& line_size, + size_t buffer_size) { + undo_remove_eol(buffer, line_size, buffer_size); chars_read_ = curr_char_; auto [next_ssize, eof] = @@ -3152,8 +3158,8 @@ private: ++line_number_; size_t next_size = remove_eol(helper_buffer_, next_ssize); - realloc_concat(buffer, size, next_line_buffer_size_, helper_buffer_, - next_size); + realloc_concat(buffer, line_size, next_line_buffer_size_, + helper_buffer_, next_size); return true; } diff --git a/test/test_parser1_3.cpp b/test/test_parser1_3.cpp index 07147b6..e1f9b6e 100644 --- a/test/test_parser1_3.cpp +++ b/test/test_parser1_3.cpp @@ -16,13 +16,14 @@ TEST_CASE_TEMPLATE("test multiline restricted", T, ParserOptionCombinations) { out << "5,6,just\\\n\\\nstrings" << std::endl; #endif out << "7,8,ju\\\n\\\n\\\nnk" << std::endl; + out << "99,100,\"\n\n\n\n" << std::endl; out << "9,10,\"just\\\n\nstrings\"" << std::endl; out << "11,12,\"ju\\\n|\n\n\n\n\nk\"" << std::endl; out << "13,14,\"ju\\\n\\\n15,16\"\\\n\\\\\n\nnk\"" << std::endl; out << "17,18,\"ju\\\n\\\n\\\n\\\\\n\nnk\"" << std::endl; out << "19,20,just strings" << std::endl; } - auto bad_lines = 15; + auto bad_lines = 20; auto num_errors = 0; auto [p, _] =