From e0a3c5384f5d7fefdd52aac7da9e2722b183a340 Mon Sep 17 00:00:00 2001 From: Henrique Date: Thu, 13 May 2021 11:51:07 -0300 Subject: [PATCH] csv: fix parse error of last empty field on unquoted line (#10083) --- vlib/encoding/csv/reader.v | 7 +++--- vlib/encoding/csv/reader_test.v | 39 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/vlib/encoding/csv/reader.v b/vlib/encoding/csv/reader.v index c0f3d46b89..28b0497014 100644 --- a/vlib/encoding/csv/reader.v +++ b/vlib/encoding/csv/reader.v @@ -134,7 +134,7 @@ fn (mut r Reader) read_record() ?[]string { need_read = false keep_raw = false } - if line[0] != `"` { // not quoted + if line.len == 0 || line[0] != `"` { // not quoted j := line.index(r.delimiter.ascii_str()) or { // last fields << line[..line.len] @@ -160,9 +160,10 @@ fn (mut r Reader) read_record() ?[]string { if next == r.delimiter { fields << line[..j] if j + 2 == line.len { - break + line = '' + } else { + line = line[j + 2..] } - line = line[j + 2..] continue } } diff --git a/vlib/encoding/csv/reader_test.v b/vlib/encoding/csv/reader_test.v index 86ecf96de2..b8958a3149 100644 --- a/vlib/encoding/csv/reader_test.v +++ b/vlib/encoding/csv/reader_test.v @@ -111,11 +111,50 @@ fn test_last_field_empty() { } else if row_count == 3 { assert row[0] == 'two' assert row[1] == 'second' + assert row[2] == '' } } assert row_count == 3 } +fn test_empty_fields_no_quotes() { + data := '1,2,3,4\n,6,7,8\n9,,11,12\n13,14,,16\n17,18,19,\n' + + mut csv_reader := csv.new_reader(data) + mut row_count := 0 + for { + row := csv_reader.read() or { break } + row_count++ + if row_count == 1 { + assert row[0] == '1' + assert row[1] == '2' + assert row[2] == '3' + assert row[3] == '4' + } else if row_count == 2 { + assert row[0] == '' + assert row[1] == '6' + assert row[2] == '7' + assert row[3] == '8' + } else if row_count == 3 { + assert row[0] == '9' + assert row[1] == '' + assert row[2] == '11' + assert row[3] == '12' + } else if row_count == 4 { + assert row[0] == '13' + assert row[1] == '14' + assert row[2] == '' + assert row[3] == '16' + } else if row_count == 5 { + assert row[0] == '17' + assert row[1] == '18' + assert row[2] == '19' + assert row[3] == '' + } + } + assert row_count == 5 +} + fn test_empty_line() { data := '"name","description","value"\n\n\n"one","first","1"\n\n"two","second",\n' mut csv_reader := csv.new_reader(data)