Skip negative integers in input framework where not type-permissible

Script-layer counts, when provided as negative integers in an input
file, got cast to unsigned values because strtoull() does not complain
about negative values. For example, input string "-1" would lead to
value 18446744073709551615 (an all-ones 64-bit int) on x86_64. This is
more likely to be an error than an intent to get very large,
platform-dependent values, so these input lines are now skipped with
according messaging in the reporter.log/stderr.

This also affected ports: -1/tcp got cast to unsigned and only thrown
out because PortVal rejects values > 65535, mapping them to 0. We now
skip such inputs as well.

Updates existing input framework tests to capture the new behavior.
This commit is contained in:
Christian Kreibich 2021-01-28 22:42:39 -08:00
parent d845f01b27
commit 38d6b6a98b
7 changed files with 25 additions and 7 deletions

View file

@ -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));

View file

@ -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;
};