mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 10:38:20 +00:00
support for uninitialized fields & empty sets and tables.
The only snag is... with the default output format of the log-file writer, the input reader cannot tell if a table or set is empty or uninitialized (both cases use the same character by default). In this case, by default it is assumed that the field/vector is uninitalized.
This commit is contained in:
parent
4fef1e3f8c
commit
4dd95fcf3c
4 changed files with 57 additions and 79 deletions
|
@ -1 +1,3 @@
|
||||||
@load ./main
|
@load ./main
|
||||||
|
@load ./readers/ascii
|
||||||
|
|
||||||
|
|
|
@ -505,10 +505,10 @@ void InputMgr::SendEntry(const InputReader* reader, const LogVal* const *vals) {
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( val == 0 ) {
|
/* if ( val == 0 ) {
|
||||||
reporter->InternalError("conversion error");
|
reporter->InternalError("conversion error");
|
||||||
return;
|
return;
|
||||||
}
|
} */
|
||||||
|
|
||||||
r->Assign(j,val);
|
r->Assign(j,val);
|
||||||
|
|
||||||
|
@ -871,7 +871,9 @@ int InputMgr::GetLogValLength(const LogVal* val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_VECTOR: {
|
case TYPE_VECTOR: {
|
||||||
for ( int i = 0; i < val->val.vector_val.size; i++ ) {
|
int j = val->val.vector_val.size;
|
||||||
|
for ( int i = 0; i < j; i++ ) {
|
||||||
|
reporter->Error("size is %d", val->val.vector_val.size);
|
||||||
length += GetLogValLength(val->val.vector_val.vals[i]);
|
length += GetLogValLength(val->val.vector_val.vals[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -945,7 +947,8 @@ int InputMgr::CopyLogVal(char *data, const int startpos, const LogVal* val) {
|
||||||
|
|
||||||
case TYPE_VECTOR: {
|
case TYPE_VECTOR: {
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for ( int i = 0; i < val->val.vector_val.size; i++ ) {
|
int j = val->val.vector_val.size;
|
||||||
|
for ( int i = 0; i < j; i++ ) {
|
||||||
length += CopyLogVal(data, startpos+length, val->val.vector_val.vals[i]);
|
length += CopyLogVal(data, startpos+length, val->val.vector_val.vals[i]);
|
||||||
}
|
}
|
||||||
return length;
|
return length;
|
||||||
|
@ -995,6 +998,10 @@ Val* InputMgr::LogValToVal(const LogVal* val, BroType* request_type) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !val->present ) {
|
||||||
|
return 0; // unset field
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch ( val->type ) {
|
switch ( val->type ) {
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
|
@ -1033,13 +1040,6 @@ Val* InputMgr::LogValToVal(const LogVal* val, BroType* request_type) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_TABLE: {
|
case TYPE_TABLE: {
|
||||||
if ( val->val.set_val.size == 0 ) {
|
|
||||||
// empty table
|
|
||||||
TypeList* set_index = new TypeList(base_type(TYPE_ANY));
|
|
||||||
// iim quite sure this does not work... we probably need the internal set type for this...
|
|
||||||
reporter->InternalError("Implement me.");
|
|
||||||
return new TableVal(new SetType(set_index, 0));
|
|
||||||
} else {
|
|
||||||
// all entries have to have the same type...
|
// all entries have to have the same type...
|
||||||
BroType* type = request_type->AsTableType()->Indices()->PureType();
|
BroType* type = request_type->AsTableType()->Indices()->PureType();
|
||||||
TypeList* set_index = new TypeList(type->Ref());
|
TypeList* set_index = new TypeList(type->Ref());
|
||||||
|
@ -1050,13 +1050,10 @@ Val* InputMgr::LogValToVal(const LogVal* val, BroType* request_type) {
|
||||||
t->Assign(LogValToVal( val->val.set_val.vals[i], type ), 0);
|
t->Assign(LogValToVal( val->val.set_val.vals[i], type ), 0);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_VECTOR: {
|
case TYPE_VECTOR: {
|
||||||
assert ( val->val.vector_val.size > 1 ); // implement empty vector...
|
|
||||||
|
|
||||||
// all entries have to have the same type...
|
// all entries have to have the same type...
|
||||||
BroType* type = request_type->AsVectorType()->YieldType();
|
BroType* type = request_type->AsVectorType()->YieldType();
|
||||||
VectorType* vt = new VectorType(type->Ref());
|
VectorType* vt = new VectorType(type->Ref());
|
||||||
|
|
|
@ -34,31 +34,19 @@ InputReaderAscii::InputReaderAscii()
|
||||||
|
|
||||||
//keyMap = new map<string, string>();
|
//keyMap = new map<string, string>();
|
||||||
|
|
||||||
separator_len = BifConst::LogAscii::separator->Len();
|
separator.assign( (const char*) BifConst::InputAscii::separator->Bytes(), BifConst::InputAscii::separator->Len());
|
||||||
separator = new char[separator_len];
|
if ( separator.size() != 1 ) {
|
||||||
memcpy(separator, BifConst::LogAscii::separator->Bytes(),
|
|
||||||
separator_len);
|
|
||||||
if ( separator_len != 1 ) {
|
|
||||||
Error("separator length has to be 1. Separator will be truncated.");
|
Error("separator length has to be 1. Separator will be truncated.");
|
||||||
}
|
}
|
||||||
|
|
||||||
set_separator_len = BifConst::LogAscii::set_separator->Len();
|
set_separator.assign( (const char*) BifConst::InputAscii::set_separator->Bytes(), BifConst::InputAscii::set_separator->Len());
|
||||||
set_separator = new char[set_separator_len];
|
if ( set_separator.size() != 1 ) {
|
||||||
memcpy(set_separator, BifConst::LogAscii::set_separator->Bytes(),
|
|
||||||
set_separator_len);
|
|
||||||
if ( set_separator_len != 1 ) {
|
|
||||||
Error("set_separator length has to be 1. Separator will be truncated.");
|
Error("set_separator length has to be 1. Separator will be truncated.");
|
||||||
}
|
}
|
||||||
|
|
||||||
empty_field_len = BifConst::LogAscii::empty_field->Len();
|
empty_field.assign( (const char*) BifConst::InputAscii::empty_field->Bytes(), BifConst::InputAscii::empty_field->Len());
|
||||||
empty_field = new char[empty_field_len];
|
|
||||||
memcpy(empty_field, BifConst::LogAscii::empty_field->Bytes(),
|
|
||||||
empty_field_len);
|
|
||||||
|
|
||||||
unset_field_len = BifConst::LogAscii::unset_field->Len();
|
unset_field.assign( (const char*) BifConst::InputAscii::unset_field->Bytes(), BifConst::InputAscii::unset_field->Len());
|
||||||
unset_field = new char[unset_field_len];
|
|
||||||
memcpy(unset_field, BifConst::LogAscii::unset_field->Bytes(),
|
|
||||||
unset_field_len);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +54,6 @@ InputReaderAscii::~InputReaderAscii()
|
||||||
{
|
{
|
||||||
DoFinish();
|
DoFinish();
|
||||||
|
|
||||||
delete [] separator;
|
|
||||||
delete [] set_separator;
|
|
||||||
delete [] empty_field;
|
|
||||||
delete [] unset_field;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputReaderAscii::DoFinish()
|
void InputReaderAscii::DoFinish()
|
||||||
|
@ -172,7 +156,10 @@ bool InputReaderAscii::GetLine(string& str) {
|
||||||
LogVal* InputReaderAscii::EntryToVal(string s, FieldMapping field) {
|
LogVal* InputReaderAscii::EntryToVal(string s, FieldMapping field) {
|
||||||
|
|
||||||
LogVal* val = new LogVal(field.type, true);
|
LogVal* val = new LogVal(field.type, true);
|
||||||
//bzero(val, sizeof(LogVal));
|
|
||||||
|
if ( s.compare(unset_field) == 0 ) { // field is not set...
|
||||||
|
return new LogVal(field.type, false);
|
||||||
|
}
|
||||||
|
|
||||||
switch ( field.type ) {
|
switch ( field.type ) {
|
||||||
case TYPE_ENUM:
|
case TYPE_ENUM:
|
||||||
|
@ -245,18 +232,12 @@ LogVal* InputReaderAscii::EntryToVal(string s, FieldMapping field) {
|
||||||
|
|
||||||
unsigned int pos = 0;
|
unsigned int pos = 0;
|
||||||
|
|
||||||
|
if ( s.compare(empty_field) == 0 )
|
||||||
|
length = 0;
|
||||||
|
|
||||||
LogVal** lvals = new LogVal* [length];
|
LogVal** lvals = new LogVal* [length];
|
||||||
|
|
||||||
if ( field.type == TYPE_TABLE ) {
|
if ( field.type == TYPE_TABLE ) {
|
||||||
// construct a table from entry...
|
|
||||||
// for the moment assume, that entries are split by ",".
|
|
||||||
|
|
||||||
/* Fix support for emtyp tables if ( s == "-" ) {
|
|
||||||
// empty
|
|
||||||
val->val.set_val.size = 0;
|
|
||||||
break;
|
|
||||||
} */
|
|
||||||
|
|
||||||
val->val.set_val.vals = lvals;
|
val->val.set_val.vals = lvals;
|
||||||
val->val.set_val.size = length;
|
val->val.set_val.size = length;
|
||||||
} else if ( field.type == TYPE_VECTOR ) {
|
} else if ( field.type == TYPE_VECTOR ) {
|
||||||
|
@ -266,18 +247,20 @@ LogVal* InputReaderAscii::EntryToVal(string s, FieldMapping field) {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( length == 0 )
|
||||||
|
break; //empty
|
||||||
|
|
||||||
istringstream splitstream(s);
|
istringstream splitstream(s);
|
||||||
while ( splitstream ) {
|
while ( splitstream ) {
|
||||||
string element;
|
string element;
|
||||||
|
|
||||||
if ( pos >= length ) {
|
|
||||||
Error(Fmt("Internal error while parsing set. pos %d > length %d", pos, length));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !getline(splitstream, element, set_separator[0]) )
|
if ( !getline(splitstream, element, set_separator[0]) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if ( pos >= length ) {
|
||||||
|
Error(Fmt("Internal error while parsing set. pos %d >= length %d. Element: %s", pos, length, element.c_str()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
LogVal* newval = EntryToVal(element, field.subType());
|
LogVal* newval = EntryToVal(element, field.subType());
|
||||||
if ( newval == 0 ) {
|
if ( newval == 0 ) {
|
||||||
|
|
|
@ -59,17 +59,13 @@ private:
|
||||||
//map<string, string> *keyMap;
|
//map<string, string> *keyMap;
|
||||||
//
|
//
|
||||||
// Options set from the script-level.
|
// Options set from the script-level.
|
||||||
char* separator;
|
string separator;
|
||||||
int separator_len;
|
|
||||||
|
|
||||||
char* set_separator;
|
string set_separator;
|
||||||
int set_separator_len;
|
|
||||||
|
|
||||||
char* empty_field;
|
string empty_field;
|
||||||
int empty_field_len;
|
|
||||||
|
|
||||||
char* unset_field;
|
string unset_field;
|
||||||
int unset_field_len;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue