Merge remote-tracking branch 'origin/topic/jsiwek/raw_output'

* origin/topic/jsiwek/raw_output:
  Fix &raw_output and enable_raw_output interpretation of NUL characters
This commit is contained in:
Robin Sommer 2011-08-03 16:26:00 -07:00
commit d8aece07d7
12 changed files with 109 additions and 22 deletions

@ -1 +1 @@
Subproject commit d21dbd3fde5d75c7d5dac69510afd5d5e9b7b704
Subproject commit 86990f1640d986e39d5bb1287dbeb03b59a464f0

View file

@ -174,15 +174,20 @@ void ODesc::AddBytes(const BroString* s)
{
if ( IsReadable() )
{
int render_style = BroString::EXPANDED_STRING;
if ( Style() == ALTERNATIVE_STYLE )
// Only change NULs, since we can't in any case
// cope with them.
render_style = BroString::ESC_NULL;
if ( Style() == RAW_STYLE )
AddBytes(reinterpret_cast<const char*>(s->Bytes()), s->Len());
else
{
int render_style = BroString::EXPANDED_STRING;
if ( Style() == ALTERNATIVE_STYLE )
// Only change NULs, since we can't in any case
// cope with them.
render_style = BroString::ESC_NULL;
const char* str = s->Render(render_style);
Add(str);
delete [] str;
const char* str = s->Render(render_style);
Add(str);
delete [] str;
}
}
else
{

View file

@ -17,6 +17,7 @@ typedef enum {
typedef enum {
STANDARD_STYLE,
ALTERNATIVE_STYLE,
RAW_STYLE,
} desc_style;
class BroFile;

View file

@ -2385,7 +2385,7 @@ bool RemoteSerializer::FlushPrintBuffer(Peer* p)
return true;
}
bool RemoteSerializer::SendPrintHookEvent(BroFile* f, const char* txt)
bool RemoteSerializer::SendPrintHookEvent(BroFile* f, const char* txt, size_t len)
{
loop_over_list(peers, i)
{
@ -2398,8 +2398,6 @@ bool RemoteSerializer::SendPrintHookEvent(BroFile* f, const char* txt)
if ( ! fname )
continue; // not a managed file.
size_t len = strlen(txt);
// We cut off everything after the max buffer size. That
// makes the code a bit easier, and we shouldn't have such
// long lines anyway.

View file

@ -95,7 +95,7 @@ public:
bool SendPing(PeerID peer, uint32 seq);
// Broadcast remote print.
bool SendPrintHookEvent(BroFile* f, const char* txt);
bool SendPrintHookEvent(BroFile* f, const char* txt, size_t len);
// Send a request to create a writer on a remote side.
bool SendLogCreateWriter(PeerID peer, EnumVal* id, EnumVal* writer, string path, int num_fields, const LogField* const * fields);

View file

@ -277,16 +277,28 @@ Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
bool ph = print_hook && f->IsPrintHookEnabled();
desc_style style = f->IsRawOutput() ? ALTERNATIVE_STYLE : STANDARD_STYLE;
desc_style style = f->IsRawOutput() ? RAW_STYLE : STANDARD_STYLE;
if ( ! (suppress_local_output && ph) )
{
ODesc d(DESC_READABLE, f);
d.SetFlush(0);
d.SetStyle(style);
if ( f->IsRawOutput() )
{
ODesc d(DESC_READABLE);
d.SetFlush(0);
d.SetStyle(style);
PrintVals(&d, vals, offset);
f->Write("\n", 1);
PrintVals(&d, vals, offset);
f->Write(d.Description(), d.Len());
}
else
{
ODesc d(DESC_READABLE, f);
d.SetFlush(0);
d.SetStyle(style);
PrintVals(&d, vals, offset);
f->Write("\n", 1);
}
}
if ( ph )
@ -300,14 +312,14 @@ Val* PrintStmt::DoExec(val_list* vals, stmt_flow_type& /* flow */) const
val_list* vl = new val_list(2);
::Ref(f);
vl->append(new Val(f));
vl->append(new StringVal(d.Description()));
vl->append(new StringVal(d.Len(), d.Description()));
// Note, this doesn't do remote printing.
mgr.Dispatch(new Event(print_hook, vl), true);
}
if ( remote_serializer )
remote_serializer->SendPrintHookEvent(f, d.Description());
remote_serializer->SendPrintHookEvent(f, d.Description(), d.Len());
}
return 0;

View file

@ -3567,7 +3567,7 @@ void describe_vals(const val_list* vals, ODesc* d, int offset)
for ( int i = offset; i < vals->length(); ++i )
{
if ( i > offset && d->IsReadable() )
if ( i > offset && d->IsReadable() && d->Style() != RAW_STYLE )
d->Add(", ");
(*vals)[i]->Describe(d);

View file

@ -0,0 +1 @@
helloXworldhi

View file

@ -0,0 +1 @@
helloXworldhi

View file

@ -0,0 +1 @@
helloXworldhi

View file

@ -0,0 +1,23 @@
# Files which enable raw output via the BiF shouldn't interpret NUL characters
# in strings that are `print`ed to it.
# @TEST-EXEC: bro %INPUT
# @TEST-EXEC: tr '\000' 'X' <myfile >output
# @TEST-EXEC: btest-diff output
# @TEST-EXEC: cmp myfile hookfile
event bro_init()
{
local myfile: file;
myfile = open("myfile");
enable_raw_output(myfile);
print myfile, "hello\x00world", "hi";
close(myfile);
}
event print_hook(f: file, s: string)
{
local hookfile = open("hookfile");
write_file(hookfile, s);
close(hookfile);
}

View file

@ -0,0 +1,45 @@
# Files with the &raw_output attribute shouldn't interpret NUL characters
# in strings that are `print`ed to it.
# @TEST-EXEC: bro %INPUT
# @TEST-EXEC: tr '\000' 'X' <myfile >output
# @TEST-EXEC: btest-diff output
# @TEST-EXEC: cmp myfile hookfile
# first check local variable of file type w/ &raw_output
event bro_init()
{
local myfile: file;
myfile = open("myfile");
enable_raw_output(myfile);
print myfile, "hello\x00world", "hi";
close(myfile);
}
event print_hook(f: file, s: string)
{
local hookfile = open("hookfile");
write_file(hookfile, s);
close(hookfile);
}
# @TEST-START-NEXT
# now check global variables of file type w/ &raw_output
global myfile: file;
event bro_init()
{
myfile = open("myfile");
enable_raw_output(myfile);
print myfile, "hello\x00world", "hi";
close(myfile);
}
event print_hook(f: file, s: string)
{
local hookfile = open("hookfile");
write_file(hookfile, s);
close(hookfile);
}