diff --git a/src/threading/formatters/Ascii.cc b/src/threading/formatters/Ascii.cc index b9075f97da..61cd7846fa 100644 --- a/src/threading/formatters/Ascii.cc +++ b/src/threading/formatters/Ascii.cc @@ -261,7 +261,7 @@ Value* Ascii::ParseValue(const string& s, const string& name, TypeTag type, Type case TYPE_COUNT: val->val.uint_val = strtoull(start, &end, 10); - if ( CheckNumberError(start, end) ) + if ( CheckNumberError(start, end, true) ) goto parse_error; break; @@ -292,7 +292,7 @@ Value* Ascii::ParseValue(const string& s, const string& name, TypeTag type, Type start = numberpart.c_str(); } val->val.port_val.port = strtoull(start, &end, 10); - if ( CheckNumberError(start, end) ) + if ( CheckNumberError(start, end, true) ) goto parse_error; } break; @@ -473,7 +473,7 @@ parse_error: return nullptr; } -bool Ascii::CheckNumberError(const char* start, const char* end) const +bool Ascii::CheckNumberError(const char* start, const char* end, bool nonneg_only) const { MsgThread* thread = GetThread(); @@ -491,6 +491,18 @@ bool Ascii::CheckNumberError(const char* start, const char* end) const if ( (*end != '\0') ) thread->Warning(thread->Fmt("Number '%s' contained non-numeric trailing characters. Ignored trailing characters '%s'", start, end)); + if ( nonneg_only ) { + // String may legitimately start with whitespace, so + // we skip this before checking for a minus sign. + const char* s = start; + while ( s < end && isspace(*s) ) + s++; + if ( *s == '-' ) { + thread->Warning(thread->Fmt("Number '%s' cannot be negative", start)); + return true; + } + } + if ( errno == EINVAL ) { thread->Warning(thread->Fmt("String '%s' could not be converted to a number", start)); diff --git a/src/threading/formatters/Ascii.h b/src/threading/formatters/Ascii.h index c2d6218af2..4cfe2cec04 100644 --- a/src/threading/formatters/Ascii.h +++ b/src/threading/formatters/Ascii.h @@ -54,7 +54,7 @@ public: TypeTag type, TypeTag subtype = TYPE_ERROR) const; private: - bool CheckNumberError(const char* start, const char* end) const; + bool CheckNumberError(const char* start, const char* end, bool nonneg_only = false) const; SeparatorInfo separators; }; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline b/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline index ca44cfc3a2..0bac11e721 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline +++ b/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/.stderrwithoutfirstline @@ -5,5 +5,7 @@ warning: ..<...>/Input::READER_ASCII: Number '9223372036854775801TEXTHERE' conta warning: ..<...>/Input::READER_ASCII: Number '1Justtext' contained non-numeric trailing characters. Ignored trailing characters 'Justtext' warning: ..<...>/Input::READER_ASCII: String 'Justtext' contained no parseable number warning: ..<...>/Input::READER_ASCII: Could not convert line 'Justtext 1' of ../input.log to Val. Ignoring line. +warning: ..<...>/Input::READER_ASCII: Number ' -18446744073709551612' cannot be negative +warning: ..<...>/Input::READER_ASCII: Could not convert line '9223372036854775800 -18446744073709551612' of ../input.log to Val. Ignoring line. received termination signal >>> diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/out b/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/out index 366f93130c..3bc16fee9d 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/out +++ b/testing/btest/Baseline/scripts.base.frameworks.input.invalidnumbers/out @@ -1,5 +1,4 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. { -[9223372036854775801] = [c=1], -[9223372036854775800] = [c=4] +[9223372036854775801] = [c=1] } diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.port-embedded/zeek..stderr b/testing/btest/Baseline/scripts.base.frameworks.input.port-embedded/zeek..stderr index 2695e2a3d1..b32babb871 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.input.port-embedded/zeek..stderr +++ b/testing/btest/Baseline/scripts.base.frameworks.input.port-embedded/zeek..stderr @@ -1,3 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. warning: ../input.log/Input::READER_ASCII: Port '50/trash' contained unknown protocol 'trash' +warning: ../input.log/Input::READER_ASCII: Number '-1' cannot be negative +warning: ../input.log/Input::READER_ASCII: Could not convert line '1.2.3.8 -1/tcp' of ../input.log to Val. Ignoring line. received termination signal diff --git a/testing/btest/scripts/base/frameworks/input/invalidnumbers.zeek b/testing/btest/scripts/base/frameworks/input/invalidnumbers.zeek index 16a3cda1de..822e99f511 100644 --- a/testing/btest/scripts/base/frameworks/input/invalidnumbers.zeek +++ b/testing/btest/scripts/base/frameworks/input/invalidnumbers.zeek @@ -4,6 +4,8 @@ # @TEST-EXEC: sed 1d .stderr > .stderrwithoutfirstline # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderrwithoutfirstline +# Note the tab+space separator in the last line of the following is +# intentional. It verifies our whitespace handling. @TEST-START-FILE input.log #separator \x09 #fields i c @@ -11,7 +13,7 @@ 12129223372036854775800 121218446744073709551612 9223372036854775801TEXTHERE 1Justtext Justtext 1 -9223372036854775800 -18446744073709551612 +9223372036854775800 -18446744073709551612 @TEST-END-FILE redef exit_only_after_terminate = T; diff --git a/testing/btest/scripts/base/frameworks/input/port-embedded.zeek b/testing/btest/scripts/base/frameworks/input/port-embedded.zeek index ef4b0a0651..5e8ad05fb7 100644 --- a/testing/btest/scripts/base/frameworks/input/port-embedded.zeek +++ b/testing/btest/scripts/base/frameworks/input/port-embedded.zeek @@ -9,6 +9,7 @@ 1.2.3.5 52/udp 1.2.3.6 30/unknown 1.2.3.7 50/trash +1.2.3.8 -1/tcp @TEST-END-FILE redef exit_only_after_terminate = T;