Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eternal loop in csv parser #220

Closed
DavidKorczynski opened this issue Apr 6, 2020 · 2 comments
Closed

eternal loop in csv parser #220

DavidKorczynski opened this issue Apr 6, 2020 · 2 comments

Comments

@DavidKorczynski
Copy link
Contributor

Hi,
The following small program triggers what seems to be an eternal loop in:

#include <stdio.h>
#include <jsoncons_ext/csv/csv.hpp>
#include <jsoncons/json_reader.hpp>

using namespace jsoncons;

int main()
{
        char data[4] = {'\x22', '\x22', '\x01', '\x0a'};
        int size = 4;
        std::string input(reinterpret_cast<const char*>(data), size);
        json_decoder<ojson> decoder;
        csv::csv_options options;
        options.assume_header(true);
        options.mapping(csv::mapping_kind::n_rows);
        try {
                csv::csv_reader reader1(input, decoder, options);
                reader1.read();
        }
        catch(jsoncons::ser_error e) {}
        catch(jsoncons::json_runtime_error<std::runtime_error> e) {}

        return 0;
}

From what I can tell, the eternal loop happens in parse_some and this code specifically:

        for (; (input_ptr_ < local_input_end) && more_;)
        {
            CharT curr_char = *input_ptr_;

            switch (state_) 

            ....
            ....

                case csv_parse_state::between_values:
                    switch (curr_char)
                    {
                        case '\r':
                        case '\n':
                        {
                            if (options_.trim_leading() || options_.trim_trailing())
                            {
                                trim_string_buffer(options_.trim_leading(),options_.trim_trailing());
                            }
                            if (!(options_.ignore_empty_values() && buffer_.empty()))
                            {
                                before_value(ec);
                                state_ = csv_parse_state::before_last_quoted_field;
                            }
                            else
                            {
                                state_ = csv_parse_state::end_record;
                            }
                            break;
                        }
                        default:
                            if (curr_char == options_.field_delimiter())
                            {
                                if (options_.trim_leading() || options_.trim_trailing())
                                {
                                    trim_string_buffer(options_.trim_leading(),options_.trim_trailing());
                                }
                                before_value(ec);
                                state_ = csv_parse_state::before_quoted_field;
                            }
                            else if (options_.subfield_delimiter() != char_type() && curr_char == options_.subfield_delimiter())
                            {
                                if (options_.trim_leading() || options_.trim_trailing())
                                {
                                    trim_string_buffer(options_.trim_leading(),options_.trim_trailing());
                                }
                                before_value(ec);
                                state_ = csv_parse_state::before_quoted_subfield;
                            }
                            break;
                    }
                    break;
        }
    }

where the execution will keep going into case csv_parse::between_values and then go into the default case in the switch, where both the if and else if statements will be skipped.

@danielaparker
Copy link
Owner

Thanks for reporting. Fixed on master.

@danielaparker
Copy link
Owner

Fixed in v0.151.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants