mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
ok, this one might really be a bit too big for 2.1
Give all kinds of errors when encountering invalid numbers (like out-of-range-warnings, etc).
This commit is contained in:
parent
7e46936728
commit
f133e8808a
7 changed files with 122 additions and 8 deletions
|
@ -11,6 +11,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
using namespace input::reader;
|
using namespace input::reader;
|
||||||
using threading::Value;
|
using threading::Value;
|
||||||
|
@ -209,6 +210,34 @@ bool Ascii::GetLine(string& str)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ascii::CheckNumberError(const string & s, const char * end)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( s.length() == 0 )
|
||||||
|
{
|
||||||
|
Error("Got empty string for number field");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( end == s.c_str() ) {
|
||||||
|
Error(Fmt("String '%s' contained no parseable number", s.c_str()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( *end != '\0' )
|
||||||
|
Error(Fmt("Number '%s' contained non-numeric trailing characters. Ignored trailing characters '%s'", s.c_str(), end));
|
||||||
|
|
||||||
|
if ( errno == EINVAL )
|
||||||
|
{
|
||||||
|
Error(Fmt("String '%s' could not be converted to a number", s.c_str()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if ( errno == ERANGE )
|
||||||
|
Error(Fmt("Number '%s' out of supported range. Number was truncated", s.c_str()));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Value* Ascii::EntryToVal(string s, FieldMapping field)
|
Value* Ascii::EntryToVal(string s, FieldMapping field)
|
||||||
{
|
{
|
||||||
|
@ -216,6 +245,8 @@ Value* Ascii::EntryToVal(string s, FieldMapping field)
|
||||||
return new Value(field.type, false);
|
return new Value(field.type, false);
|
||||||
|
|
||||||
Value* val = new Value(field.type, true);
|
Value* val = new Value(field.type, true);
|
||||||
|
char* end;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
switch ( field.type ) {
|
switch ( field.type ) {
|
||||||
case TYPE_ENUM:
|
case TYPE_ENUM:
|
||||||
|
@ -239,22 +270,31 @@ Value* Ascii::EntryToVal(string s, FieldMapping field)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
val->val.int_val = strtoll(s.c_str(), (char**) NULL, 10);
|
val->val.int_val = strtoll(s.c_str(), &end, 10);
|
||||||
|
if ( CheckNumberError(s, end) )
|
||||||
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_DOUBLE:
|
case TYPE_DOUBLE:
|
||||||
case TYPE_TIME:
|
case TYPE_TIME:
|
||||||
case TYPE_INTERVAL:
|
case TYPE_INTERVAL:
|
||||||
val->val.double_val = atof(s.c_str());
|
val->val.double_val = strtod(s.c_str(), &end);
|
||||||
|
if ( CheckNumberError(s, end) )
|
||||||
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_COUNT:
|
case TYPE_COUNT:
|
||||||
case TYPE_COUNTER:
|
case TYPE_COUNTER:
|
||||||
val->val.uint_val = strtoull(s.c_str(),(char**) NULL, 10);
|
val->val.uint_val = strtoull(s.c_str(), &end, 10);
|
||||||
|
if ( CheckNumberError(s, end) )
|
||||||
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_PORT:
|
case TYPE_PORT:
|
||||||
val->val.port_val.port = atoi(s.c_str());
|
val->val.port_val.port = strtoull(s.c_str(), &end, 10);
|
||||||
|
if ( CheckNumberError(s, end) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
val->val.port_val.proto = TRANSPORT_UNKNOWN;
|
val->val.port_val.proto = TRANSPORT_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -268,9 +308,12 @@ Value* Ascii::EntryToVal(string s, FieldMapping field)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int width = atoi(s.substr(pos+1).c_str());
|
uint8_t width = (uint8_t) strtol(s.substr(pos+1).c_str(), &end, 10);
|
||||||
string addr = s.substr(0, pos);
|
string addr = s.substr(0, pos);
|
||||||
|
|
||||||
|
if ( CheckNumberError(s, end) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
val->val.subnet_val.prefix = StringToAddr(addr);
|
val->val.subnet_val.prefix = StringToAddr(addr);
|
||||||
val->val.subnet_val.length = width;
|
val->val.subnet_val.length = width;
|
||||||
break;
|
break;
|
||||||
|
@ -490,7 +533,7 @@ bool Ascii::DoUpdate()
|
||||||
Value* val = EntryToVal(stringfields[(*fit).position], *fit);
|
Value* val = EntryToVal(stringfields[(*fit).position], *fit);
|
||||||
if ( val == 0 )
|
if ( val == 0 )
|
||||||
{
|
{
|
||||||
Error("Could not convert String value to Val");
|
Error(Fmt("Could not convert line '%s' to Val. Aborting file read.", line.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ private:
|
||||||
bool ReadHeader(bool useCached);
|
bool ReadHeader(bool useCached);
|
||||||
bool GetLine(string& str);
|
bool GetLine(string& str);
|
||||||
threading::Value* EntryToVal(string s, FieldMapping type);
|
threading::Value* EntryToVal(string s, FieldMapping type);
|
||||||
|
bool CheckNumberError(const string & s, const char * end);
|
||||||
|
|
||||||
ifstream* file;
|
ifstream* file;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
[9223372036854775800] = [c=18446744073709551612]
|
[9223372036854775800] = [c=18446744073709551612],
|
||||||
|
[-9223372036854775800] = [c=18446744073709551612]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
error: ../input.log/Input::READER_ASCII: Number '12129223372036854775800' out of supported range. Number was truncated
|
||||||
|
error: ../input.log/Input::READER_ASCII: Number '121218446744073709551612' out of supported range. Number was truncated
|
||||||
|
error: ../input.log/Input::READER_ASCII: Number '9223372036854775801TEXTHERE' contained non-numeric trailing characters. Ignored trailing characters 'TEXTHERE'
|
||||||
|
error: ../input.log/Input::READER_ASCII: Number '1Justtext' contained non-numeric trailing characters. Ignored trailing characters 'Justtext'
|
||||||
|
error: ../input2.log/Input::READER_ASCII: String 'Justtext' contained no parseable number
|
||||||
|
error: ../input2.log/Input::READER_ASCII: Could not convert line 'Justtext 1' to Val. Aborting file read.
|
||||||
|
received termination signal
|
||||||
|
>>>
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
[9223372036854775807] = [c=18446744073709551615],
|
||||||
|
[9223372036854775800] = [c=4],
|
||||||
|
[9223372036854775801] = [c=1]
|
||||||
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
#fields i c
|
#fields i c
|
||||||
#types int count
|
#types int count
|
||||||
9223372036854775800 18446744073709551612
|
9223372036854775800 18446744073709551612
|
||||||
|
-9223372036854775800 18446744073709551612
|
||||||
@TEST-END-FILE
|
@TEST-END-FILE
|
||||||
|
|
||||||
@load frameworks/communication/listen
|
@load frameworks/communication/listen
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
# (uses listen.bro just to ensure input sources are more reliably fully-read).
|
||||||
|
# @TEST-SERIALIZE: comm
|
||||||
|
#
|
||||||
|
# @TEST-EXEC: btest-bg-run bro bro -b %INPUT
|
||||||
|
# @TEST-EXEC: btest-bg-wait -k 5
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
# @TEST-EXEC: sed 1d .stderr > .stderrwithoutfirstline
|
||||||
|
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff .stderrwithoutfirstline
|
||||||
|
|
||||||
|
@TEST-START-FILE input.log
|
||||||
|
#separator \x09
|
||||||
|
#fields i c
|
||||||
|
#types int count
|
||||||
|
12129223372036854775800 121218446744073709551612
|
||||||
|
9223372036854775801TEXTHERE 1Justtext
|
||||||
|
9223372036854775800 -18446744073709551612
|
||||||
|
@TEST-END-FILE
|
||||||
|
|
||||||
|
@TEST-START-FILE input2.log
|
||||||
|
#separator \x09
|
||||||
|
#fields i c
|
||||||
|
#types int count
|
||||||
|
Justtext 1
|
||||||
|
@TEST-END-FILE
|
||||||
|
|
||||||
|
|
||||||
|
@load frameworks/communication/listen
|
||||||
|
|
||||||
|
global outfile: file;
|
||||||
|
|
||||||
|
module A;
|
||||||
|
|
||||||
|
type Idx: record {
|
||||||
|
i: int;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Val: record {
|
||||||
|
c: count;
|
||||||
|
};
|
||||||
|
|
||||||
|
global servers: table[int] of Val = table();
|
||||||
|
|
||||||
|
event bro_init()
|
||||||
|
{
|
||||||
|
outfile = open("../out");
|
||||||
|
# first read in the old stuff into the table...
|
||||||
|
Input::add_table([$source="../input.log", $name="ssh", $idx=Idx, $val=Val, $destination=servers]);
|
||||||
|
Input::remove("ssh");
|
||||||
|
}
|
||||||
|
|
||||||
|
event Input::update_finished(name: string, source:string)
|
||||||
|
{
|
||||||
|
print outfile, servers;
|
||||||
|
Input::add_table([$source="../input2.log", $name="ssh2", $idx=Idx, $val=Val, $destination=servers]);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue