From d57ad3e4050f34812b90a312e1c36e27e3e9032c Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 19 Jul 2022 10:40:11 -0700 Subject: [PATCH] Fix a bug with splitting strings in Ascii input reader The previous way of splitting strings would break if the last string in the line was an empty string, and it would return one fewer fields than it should have. This was breaking the last line in the scripts.base.framework.input.ascii.setspecialcases once the bug fixed in GH #1628 was fixed. --- src/input/readers/ascii/Ascii.cc | 39 +++++-------------- .../out | 12 +++--- .../frameworks/input/setspecialcases.zeek | 2 +- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/src/input/readers/ascii/Ascii.cc b/src/input/readers/ascii/Ascii.cc index 5a0a11bfc9..a021ad28f8 100644 --- a/src/input/readers/ascii/Ascii.cc +++ b/src/input/readers/ascii/Ascii.cc @@ -170,7 +170,6 @@ bool Ascii::ReadHeader(bool useCached) { // try to read the header line... string line; - map ifields; if ( ! useCached ) { @@ -190,17 +189,7 @@ bool Ascii::ReadHeader(bool useCached) line = headerline; // construct list of field names. - istringstream splitstream(line); - int pos = 0; - while ( splitstream ) - { - string s; - if ( ! getline(splitstream, s, separator[0]) ) - break; - - ifields[s] = pos; - pos++; - } + auto ifields = util::split(line, separator[0]); // printf("Updating fields from description %s\n", line.c_str()); columnMap.clear(); @@ -211,7 +200,7 @@ bool Ascii::ReadHeader(bool useCached) { const Field* field = fields[i]; - auto fit = ifields.find(field->name); + auto fit = std::find(ifields.begin(), ifields.end(), field->name); if ( fit == ifields.end() ) { if ( field->optional ) @@ -232,11 +221,12 @@ bool Ascii::ReadHeader(bool useCached) return false; } - FieldMapping f(field->name, field->type, field->subtype, static_cast(ifields[field->name])); + int index = static_cast(std::distance(ifields.begin(), fit)); + FieldMapping f(field->name, field->type, field->subtype, index); if ( field->secondary_name && strlen(field->secondary_name) != 0 ) { - auto fit2 = ifields.find(field->secondary_name); + auto fit2 = std::find(ifields.begin(), ifields.end(), field->secondary_name); if ( fit2 == ifields.end() ) { FailWarn(fail_on_file_problem, @@ -247,7 +237,7 @@ bool Ascii::ReadHeader(bool useCached) return false; } - f.secondary_position = static_cast(ifields[field->secondary_name]); + f.secondary_position = static_cast(std::distance(ifields.begin(), fit2)); } columnMap.push_back(f); @@ -366,21 +356,10 @@ bool Ascii::DoUpdate() { // split on tabs bool error = false; - istringstream splitstream(line); + auto stringfields = util::split(line, separator[0]); - map stringfields; - int pos = 0; - while ( splitstream ) - { - string s; - if ( ! getline(splitstream, s, separator[0]) ) - break; - - stringfields[pos] = s; - pos++; - } - - pos--; // for easy comparisons of max element. + // This needs to be a signed value or the comparisons below will fail. + int pos = static_cast(stringfields.size() - 1); Value** fields = new Value*[NumFields()]; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.setspecialcases/out b/testing/btest/Baseline/scripts.base.frameworks.input.setspecialcases/out index 7b8f14e1e8..47f224033d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.setspecialcases/out +++ b/testing/btest/Baseline/scripts.base.frameworks.input.setspecialcases/out @@ -17,9 +17,9 @@ testing, testing,testing,testing, { } -}, s=[, , , ]], -}, s=[, testing]], -}, s=[]], -}, s=[testing, , testing]], -}, s=[testing, ]], -}, s=[testing,testing,testing,]] +}, ss=[, , , ]], +}, ss=[, testing]], +}, ss=[]], +}, ss=[testing, , testing]], +}, ss=[testing, ]], +}, ss=[testing,testing,testing,]] diff --git a/testing/btest/scripts/base/frameworks/input/setspecialcases.zeek b/testing/btest/scripts/base/frameworks/input/setspecialcases.zeek index b68e4b53d0..32827c60e3 100644 --- a/testing/btest/scripts/base/frameworks/input/setspecialcases.zeek +++ b/testing/btest/scripts/base/frameworks/input/setspecialcases.zeek @@ -26,7 +26,7 @@ type Idx: record { type Val: record { s: set[string]; - s: vector of string; + ss: vector of string; }; global servers: table[int] of Val = table();