Review usage of Reporter::InternalError, addresses BIT-1045.

Replaced some with InternalWarning or InternalAnalyzerError, the later
being a new method which signals the analyzer to not process further
input.  Some usages I just removed if they didn't make sense or clearly
couldn't happen.  Also did some minor refactors of related code while
reviewing/exploring ways to get rid of InternalError usages.

Also, for TCP content file write failures there's a new event:
"contents_file_write_failure".
This commit is contained in:
Jon Siwek 2013-10-10 14:45:06 -05:00
parent 6734260136
commit b828a6ddc7
51 changed files with 532 additions and 267 deletions

View file

@ -27,9 +27,6 @@ void ConnectionTimer::Init(Connection* arg_conn, timer_func arg_timer,
ConnectionTimer::~ConnectionTimer() ConnectionTimer::~ConnectionTimer()
{ {
if ( conn->RefCnt() < 1 )
reporter->InternalError("reference count inconsistency in ~ConnectionTimer");
conn->RemoveTimer(this); conn->RemoveTimer(this);
Unref(conn); Unref(conn);
} }
@ -44,9 +41,6 @@ void ConnectionTimer::Dispatch(double t, int is_expire)
conn->RemoveTimer(this); conn->RemoveTimer(this);
(conn->*timer)(t); (conn->*timer)(t);
if ( conn->RefCnt() < 1 )
reporter->InternalError("reference count inconsistency in ConnectionTimer::Dispatch");
} }
IMPLEMENT_SERIAL(ConnectionTimer, SER_CONNECTION_TIMER); IMPLEMENT_SERIAL(ConnectionTimer, SER_CONNECTION_TIMER);
@ -68,7 +62,10 @@ bool ConnectionTimer::DoSerialize(SerialInfo* info) const
else if ( timer == timer_func(&Connection::RemoveConnectionTimer) ) else if ( timer == timer_func(&Connection::RemoveConnectionTimer) )
type = 4; type = 4;
else else
reporter->InternalError("unknown function in ConnectionTimer::DoSerialize()"); {
reporter->InternalWarning("unknown function in ConnectionTimer::DoSerialize()");
return false;
}
return conn->Serialize(info) && SERIALIZE(type) && SERIALIZE(do_expire); return conn->Serialize(info) && SERIALIZE(type) && SERIALIZE(do_expire);
} }
@ -180,7 +177,12 @@ Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
Connection::~Connection() Connection::~Connection()
{ {
if ( ! finished ) if ( ! finished )
reporter->InternalError("Done() not called before destruction of Connection"); {
// TODO: not sure about this
reporter->InternalWarning(
"missing Connection::Done() before ~Connection");
Done();
}
CancelTimers(); CancelTimers();
@ -782,7 +784,15 @@ void Connection::Describe(ODesc* d) const
break; break;
case TRANSPORT_UNKNOWN: case TRANSPORT_UNKNOWN:
reporter->InternalError("unknown transport in Connction::Describe()"); d->Add("unknown");
reporter->InternalWarning(
"unknown transport in Connction::Describe()");
break;
default:
reporter->InternalError(
"unhandled transport type in Connection::Describe");
break; break;
} }

View file

@ -546,7 +546,7 @@ Val* DNS_Mgr::LookupAddr(const IPAddr& addr)
return LookupAddr(addr); return LookupAddr(addr);
default: default:
reporter->InternalError("bad mode in DNS_Mgr::LookupHost"); reporter->InternalError("bad mode in DNS_Mgr::LookupAddr");
return 0; return 0;
} }
} }
@ -833,7 +833,10 @@ void DNS_Mgr::CompareMappings(DNS_Mapping* prev_dm, DNS_Mapping* new_dm)
ListVal* new_a = new_dm->Addrs(); ListVal* new_a = new_dm->Addrs();
if ( ! prev_a || ! new_a ) if ( ! prev_a || ! new_a )
reporter->InternalError("confused in DNS_Mgr::CompareMappings"); {
reporter->InternalWarning("confused in DNS_Mgr::CompareMappings");
return;
}
ListVal* prev_delta = AddrListDelta(prev_a, new_a); ListVal* prev_delta = AddrListDelta(prev_a, new_a);
ListVal* new_delta = AddrListDelta(new_a, prev_a); ListVal* new_delta = AddrListDelta(new_a, prev_a);

View file

@ -65,14 +65,20 @@ void ODesc::PushIndent()
void ODesc::PopIndent() void ODesc::PopIndent()
{ {
if ( --indent_level < 0 ) if ( --indent_level < 0 )
reporter->InternalError("ODesc::PopIndent underflow"); {
indent_level = 0;
reporter->InternalWarning("ODesc::PopIndent underflow");
}
NL(); NL();
} }
void ODesc::PopIndentNoNL() void ODesc::PopIndentNoNL()
{ {
if ( --indent_level < 0 ) if ( --indent_level < 0 )
reporter->InternalError("ODesc::PopIndent underflow"); {
indent_level = 0;
reporter->InternalWarning("ODesc::PopIndent underflow");
}
} }
void ODesc::Add(const char* s, int do_indent) void ODesc::Add(const char* s, int do_indent)

View file

@ -91,7 +91,10 @@ void EventMgr::QueueEvent(Event* event)
void EventMgr::Dispatch() void EventMgr::Dispatch()
{ {
if ( ! head ) if ( ! head )
reporter->InternalError("EventMgr underflow"); {
reporter->InternalWarning("EventMgr::Dispatch underflow");
return;
}
Event* current = head; Event* current = head;

View file

@ -90,9 +90,14 @@ void EventRegistry::PrintDebug()
void EventRegistry::SetErrorHandler(const char* name) void EventRegistry::SetErrorHandler(const char* name)
{ {
EventHandler* eh = Lookup(name); EventHandler* eh = Lookup(name);
if ( ! eh )
reporter->InternalError("unknown event handler in SetErrorHandler()");
eh->SetErrorHandler(); if ( eh )
{
eh->SetErrorHandler();
return;
}
reporter->InternalWarning(
"unknown event handler '%s' in SetErrorHandler()", name);
} }

View file

@ -281,8 +281,13 @@ FILE* BroFile::File()
FILE* BroFile::BringIntoCache() FILE* BroFile::BringIntoCache()
{ {
char buf[256];
if ( f ) if ( f )
reporter->InternalError("BroFile non-nil non-open file"); {
reporter->InternalWarning("BroFile non-nil non-open file");
return 0;
}
if ( num_files_in_cache >= max_files_in_cache ) if ( num_files_in_cache >= max_files_in_cache )
PurgeCache(); PurgeCache();
@ -296,22 +301,30 @@ FILE* BroFile::BringIntoCache()
if ( ! f ) if ( ! f )
{ {
reporter->Error("can't open %s", name); strerror_r(errno, buf, sizeof(buf));
reporter->Error("can't open %s: %s", name, buf);
f = fopen("/dev/null", "w"); f = fopen("/dev/null", "w");
if ( ! f ) if ( f )
reporter->InternalError("out of file descriptors"); {
okay_to_manage = 0;
return f;
}
okay_to_manage = 0; strerror_r(errno, buf, sizeof(buf));
return f; reporter->InternalWarning("can't open /dev/null: %s", buf);
return 0;
} }
RaiseOpenEvent(); RaiseOpenEvent();
UpdateFileSize(); UpdateFileSize();
if ( fseek(f, position, SEEK_SET) < 0 ) if ( fseek(f, position, SEEK_SET) < 0 )
reporter->Error("reopen seek failed"); {
strerror_r(errno, buf, sizeof(buf));
reporter->Error("reopen seek failed: %s", buf);
}
InsertAtBeginning(); InsertAtBeginning();
@ -386,18 +399,30 @@ int BroFile::Close()
void BroFile::Suspend() void BroFile::Suspend()
{ {
if ( ! is_in_cache ) if ( ! is_in_cache )
reporter->InternalError("BroFile::Suspend() called for non-cached file"); {
reporter->InternalWarning("BroFile::Suspend() called for non-cached file");
return;
}
if ( ! is_open ) if ( ! is_open )
reporter->InternalError("BroFile::Suspend() called for non-open file"); {
reporter->InternalWarning("BroFile::Suspend() called for non-open file");
return;
}
Unlink(); Unlink();
if ( ! f ) if ( ! f )
reporter->InternalError("BroFile::Suspend() called for nil file"); {
reporter->InternalWarning("BroFile::Suspend() called for nil file");
return;
}
if ( (position = ftell(f)) < 0 ) if ( (position = ftell(f)) < 0 )
{ {
reporter->Error("ftell failed"); char buf[256];
strerror_r(errno, buf, sizeof(buf));
reporter->Error("ftell failed: %s", buf);
position = 0; position = 0;
} }
@ -407,10 +432,13 @@ void BroFile::Suspend()
void BroFile::PurgeCache() void BroFile::PurgeCache()
{ {
if ( ! tail ) if ( tail )
reporter->InternalError("BroFile purge of empty cache"); {
tail->Suspend();
return;
}
tail->Suspend(); reporter->InternalWarning("BroFile purge of empty cache");
} }
void BroFile::Unlink() void BroFile::Unlink()

View file

@ -22,7 +22,7 @@ void FragTimer::Dispatch(double t, int /* is_expire */)
if ( f ) if ( f )
f->Expire(t); f->Expire(t);
else else
reporter->InternalError("fragment timer dispatched w/o reassembler"); reporter->InternalWarning("fragment timer dispatched w/o reassembler");
} }
FragReassembler::FragReassembler(NetSessions* arg_s, FragReassembler::FragReassembler(NetSessions* arg_s,
@ -155,14 +155,33 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
NewBlock(network_time, offset, len, pkt); NewBlock(network_time, offset, len, pkt);
} }
void FragReassembler::Weird(const char* name) const
{
unsigned int version = ((const ip*)proto_hdr)->ip_v;
if ( version == 4 )
{
IP_Hdr hdr((const ip*)proto_hdr, false);
s->Weird(name, &hdr);
}
else if ( version == 6 )
{
IP_Hdr hdr((const ip6_hdr*)proto_hdr, false, proto_hdr_len);
s->Weird(name, &hdr);
}
else
{
reporter->InternalWarning("Unexpected IP version in FragReassembler");
reporter->Weird(name);
}
}
void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n) void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n)
{ {
IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
if ( memcmp((const void*) b1, (const void*) b2, n) ) if ( memcmp((const void*) b1, (const void*) b2, n) )
s->Weird("fragment_inconsistency", &proto_h); Weird("fragment_inconsistency");
else else
s->Weird("fragment_overlap", &proto_h); Weird("fragment_overlap");
} }
void FragReassembler::BlockInserted(DataBlock* /* start_block */) void FragReassembler::BlockInserted(DataBlock* /* start_block */)
@ -188,9 +207,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
// beyond it, which is not contiguous. This // beyond it, which is not contiguous. This
// can happen for benign reasons when we're // can happen for benign reasons when we're
// intermingling parts of two fragmented packets. // intermingling parts of two fragmented packets.
Weird("fragment_size_inconsistency");
IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
s->Weird("fragment_size_inconsistency", &proto_h);
// We decide to analyze the contiguous portion now. // We decide to analyze the contiguous portion now.
// Extend the fragment up through the end of what // Extend the fragment up through the end of what
@ -203,8 +220,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
else if ( last_block->upper > frag_size ) else if ( last_block->upper > frag_size )
{ {
IP_Hdr proto_h(proto_hdr, false, proto_hdr_len); Weird("fragment_size_inconsistency");
s->Weird("fragment_size_inconsistency", &proto_h);
frag_size = last_block->upper; frag_size = last_block->upper;
} }
@ -238,36 +254,42 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
break; break;
if ( b->upper > n ) if ( b->upper > n )
reporter->InternalError("bad fragment reassembly"); {
reporter->InternalWarning("bad fragment reassembly");
DeleteTimer();
Expire(network_time);
return;
}
memcpy((void*) &pkt[b->seq], (const void*) b->block, memcpy((void*) &pkt[b->seq], (const void*) b->block,
b->upper - b->seq); b->upper - b->seq);
} }
delete reassembled_pkt; delete reassembled_pkt;
reassembled_pkt = 0;
if ( ((const struct ip*)pkt_start)->ip_v == 4 ) unsigned int version = ((const struct ip*)pkt_start)->ip_v;
if ( version == 4 )
{ {
struct ip* reassem4 = (struct ip*) pkt_start; struct ip* reassem4 = (struct ip*) pkt_start;
reassem4->ip_len = htons(frag_size + proto_hdr_len); reassem4->ip_len = htons(frag_size + proto_hdr_len);
reassembled_pkt = new IP_Hdr(reassem4, true); reassembled_pkt = new IP_Hdr(reassem4, true);
DeleteTimer();
} }
else if ( ((const struct ip*)pkt_start)->ip_v == 6 ) else if ( version == 6 )
{ {
struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start; struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start;
reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40); reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40);
const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n); const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n);
reassembled_pkt = new IP_Hdr(reassem6, true, n, chain); reassembled_pkt = new IP_Hdr(reassem6, true, n, chain);
DeleteTimer();
} }
else else
{ reporter->InternalWarning("bad IP version in fragment reassembly: %d",
reporter->InternalError("bad IP version in fragment reassembly"); version);
}
DeleteTimer();
} }
void FragReassembler::Expire(double t) void FragReassembler::Expire(double t)

View file

@ -35,6 +35,7 @@ public:
protected: protected:
void BlockInserted(DataBlock* start_block); void BlockInserted(DataBlock* start_block);
void Overlap(const u_char* b1, const u_char* b2, int n); void Overlap(const u_char* b1, const u_char* b2, int n);
void Weird(const char* name) const;
u_char* proto_hdr; u_char* proto_hdr;
IP_Hdr* reassembled_pkt; IP_Hdr* reassembled_pkt;

View file

@ -440,7 +440,6 @@ ID* ID::Unserialize(UnserialInfo* info)
default: default:
reporter->InternalError("unknown type for UnserialInfo::id_policy"); reporter->InternalError("unknown type for UnserialInfo::id_policy");
} }
} }
@ -543,7 +542,7 @@ bool ID::DoUnserialize(UnserialInfo* info)
} }
if ( installed_tmp && ! global_scope()->Remove(name) ) if ( installed_tmp && ! global_scope()->Remove(name) )
reporter->InternalError("tmp id missing"); reporter->InternalWarning("missing tmp ID in %s unserialization", name);
return true; return true;
} }

View file

@ -433,7 +433,10 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len,
const u_char* hdrs = (const u_char*) ip6; const u_char* hdrs = (const u_char*) ip6;
if ( total_len < (int)sizeof(struct ip6_hdr) ) if ( total_len < (int)sizeof(struct ip6_hdr) )
reporter->InternalError("IPv6_HdrChain::Init with truncated IP header"); {
reporter->InternalWarning("truncated IP header in IPv6_HdrChain::Init");
return;
}
do do
{ {
@ -623,9 +626,11 @@ VectorVal* IPv6_Hdr_Chain::BuildVal() const
break; break;
#endif #endif
default: default:
reporter->InternalError("IPv6_Hdr_Chain bad header %d", type); reporter->InternalWarning("IPv6_Hdr_Chain bad header %d", type);
break; Unref(ext_hdr);
continue;
} }
rval->Assign(rval->Size(), ext_hdr); rval->Assign(rval->Size(), ext_hdr);
} }

View file

@ -176,7 +176,14 @@ public:
* Returns whether the header chain indicates a fragmented packet. * Returns whether the header chain indicates a fragmented packet.
*/ */
bool IsFragment() const bool IsFragment() const
{ return chain[chain.size()-1]->Type() == IPPROTO_FRAGMENT; } {
if ( chain.empty() )
{
reporter->InternalWarning("empty IPv6 header chain");
return false;
}
return chain[chain.size()-1]->Type() == IPPROTO_FRAGMENT;
}
/** /**
* Returns pointer to fragment header structure if the chain contains one. * Returns pointer to fragment header structure if the chain contains one.
@ -216,9 +223,13 @@ public:
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6
if ( homeAddr ) if ( homeAddr )
return IPAddr(*homeAddr); return IPAddr(*homeAddr);
else
#endif #endif
return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src); if ( chain.empty() )
{
reporter->InternalWarning("empty IPv6 header chain");
return IPAddr();
}
return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src);
} }
/** /**
@ -230,8 +241,12 @@ public:
{ {
if ( finalDst ) if ( finalDst )
return IPAddr(*finalDst); return IPAddr(*finalDst);
else if ( chain.empty() )
return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_dst); {
reporter->InternalWarning("empty IPv6 header chain");
return IPAddr();
}
return IPAddr(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_dst);
} }
/** /**
@ -305,32 +320,6 @@ protected:
*/ */
class IP_Hdr { class IP_Hdr {
public: public:
/**
* Attempts to construct the header from some blob of data based on IP
* version number. Caller must have already checked that the header
* is not truncated.
* @param p pointer to memory containing an IPv4 or IPv6 packet.
* @param arg_del whether to take ownership of \a p pointer's memory.
* @param len the length of data, in bytes, pointed to by \a p.
*/
IP_Hdr(const u_char* p, bool arg_del, int len)
: ip4(0), ip6(0), del(arg_del), ip6_hdrs(0)
{
if ( ((const struct ip*)p)->ip_v == 4 )
ip4 = (const struct ip*)p;
else if ( ((const struct ip*)p)->ip_v == 6 )
{
ip6 = (const struct ip6_hdr*)p;
ip6_hdrs = new IPv6_Hdr_Chain(ip6, len);
}
else
{
if ( arg_del )
delete [] p;
reporter->InternalError("bad IP version in IP_Hdr ctor");
}
}
/** /**
* Construct the header wrapper from an IPv4 packet. Caller must have * Construct the header wrapper from an IPv4 packet. Caller must have
* already checked that the header is not truncated. * already checked that the header is not truncated.
@ -365,15 +354,12 @@ public:
*/ */
~IP_Hdr() ~IP_Hdr()
{ {
if ( ip6 ) delete ip6_hdrs;
delete ip6_hdrs;
if ( del ) if ( del )
{ {
if ( ip4 ) delete [] (struct ip*) ip4;
delete [] (struct ip*) ip4; delete [] (struct ip6_hdr*) ip6;
else
delete [] (struct ip6_hdr*) ip6;
} }
} }
@ -472,8 +458,14 @@ public:
* For IPv6 header chains, returns the type of the last header in the chain. * For IPv6 header chains, returns the type of the last header in the chain.
*/ */
uint8 LastHeader() const uint8 LastHeader() const
{ return ip4 ? IPPROTO_RAW : {
((*ip6_hdrs)[ip6_hdrs->Size()-1])->Type(); } if ( ip4 )
return IPPROTO_RAW;
size_t i = ip6_hdrs->Size();
if ( i > 0 )
return (*ip6_hdrs)[i-1]->Type();
return IPPROTO_NONE;
}
/** /**
* Returns the protocol type of the IP packet's payload, usually an * Returns the protocol type of the IP packet's payload, usually an
@ -481,8 +473,14 @@ public:
* header's Next Header value. * header's Next Header value.
*/ */
unsigned char NextProto() const unsigned char NextProto() const
{ return ip4 ? ip4->ip_p : {
((*ip6_hdrs)[ip6_hdrs->Size()-1])->NextHdr(); } if ( ip4 )
return ip4->ip_p;
size_t i = ip6_hdrs->Size();
if ( i > 0 )
return (*ip6_hdrs)[i-1]->NextHdr();
return IPPROTO_NONE;
}
/** /**
* Returns the IPv4 Time to Live or IPv6 Hop Limit field. * Returns the IPv4 Time to Live or IPv6 Hop Limit field.

View file

@ -36,7 +36,7 @@ bool HashVal::Feed(const void* data, size_t size)
if ( valid ) if ( valid )
return DoFeed(data, size); return DoFeed(data, size);
reporter->InternalError("invalid opaque hash value"); Error("attempt to update an invalid opaque hash value");
return false; return false;
} }

View file

@ -20,7 +20,10 @@ void* PrefixTable::Insert(const IPAddr& addr, int width, void* data)
Deref_Prefix(prefix); Deref_Prefix(prefix);
if ( ! node ) if ( ! node )
reporter->InternalError("Cannot create node in patricia tree"); {
reporter->InternalWarning("Cannot create node in patricia tree");
return 0;
}
void* old = node->data; void* old = node->data;
@ -49,7 +52,7 @@ void* PrefixTable::Insert(const Val* value, void* data)
break; break;
default: default:
reporter->InternalError("Wrong index type for PrefixTable"); reporter->InternalWarning("Wrong index type for PrefixTable");
return 0; return 0;
} }
} }
@ -83,8 +86,8 @@ void* PrefixTable::Lookup(const Val* value, bool exact) const
break; break;
default: default:
reporter->InternalError("Wrong index type %d for PrefixTable", reporter->InternalWarning("Wrong index type %d for PrefixTable",
value->Type()->Tag()); value->Type()->Tag());
return 0; return 0;
} }
} }
@ -122,7 +125,7 @@ void* PrefixTable::Remove(const Val* value)
break; break;
default: default:
reporter->InternalError("Wrong index type for PrefixTable"); reporter->InternalWarning("Wrong index type for PrefixTable");
return 0; return 0;
} }
} }

View file

@ -21,8 +21,6 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq,
upper = seq + size; upper = seq + size;
block = new u_char[size]; block = new u_char[size];
if ( ! block )
reporter->InternalError("out of memory");
memcpy((void*) block, (const void*) data, size); memcpy((void*) block, (const void*) data, size);

View file

@ -3584,8 +3584,6 @@ bool SocketComm::ProcessParentMessage()
InternalError(fmt("unknown msg type %d", parent_msgtype)); InternalError(fmt("unknown msg type %d", parent_msgtype));
return true; return true;
} }
InternalError("cannot be reached");
} }
case ARGS: case ARGS:
@ -3609,9 +3607,9 @@ bool SocketComm::ProcessParentMessage()
default: default:
InternalError("unknown msgstate"); InternalError("unknown msgstate");
return false;
} }
InternalError("cannot be reached");
return false; return false;
} }

View file

@ -137,11 +137,27 @@ void Reporter::InternalError(const char* fmt, ...)
abort(); abort();
} }
void Reporter::InternalAnalyzerError(analyzer::Analyzer* a, const char* fmt,
...)
{
if ( a )
a->SetSkip(true);
va_list ap;
va_start(ap, fmt);
// Always log to stderr.
// TODO: would be nice to also log a call stack.
DoLog("analyzer error", reporter_error, stderr, 0, 0, true, true, 0, fmt,
ap);
va_end(ap);
}
void Reporter::InternalWarning(const char* fmt, ...) void Reporter::InternalWarning(const char* fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
FILE* out = warnings_to_stderr ? stderr : 0; FILE* out = warnings_to_stderr ? stderr : 0;
// TODO: would be nice to also log a call stack.
DoLog("internal warning", reporter_warning, out, 0, 0, true, true, 0, fmt, DoLog("internal warning", reporter_warning, out, 0, 0, true, true, 0, fmt,
ap); ap);
va_end(ap); va_end(ap);

View file

@ -12,6 +12,7 @@
#include "EventHandler.h" #include "EventHandler.h"
#include "IPAddr.h" #include "IPAddr.h"
namespace analyzer { class Analyzer; }
class Connection; class Connection;
class Location; class Location;
class Reporter; class Reporter;
@ -91,6 +92,10 @@ public:
// dump after the message has been reported. // dump after the message has been reported.
void InternalError(const char* fmt, ...) FMT_ATTR; void InternalError(const char* fmt, ...) FMT_ATTR;
// Reporter an internal analyzer error. That analyzer will not process
// any further input, but Bro otherwise continues normally.
void InternalAnalyzerError(analyzer::Analyzer* a, const char* fmt, ...);
// Toggle whether non-fatal messages should be reported through the // Toggle whether non-fatal messages should be reported through the
// scripting layer rather on standard output. Fatal errors are always // scripting layer rather on standard output. Fatal errors are always
// reported via stderr. // reported via stderr.

View file

@ -521,7 +521,7 @@ static inline bool compare(const maskedvalue_list& mvals, uint32 v,
break; break;
default: default:
reporter->InternalError("unknown comparison type"); reporter->InternalError("unknown RuleHdrTest comparison type");
break; break;
} }
return false; return false;
@ -556,7 +556,7 @@ static inline bool compare(const vector<IPPrefix>& prefixes, const IPAddr& a,
break; break;
default: default:
reporter->InternalError("unknown comparison type"); reporter->InternalError("unknown RuleHdrTest comparison type");
break; break;
} }
return false; return false;
@ -661,7 +661,7 @@ RuleEndpointState* RuleMatcher::InitEndpoint(analyzer::Analyzer* analyzer,
break; break;
default: default:
reporter->InternalError("unknown protocol"); reporter->InternalError("unknown RuleHdrTest protocol type");
break; break;
} }

View file

@ -419,7 +419,7 @@ bool Serializer::UnserializeCall(UnserialInfo* info)
break; break;
default: default:
reporter->InternalError("invalid function flavor"); reporter->InternalError("unserialized call for invalid function flavor");
break; break;
} }

View file

@ -781,7 +781,10 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
} }
else else
reporter->InternalError("Bad IP protocol version in DoNextInnerPacket"); {
reporter->InternalWarning("Bad IP protocol version in ParseIPPacket");
return -1;
}
if ( (uint32)caplen != inner->TotalLen() ) if ( (uint32)caplen != inner->TotalLen() )
return (uint32)caplen < inner->TotalLen() ? -1 : 1; return (uint32)caplen < inner->TotalLen() ? -1 : 1;
@ -993,21 +996,21 @@ void NetSessions::Remove(Connection* c)
switch ( c->ConnTransport() ) { switch ( c->ConnTransport() ) {
case TRANSPORT_TCP: case TRANSPORT_TCP:
if ( ! tcp_conns.RemoveEntry(k) ) if ( ! tcp_conns.RemoveEntry(k) )
reporter->InternalError("connection missing"); reporter->InternalWarning("connection missing");
break; break;
case TRANSPORT_UDP: case TRANSPORT_UDP:
if ( ! udp_conns.RemoveEntry(k) ) if ( ! udp_conns.RemoveEntry(k) )
reporter->InternalError("connection missing"); reporter->InternalWarning("connection missing");
break; break;
case TRANSPORT_ICMP: case TRANSPORT_ICMP:
if ( ! icmp_conns.RemoveEntry(k) ) if ( ! icmp_conns.RemoveEntry(k) )
reporter->InternalError("connection missing"); reporter->InternalWarning("connection missing");
break; break;
case TRANSPORT_UNKNOWN: case TRANSPORT_UNKNOWN:
reporter->InternalError("unknown transport when removing connection"); reporter->InternalWarning("unknown transport when removing connection");
break; break;
} }
@ -1018,13 +1021,18 @@ void NetSessions::Remove(Connection* c)
void NetSessions::Remove(FragReassembler* f) void NetSessions::Remove(FragReassembler* f)
{ {
if ( ! f ) return; if ( ! f )
HashKey* k = f->Key(); return;
if ( ! k )
reporter->InternalError("fragment block not in dictionary");
if ( ! fragments.RemoveEntry(k) ) HashKey* k = f->Key();
reporter->InternalError("fragment block missing");
if ( k )
{
if ( ! fragments.RemoveEntry(k) )
reporter->InternalWarning("fragment reassembler not in dict");
}
else
reporter->InternalWarning("missing fragment reassembler hash key");
Unref(f); Unref(f);
} }
@ -1055,7 +1063,9 @@ void NetSessions::Insert(Connection* c)
break; break;
default: default:
reporter->InternalError("unknown connection type"); reporter->InternalWarning("unknown connection type");
Unref(c);
return;
} }
if ( old && old != c ) if ( old && old != c )
@ -1147,8 +1157,8 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
tproto = TRANSPORT_ICMP; tproto = TRANSPORT_ICMP;
break; break;
default: default:
reporter->InternalError("unknown transport protocol"); reporter->InternalWarning("unknown transport protocol");
break; return 0;
}; };
if ( tproto == TRANSPORT_TCP ) if ( tproto == TRANSPORT_TCP )
@ -1181,7 +1191,13 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation); Connection* conn = new Connection(this, k, t, id, flow_label, encapsulation);
conn->SetTransport(tproto); conn->SetTransport(tproto);
analyzer_mgr->BuildInitialAnalyzerTree(conn);
if ( ! analyzer_mgr->BuildInitialAnalyzerTree(conn) )
{
conn->Done();
Unref(conn);
return 0;
}
bool external = conn->IsExternal(); bool external = conn->IsExternal();

View file

@ -799,8 +799,9 @@ int SwitchStmt::FindCaseLabelMatch(const Val* v) const
if ( ! hk ) if ( ! hk )
{ {
reporter->PushLocation(e->GetLocationInfo()); reporter->PushLocation(e->GetLocationInfo());
reporter->InternalError("switch expression type mismatch (%s/%s)", reporter->Error("switch expression type mismatch (%s/%s)",
type_name(v->Type()->Tag()), type_name(e->Type()->Tag())); type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
return -1;
} }
int* label_idx = case_label_map.Lookup(hk); int* label_idx = case_label_map.Lookup(hk);

View file

@ -238,7 +238,6 @@ bool Val::DoSerialize(SerialInfo* info) const
return false; return false;
} }
reporter->InternalError("should not be reached");
return false; return false;
} }
@ -316,7 +315,6 @@ bool Val::DoUnserialize(UnserialInfo* info)
return false; return false;
} }
reporter->InternalError("should not be reached");
return false; return false;
} }
@ -519,8 +517,9 @@ void Val::ValDescribe(ODesc* d) const
break; break;
default: default:
// Don't call Internal(), that'll loop! reporter->InternalWarning("Val description unavailable");
reporter->InternalError("Val description unavailable"); d->Add("<value description unavailable>");
break;
} }
} }
@ -1893,7 +1892,7 @@ Val* TableVal::Delete(const Val* index)
Val* va = v ? (v->Value() ? v->Value() : this->Ref()) : 0; Val* va = v ? (v->Value() ? v->Value() : this->Ref()) : 0;
if ( subnets && ! subnets->Remove(index) ) if ( subnets && ! subnets->Remove(index) )
reporter->InternalError("index not in prefix table"); reporter->InternalWarning("index not in prefix table");
if ( LoggingAccess() ) if ( LoggingAccess() )
{ {
@ -1935,7 +1934,7 @@ Val* TableVal::Delete(const HashKey* k)
{ {
Val* index = table_hash->RecoverVals(k); Val* index = table_hash->RecoverVals(k);
if ( ! subnets->Remove(index) ) if ( ! subnets->Remove(index) )
reporter->InternalError("index not in prefix table"); reporter->InternalWarning("index not in prefix table");
Unref(index); Unref(index);
} }
@ -2195,7 +2194,7 @@ void TableVal::DoExpire(double t)
{ {
Val* index = RecoverIndex(k); Val* index = RecoverIndex(k);
if ( ! subnets->Remove(index) ) if ( ! subnets->Remove(index) )
reporter->InternalError("index not in prefix table"); reporter->InternalWarning("index not in prefix table");
Unref(index); Unref(index);
} }
@ -3300,7 +3299,7 @@ int same_atomic_val(const Val* v1, const Val* v2)
return v1->AsSubNet() == v2->AsSubNet(); return v1->AsSubNet() == v2->AsSubNet();
default: default:
reporter->InternalError("same_atomic_val called for non-atomic value"); reporter->InternalWarning("same_atomic_val called for non-atomic value");
return 0; return 0;
} }

View file

@ -303,7 +303,7 @@ public:
* Signals the analyzer to skip all further input processsing. The \a * Signals the analyzer to skip all further input processsing. The \a
* Next*() methods check this flag and discard the input if its set. * Next*() methods check this flag and discard the input if its set.
* *
* @param do_skipe If true, further processing will be skipped. * @param do_skip If true, further processing will be skipped.
*/ */
void SetSkip(bool do_skip) { skip = do_skip; } void SetSkip(bool do_skip) { skip = do_skip; }

View file

@ -250,6 +250,9 @@ bool Manager::RegisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 port
{ {
tag_set* l = LookupPort(proto, port, true); tag_set* l = LookupPort(proto, port, true);
if ( ! l )
return false;
#ifdef DEBUG #ifdef DEBUG
const char* name = GetComponentName(tag); const char* name = GetComponentName(tag);
DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name, port, proto); DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name, port, proto);
@ -263,6 +266,9 @@ bool Manager::UnregisterAnalyzerForPort(Tag tag, TransportProto proto, uint32 po
{ {
tag_set* l = LookupPort(proto, port, true); tag_set* l = LookupPort(proto, port, true);
if ( ! l )
return true; // still a "successful" unregistration
#ifdef DEBUG #ifdef DEBUG
const char* name = GetComponentName(tag); const char* name = GetComponentName(tag);
DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name, port, proto); DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name, port, proto);
@ -277,18 +283,27 @@ Analyzer* Manager::InstantiateAnalyzer(Tag tag, Connection* conn)
Component* c = Lookup(tag); Component* c = Lookup(tag);
if ( ! c ) if ( ! c )
reporter->InternalError("request to instantiate unknown analyzer"); {
reporter->InternalWarning("request to instantiate unknown analyzer");
return 0;
}
if ( ! c->Enabled() ) if ( ! c->Enabled() )
return 0; return 0;
if ( ! c->Factory() ) if ( ! c->Factory() )
reporter->InternalError("analyzer %s cannot be instantiated dynamically", GetComponentName(tag)); {
reporter->InternalWarning("analyzer %s cannot be instantiated dynamically", GetComponentName(tag));
return 0;
}
Analyzer* a = c->Factory()(conn); Analyzer* a = c->Factory()(conn);
if ( ! a ) if ( ! a )
reporter->InternalError("analyzer instantiation failed"); {
reporter->InternalWarning("analyzer instantiation failed");
return 0;
}
a->SetAnalyzerTag(tag); a->SetAnalyzerTag(tag);
@ -315,7 +330,8 @@ Manager::tag_set* Manager::LookupPort(TransportProto proto, uint32 port, bool ad
break; break;
default: default:
reporter->InternalError("unsupport transport protocol in analyzer::Manager::LookupPort"); reporter->InternalWarning("unsupported transport protocol in analyzer::Manager::LookupPort");
return 0;
} }
analyzer_map_by_port::const_iterator i = m->find(port); analyzer_map_by_port::const_iterator i = m->find(port);
@ -338,7 +354,6 @@ Manager::tag_set* Manager::LookupPort(PortVal* val, bool add_if_not_found)
bool Manager::BuildInitialAnalyzerTree(Connection* conn) bool Manager::BuildInitialAnalyzerTree(Connection* conn)
{ {
Analyzer* analyzer = 0;
tcp::TCP_Analyzer* tcp = 0; tcp::TCP_Analyzer* tcp = 0;
udp::UDP_Analyzer* udp = 0; udp::UDP_Analyzer* udp = 0;
icmp::ICMP_Analyzer* icmp = 0; icmp::ICMP_Analyzer* icmp = 0;
@ -374,14 +389,9 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn)
} }
default: default:
reporter->InternalError("unknown protocol"); reporter->InternalWarning("unknown protocol can't build analyzer tree");
}
if ( ! root )
{
DBG_ANALYZER(conn, "cannot build analyzer tree");
return false; return false;
} }
// Any scheduled analyzer? // Any scheduled analyzer?
for ( tag_set::iterator i = expected.begin(); i != expected.end(); i++ ) for ( tag_set::iterator i = expected.begin(); i != expected.end(); i++ )

View file

@ -214,7 +214,8 @@ public:
* *
* @return The new analyzer instance. Note that the analyzer will not * @return The new analyzer instance. Note that the analyzer will not
* have been added to the connection's analyzer tree yet. Returns * have been added to the connection's analyzer tree yet. Returns
* null if tag is invalid or the requested analyzer is disabled. * null if tag is invalid, the requested analyzer is disabled, or the
* analyzer can't be instantiated.
*/ */
Analyzer* InstantiateAnalyzer(Tag tag, Connection* c); Analyzer* InstantiateAnalyzer(Tag tag, Connection* c);

View file

@ -698,7 +698,11 @@ void HTTP_Message::SubmitData(int len, const char* buf)
{ {
if ( buf != (const char*) data_buffer->Bytes() + buffer_offset || if ( buf != (const char*) data_buffer->Bytes() + buffer_offset ||
buffer_offset + len > buffer_size ) buffer_offset + len > buffer_size )
reporter->InternalError("buffer misalignment"); {
reporter->InternalAnalyzerError(MyHTTP_Analyzer(),
"HTTP message buffer misalignment");
return;
}
buffer_offset += len; buffer_offset += len;
if ( buffer_offset >= buffer_size ) if ( buffer_offset >= buffer_size )
@ -743,7 +747,9 @@ void HTTP_Message::SubmitEvent(int event_type, const char* detail)
break; break;
default: default:
reporter->InternalError("unrecognized HTTP message event"); reporter->InternalAnalyzerError(MyHTTP_Analyzer(),
"unrecognized HTTP message event");
return;
} }
MyHTTP_Analyzer()->HTTP_Event(category, detail); MyHTTP_Analyzer()->HTTP_Event(category, detail);
@ -962,7 +968,13 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
switch ( request_state ) { switch ( request_state ) {
case EXPECT_REQUEST_LINE: case EXPECT_REQUEST_LINE:
if ( HTTP_RequestLine(line, end_of_line) ) {
int res = HTTP_RequestLine(line, end_of_line);
if ( res < 0 )
return;
else if ( res > 0 )
{ {
++num_requests; ++num_requests;
@ -1001,6 +1013,7 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
} }
} }
} }
}
break; break;
case EXPECT_REQUEST_MESSAGE: case EXPECT_REQUEST_MESSAGE:
@ -1225,7 +1238,10 @@ int HTTP_Analyzer::HTTP_RequestLine(const char* line, const char* end_of_line)
request_method = new StringVal(end_of_method - line, line); request_method = new StringVal(end_of_method - line, line);
if ( ! ParseRequest(rest, end_of_line) ) if ( ! ParseRequest(rest, end_of_line) )
reporter->InternalError("HTTP ParseRequest failed"); {
reporter->InternalAnalyzerError(this, "HTTP ParseRequest failed");
return -1;
}
Conn()->Match(Rule::HTTP_REQUEST, Conn()->Match(Rule::HTTP_REQUEST,
(const u_char*) unescaped_URI->AsString()->Bytes(), (const u_char*) unescaped_URI->AsString()->Bytes(),

View file

@ -60,9 +60,9 @@ void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
break; break;
default: default:
reporter->InternalError("unexpected IP proto in ICMP analyzer: %d", reporter->InternalAnalyzerError(this,
ip->NextProto()); "unexpected IP proto in ICMP analyzer: %d", ip->NextProto());
break; return;
} }
if ( chksum != 0xffff ) if ( chksum != 0xffff )
@ -99,7 +99,11 @@ void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
else if ( ip->NextProto() == IPPROTO_ICMPV6 ) else if ( ip->NextProto() == IPPROTO_ICMPV6 )
NextICMP6(current_timestamp, icmpp, len, caplen, data, ip); NextICMP6(current_timestamp, icmpp, len, caplen, data, ip);
else else
reporter->InternalError("unexpected next protocol in ICMP::DeliverPacket()"); {
reporter->InternalAnalyzerError(this,
"expected ICMP as IP packet's protocol, got %d", ip->NextProto());
return;
}
if ( caplen >= len ) if ( caplen >= len )

View file

@ -117,7 +117,11 @@ void Login_Analyzer::NewLine(bool orig, char* line)
} }
if ( state != LOGIN_STATE_CONFUSED ) if ( state != LOGIN_STATE_CONFUSED )
reporter->InternalError("bad state in Login_Analyzer::NewLine"); {
reporter->InternalAnalyzerError(this,
"bad state in Login_Analyzer::NewLine");
return;
}
// When we're in "confused", we feed each user input line to // When we're in "confused", we feed each user input line to
// login_confused_text, but also scan the text in the // login_confused_text, but also scan the text in the
@ -550,6 +554,9 @@ int Login_Analyzer::IsTimeout(const char* line) const
int Login_Analyzer::IsEmpty(const char* line) const int Login_Analyzer::IsEmpty(const char* line) const
{ {
if ( ! line )
return true;
while ( *line && isspace(*line) ) while ( *line && isspace(*line) )
++line; ++line;
@ -571,10 +578,14 @@ void Login_Analyzer::AddUserText(const char* line)
} }
} }
char* Login_Analyzer::PeekUserText() const char* Login_Analyzer::PeekUserText()
{ {
if ( num_user_text <= 0 ) if ( num_user_text <= 0 )
reporter->InternalError("underflow in Login_Analyzer::PeekUserText()"); {
reporter->InternalAnalyzerError(this,
"underflow in Login_Analyzer::PeekUserText()");
return 0;
}
return user_text[user_text_first]; return user_text[user_text_first];
} }
@ -583,6 +594,9 @@ char* Login_Analyzer::PopUserText()
{ {
char* s = PeekUserText(); char* s = PeekUserText();
if ( ! s )
return 0;
if ( ++user_text_first == MAX_USER_TEXT ) if ( ++user_text_first == MAX_USER_TEXT )
user_text_first = 0; user_text_first = 0;
@ -594,8 +608,11 @@ char* Login_Analyzer::PopUserText()
Val* Login_Analyzer::PopUserTextVal() Val* Login_Analyzer::PopUserTextVal()
{ {
char* s = PopUserText(); char* s = PopUserText();
BroString* bs = new BroString(1, byte_vec(s), strlen(s));
return new StringVal(bs); if ( s )
return new StringVal(new BroString(1, byte_vec(s), strlen(s)));
else
return new StringVal("");
} }
int Login_Analyzer::MatchesTypeahead(const char* line) const int Login_Analyzer::MatchesTypeahead(const char* line) const

View file

@ -55,8 +55,8 @@ protected:
int IsEmpty(const char* line) const; int IsEmpty(const char* line) const;
void AddUserText(const char* line); // complains on overflow void AddUserText(const char* line); // complains on overflow
char* PeekUserText() const; // internal error on underflow char* PeekUserText(); // internal warning on underflow
char* PopUserText(); // internal error on underflow char* PopUserText(); // internal warning on underflow
Val* PopUserTextVal(); Val* PopUserTextVal();
int MatchesTypeahead(const char* line) const; int MatchesTypeahead(const char* line) const;

View file

@ -39,8 +39,13 @@ TelnetOption::TelnetOption(NVT_Analyzer* arg_endp, unsigned int arg_code)
void TelnetOption::RecvOption(unsigned int type) void TelnetOption::RecvOption(unsigned int type)
{ {
TelnetOption* peer = endp->FindPeerOption(code); TelnetOption* peer = endp->FindPeerOption(code);
if ( ! peer ) if ( ! peer )
reporter->InternalError("option peer missing in TelnetOption::RecvOption"); {
reporter->InternalAnalyzerError(endp,
"option peer missing in TelnetOption::RecvOption");
return;
}
// WILL/WONT/DO/DONT are messages we've *received* from our peer. // WILL/WONT/DO/DONT are messages we've *received* from our peer.
switch ( type ) { switch ( type ) {
@ -85,7 +90,9 @@ void TelnetOption::RecvOption(unsigned int type)
break; break;
default: default:
reporter->InternalError("bad option type in TelnetOption::RecvOption"); reporter->InternalAnalyzerError(endp,
"bad option type in TelnetOption::RecvOption");
return;
} }
} }
@ -165,7 +172,11 @@ void TelnetEncryptOption::RecvSubOption(u_char* data, int len)
(TelnetEncryptOption*) endp->FindPeerOption(code); (TelnetEncryptOption*) endp->FindPeerOption(code);
if ( ! peer ) if ( ! peer )
reporter->InternalError("option peer missing in TelnetEncryptOption::RecvSubOption"); {
reporter->InternalAnalyzerError(endp,
"option peer missing in TelnetEncryptOption::RecvSubOption");
return;
}
if ( peer->DidRequest() || peer->DoingEncryption() || if ( peer->DidRequest() || peer->DoingEncryption() ||
peer->Endpoint()->AuthenticationHasBeenAccepted() ) peer->Endpoint()->AuthenticationHasBeenAccepted() )
@ -201,7 +212,10 @@ void TelnetAuthenticateOption::RecvSubOption(u_char* data, int len)
(TelnetAuthenticateOption*) endp->FindPeerOption(code); (TelnetAuthenticateOption*) endp->FindPeerOption(code);
if ( ! peer ) if ( ! peer )
reporter->InternalError("option peer missing in TelnetAuthenticateOption::RecvSubOption"); {
reporter->InternalAnalyzerError(endp,
"option peer missing in TelnetAuthenticateOption::RecvSubOption");
}
if ( ! peer->DidRequestAuthentication() ) if ( ! peer->DidRequestAuthentication() )
InconsistentOption(0); InconsistentOption(0);

View file

@ -131,7 +131,8 @@ void Contents_Rsh_Analyzer::DoDeliver(int len, const u_char* data)
break; break;
default: default:
reporter->InternalError("bad state in Contents_Rsh_Analyzer::DoDeliver"); reporter->InternalAnalyzerError(this,
"bad state in Contents_Rsh_Analyzer::DoDeliver");
break; break;
} }
} }
@ -186,7 +187,10 @@ void Rsh_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
void Rsh_Analyzer::ClientUserName(const char* s) void Rsh_Analyzer::ClientUserName(const char* s)
{ {
if ( client_name ) if ( client_name )
reporter->InternalError("multiple rsh client names"); {
reporter->InternalAnalyzerError(this, "multiple rsh client names");
return;
}
client_name = new StringVal(s); client_name = new StringVal(s);
} }
@ -194,7 +198,11 @@ void Rsh_Analyzer::ClientUserName(const char* s)
void Rsh_Analyzer::ServerUserName(const char* s) void Rsh_Analyzer::ServerUserName(const char* s)
{ {
if ( username ) if ( username )
reporter->InternalError("multiple rsh initial client names"); {
reporter->InternalAnalyzerError(this,
"multiple rsh initial client names");
return;
}
username = new StringVal(s); username = new StringVal(s);
} }

View file

@ -193,7 +193,8 @@ void Contents_Rlogin_Analyzer::DoDeliver(int len, const u_char* data)
break; break;
default: default:
reporter->InternalError("bad state in Contents_Rlogin_Analyzer::DoDeliver"); reporter->InternalAnalyzerError(this,
"bad state in Contents_Rlogin_Analyzer::DoDeliver");
break; break;
} }
} }
@ -224,7 +225,10 @@ Rlogin_Analyzer::Rlogin_Analyzer(Connection* conn)
void Rlogin_Analyzer::ClientUserName(const char* s) void Rlogin_Analyzer::ClientUserName(const char* s)
{ {
if ( client_name ) if ( client_name )
reporter->InternalError("multiple rlogin client names"); {
reporter->InternalAnalyzerError(this, "multiple rlogin client names");
return;
}
client_name = new StringVal(s); client_name = new StringVal(s);
} }

View file

@ -557,7 +557,12 @@ void MIME_Entity::init()
MIME_Entity::~MIME_Entity() MIME_Entity::~MIME_Entity()
{ {
if ( ! end_of_data ) if ( ! end_of_data )
reporter->InternalError("EndOfData must be called before delete a MIME_Entity"); {
// TODO: not sure about this
reporter->InternalWarning(
"missing MIME_Entity::EndOfData() before ~MIME_Entity");
EndOfData();
}
delete current_header_line; delete current_header_line;
Unref(content_type_str); Unref(content_type_str);
@ -1088,8 +1093,6 @@ void MIME_Entity::DecodeBase64(int len, const char* data)
rlen = 128; rlen = 128;
char* prbuf = rbuf; char* prbuf = rbuf;
int decoded = base64_decoder->Decode(len, data, &rlen, &prbuf); int decoded = base64_decoder->Decode(len, data, &rlen, &prbuf);
if ( prbuf != rbuf )
reporter->InternalError("buffer pointer modified in base64 decoding");
DataOctets(rlen, rbuf); DataOctets(rlen, rbuf);
len -= decoded; data += decoded; len -= decoded; data += decoded;
} }
@ -1098,7 +1101,10 @@ void MIME_Entity::DecodeBase64(int len, const char* data)
void MIME_Entity::StartDecodeBase64() void MIME_Entity::StartDecodeBase64()
{ {
if ( base64_decoder ) if ( base64_decoder )
reporter->InternalError("previous Base64 decoder not released!"); {
reporter->InternalWarning("previous MIME Base64 decoder not released");
delete base64_decoder;
}
base64_decoder = new Base64Converter(message->GetAnalyzer()); base64_decoder = new Base64Converter(message->GetAnalyzer());
} }
@ -1114,8 +1120,6 @@ void MIME_Entity::FinishDecodeBase64()
if ( base64_decoder->Done(&rlen, &prbuf) ) if ( base64_decoder->Done(&rlen, &prbuf) )
{ // some remaining data { // some remaining data
if ( prbuf != rbuf )
reporter->InternalError("buffer pointer modified in base64 decoding");
if ( rlen > 0 ) if ( rlen > 0 )
DataOctets(rlen, rbuf); DataOctets(rlen, rbuf);
} }
@ -1390,7 +1394,11 @@ void MIME_Mail::SubmitAllHeaders(MIME_HeaderList& hlist)
void MIME_Mail::SubmitData(int len, const char* buf) void MIME_Mail::SubmitData(int len, const char* buf)
{ {
if ( buf != (char*) data_buffer->Bytes() + buffer_start ) if ( buf != (char*) data_buffer->Bytes() + buffer_start )
reporter->InternalError("buffer misalignment"); {
reporter->InternalAnalyzerError(GetAnalyzer(),
"MIME buffer misalignment");
return;
}
if ( compute_content_hash ) if ( compute_content_hash )
{ {
@ -1483,7 +1491,9 @@ void MIME_Mail::SubmitEvent(int event_type, const char* detail)
break; break;
default: default:
reporter->InternalError("unrecognized MIME_Mail event"); reporter->InternalAnalyzerError(GetAnalyzer(),
"unrecognized MIME_Mail event");
return;
} }
if ( mime_event ) if ( mime_event )

View file

@ -193,7 +193,8 @@ public:
virtual ~MIME_Message() virtual ~MIME_Message()
{ {
if ( ! finished ) if ( ! finished )
reporter->InternalError("Done() must be called before destruction"); reporter->InternalAnalyzerError(analyzer,
"missing MIME_Message::Done() call");
} }
virtual void Done() { finished = 1; } virtual void Done() { finished = 1; }

View file

@ -209,7 +209,9 @@ void POP3_Analyzer::ProcessRequest(int length, const char* line)
break; break;
default: default:
reporter->InternalError("unexpected authorization state"); reporter->InternalAnalyzerError(this,
"unexpected POP3 authorization state");
return;
} }
delete decoded; delete decoded;
@ -565,7 +567,8 @@ void POP3_Analyzer::ProcessClientCmd()
break; break;
default: default:
reporter->InternalError("command not known"); reporter->InternalAnalyzerError(this, "unknown POP3 command");
return;
} }
} }

View file

@ -265,7 +265,10 @@ int RPC_Interpreter::DeliverRPC(const u_char* buf, int n, int rpclen,
} }
else if ( n < 0 ) else if ( n < 0 )
reporter->InternalError("RPC underflow"); {
reporter->InternalAnalyzerError(analyzer, "RPC underflow");
return 0;
}
return 1; return 1;
} }
@ -474,8 +477,12 @@ bool Contents_RPC::CheckResync(int& len, const u_char*& data, bool orig)
} }
if ( resync_toskip != 0 ) if ( resync_toskip != 0 )
{
// Should never happen. // Should never happen.
reporter->InternalError("RPC resync: skipping over data failed"); reporter->InternalAnalyzerError(this,
"RPC resync: skipping over data failed");
return false;
}
// Now lets see whether data points to the beginning of a RPC // Now lets see whether data points to the beginning of a RPC
// frame. If the resync processs is successful, we should be // frame. If the resync processs is successful, we should be
@ -625,7 +632,11 @@ void Contents_RPC::DeliverStream(int len, const u_char* data, bool orig)
marker_buf.Init(4,4); marker_buf.Init(4,4);
if ( ! dummy_p ) if ( ! dummy_p )
reporter->InternalError("inconsistent RPC record marker extraction"); {
reporter->InternalAnalyzerError(this,
"inconsistent RPC record marker extraction");
return;
}
last_frag = (marker & 0x80000000) != 0; last_frag = (marker & 0x80000000) != 0;
marker &= 0x7fffffff; marker &= 0x7fffffff;

View file

@ -738,7 +738,9 @@ int SMB_Session::ParseTransaction(int is_orig, int cmd,
break; break;
default: default:
reporter->InternalError("command mismatch for ParseTransaction"); reporter->InternalAnalyzerError(analyzer,
"command mismatch for SMB_Session::ParseTransaction");
return 0;
} }
int ret; int ret;

View file

@ -102,9 +102,6 @@ void ContentLine_Analyzer::DeliverStream(int len, const u_char* data,
delete [] buf; delete [] buf;
buf = tmp; buf = tmp;
if ( ! buf )
reporter->InternalError("out of memory delivering endpoint line");
} }
DoDeliver(len, data); DoDeliver(len, data);
@ -126,7 +123,11 @@ void ContentLine_Analyzer::EndpointEOF(bool is_orig)
void ContentLine_Analyzer::SetPlainDelivery(int64_t length) void ContentLine_Analyzer::SetPlainDelivery(int64_t length)
{ {
if ( length < 0 ) if ( length < 0 )
reporter->InternalError("negative length for plain delivery"); {
reporter->InternalAnalyzerError(this,
"negative length for plain delivery");
return;
}
plain_delivery_length = length; plain_delivery_length = length;
} }

View file

@ -1580,7 +1580,8 @@ BroFile* TCP_Analyzer::GetContentsFile(unsigned int direction) const
default: default:
break; break;
} }
reporter->InternalError("inconsistency in TCP_Analyzer::GetContentsFile"); reporter->Error("bad direction %u in TCP_Analyzer::GetContentsFile",
direction);
return 0; return 0;
} }

View file

@ -34,10 +34,8 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig)
hist_last_SYN = hist_last_FIN = hist_last_RST = 0; hist_last_SYN = hist_last_FIN = hist_last_RST = 0;
src_addr = is_orig ? tcp_analyzer->Conn()->RespAddr() : src_addr = is_orig ? Conn()->RespAddr() : Conn()->OrigAddr();
tcp_analyzer->Conn()->OrigAddr(); dst_addr = is_orig ? Conn()->OrigAddr() : Conn()->RespAddr();
dst_addr = is_orig ? tcp_analyzer->Conn()->OrigAddr() :
tcp_analyzer->Conn()->RespAddr();
checksum_base = ones_complement_checksum(src_addr, 0); checksum_base = ones_complement_checksum(src_addr, 0);
checksum_base = ones_complement_checksum(dst_addr, checksum_base); checksum_base = ones_complement_checksum(dst_addr, checksum_base);
@ -54,6 +52,11 @@ TCP_Endpoint::~TCP_Endpoint()
Unref(contents_file); Unref(contents_file);
} }
Connection* TCP_Endpoint::Conn() const
{
return tcp_analyzer->Conn();
}
void TCP_Endpoint::Done() void TCP_Endpoint::Done()
{ {
if ( contents_processor ) if ( contents_processor )
@ -143,7 +146,7 @@ void TCP_Endpoint::SetState(EndpointState new_state)
// handshake. // handshake.
if ( ! is_handshake(new_state) ) if ( ! is_handshake(new_state) )
if ( is_handshake(state) && is_handshake(peer->state) ) if ( is_handshake(state) && is_handshake(peer->state) )
tcp_analyzer->Conn()->SetInactivityTimeout(tcp_inactivity_timeout); Conn()->SetInactivityTimeout(tcp_inactivity_timeout);
prev_state = state; prev_state = state;
state = new_state; state = new_state;
@ -207,8 +210,20 @@ int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen,
FILE* f = contents_file->Seek(seq - contents_start_seq); FILE* f = contents_file->Seek(seq - contents_start_seq);
if ( fwrite(data, 1, len, f) < unsigned(len) ) if ( fwrite(data, 1, len, f) < unsigned(len) )
// ### this should really generate an event {
reporter->InternalError("contents write failed"); char buf[256];
strerror_r(errno, buf, sizeof(buf));
reporter->Error("TCP contents write failed: %s", buf);
if ( contents_file_write_failure )
{
val_list* vl = new val_list();
vl->append(Conn()->BuildConnVal());
vl->append(new Val(IsOrig(), TYPE_BOOL));
vl->append(new StringVal(buf));
tcp_analyzer->ConnectionEvent(contents_file_write_failure, vl);
}
}
} }
return status; return status;
@ -241,7 +256,7 @@ int TCP_Endpoint::CheckHistory(uint32 mask, char code)
code = tolower(code); code = tolower(code);
} }
return tcp_analyzer->Conn()->CheckHistory(mask, code); return Conn()->CheckHistory(mask, code);
} }
void TCP_Endpoint::AddHistory(char code) void TCP_Endpoint::AddHistory(char code)
@ -249,6 +264,6 @@ void TCP_Endpoint::AddHistory(char code)
if ( ! IsOrig() ) if ( ! IsOrig() )
code = tolower(code); code = tolower(code);
tcp_analyzer->Conn()->AddHistory(code); Conn()->AddHistory(code);
} }

View file

@ -174,7 +174,8 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
} }
if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 ) if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 )
// This should never happen. // This should never happen. (Reassembler::TrimToSeq has the only call
// to this method and only if this condition is not true).
reporter->InternalError("Calling Undelivered for data that has already been delivered (or has already been marked as undelivered"); reporter->InternalError("Calling Undelivered for data that has already been delivered (or has already been marked as undelivered");
if ( last_reassem_seq == 1 && if ( last_reassem_seq == 1 &&
@ -322,17 +323,36 @@ void TCP_Reassembler::RecordToSeq(int start_seq, int stop_seq, BroFile* f)
void TCP_Reassembler::RecordBlock(DataBlock* b, BroFile* f) void TCP_Reassembler::RecordBlock(DataBlock* b, BroFile* f)
{ {
unsigned int len = b->Size(); if ( f->Write((const char*) b->block, b->Size()) )
if ( ! f->Write((const char*) b->block, len) ) return;
// ### this should really generate an event
reporter->InternalError("contents write failed"); reporter->Error("TCP_Reassembler contents write failed");
if ( contents_file_write_failure )
{
val_list* vl = new val_list();
vl->append(Endpoint()->Conn()->BuildConnVal());
vl->append(new Val(IsOrig(), TYPE_BOOL));
vl->append(new StringVal("TCP reassembler content write failure"));
tcp_analyzer->ConnectionEvent(contents_file_write_failure, vl);
}
} }
void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f) void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f)
{ {
if ( ! f->Write(fmt("\n<<gap %d>>\n", seq_delta(upper_seq, start_seq))) ) if ( f->Write(fmt("\n<<gap %d>>\n", seq_delta(upper_seq, start_seq))) )
// ### this should really generate an event return;
reporter->InternalError("contents gap write failed");
reporter->Error("TCP_Reassembler contents gap write failed");
if ( contents_file_write_failure )
{
val_list* vl = new val_list();
vl->append(Endpoint()->Conn()->BuildConnVal());
vl->append(new Val(IsOrig(), TYPE_BOOL));
vl->append(new StringVal("TCP reassembler gap write failure"));
tcp_analyzer->ConnectionEvent(contents_file_write_failure, vl);
}
} }
void TCP_Reassembler::BlockInserted(DataBlock* start_block) void TCP_Reassembler::BlockInserted(DataBlock* start_block)

View file

@ -287,3 +287,13 @@ event tcp_contents%(c: connection, is_orig: bool, seq: count, contents: string%)
## TODO. ## TODO.
event tcp_rexmit%(c: connection, is_orig: bool, seq: count, len: count, data_in_flight: count, window: count%); event tcp_rexmit%(c: connection, is_orig: bool, seq: count, len: count, data_in_flight: count, window: count%);
## Generated when failing to write contents of a TCP stream to a file.
##
## c: The connection whose contents are being recorded.
##
## is_orig: Which side of the connection encountered a failure to write.
##
## msg: A reason or description for the failure.
##
## .. bro:see:: set_contents_file get_contents_file
event contents_file_write_failure%(c: connection, is_orig: bool, msg: string%);

View file

@ -114,7 +114,7 @@ function get_gap_summary%(%): gap_info
## missing data; this can happen, e.g., due to an ## missing data; this can happen, e.g., due to an
## :bro:id:`ack_above_hole` event. ## :bro:id:`ack_above_hole` event.
## ##
## .. bro:see:: get_contents_file set_record_packets ## .. bro:see:: get_contents_file set_record_packets contents_file_write_failure
function set_contents_file%(cid: conn_id, direction: count, f: file%): bool function set_contents_file%(cid: conn_id, direction: count, f: file%): bool
%{ %{
Connection* c = sessions->FindConnection(cid); Connection* c = sessions->FindConnection(cid);
@ -137,7 +137,7 @@ function set_contents_file%(cid: conn_id, direction: count, f: file%): bool
## but there is no contents file for *direction*, then the function ## but there is no contents file for *direction*, then the function
## generates an error and returns a file handle to ``stderr``. ## generates an error and returns a file handle to ``stderr``.
## ##
## .. bro:see:: set_contents_file set_record_packets ## .. bro:see:: set_contents_file set_record_packets contents_file_write_failure
function get_contents_file%(cid: conn_id, direction: count%): file function get_contents_file%(cid: conn_id, direction: count%): file
%{ %{
Connection* c = sessions->FindConnection(cid); Connection* c = sessions->FindConnection(cid);

View file

@ -362,12 +362,19 @@ Analyzer* Manager::InstantiateAnalyzer(Tag tag, RecordVal* args, File* f) const
Component* c = Lookup(tag); Component* c = Lookup(tag);
if ( ! c ) if ( ! c )
reporter->InternalError("cannot instantiate unknown file analyzer: %s", {
tag.AsString().c_str()); reporter->InternalWarning(
"unknown file analyzer instantiation request: %s",
tag.AsString().c_str());
return 0;
}
if ( ! c->Factory() ) if ( ! c->Factory() )
reporter->InternalError("file analyzer %s cannot be instantiated " {
reporter->InternalWarning("file analyzer %s cannot be instantiated "
"dynamically", c->CanonicalName()); "dynamically", c->CanonicalName());
return 0;
}
return c->Factory()(args, f); return c->Factory()(args, f);
} }

View file

@ -42,6 +42,13 @@ ReaderDefinition input_readers[] = {
{ BifEnum::Input::READER_DEFAULT, "None", 0, (ReaderBackend* (*)(ReaderFrontend* frontend))0 } { BifEnum::Input::READER_DEFAULT, "None", 0, (ReaderBackend* (*)(ReaderFrontend* frontend))0 }
}; };
static void delete_value_ptr_array(Value** vals, int num_fields)
{
for ( int i = 0; i < num_fields; ++i )
delete vals[i];
delete [] vals;
}
/** /**
* InputHashes are used as Dictionaries to store the value and index hashes * InputHashes are used as Dictionaries to store the value and index hashes
* for all lines currently stored in a table. Index hash is stored as * for all lines currently stored in a table. Index hash is stored as
@ -330,7 +337,9 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
break; break;
default: default:
reporter->InternalError("unknown reader mode"); reporter->InternalWarning("unknown input reader mode");
Unref(mode);
return false;
} }
Unref(mode); Unref(mode);
@ -1014,7 +1023,8 @@ void Manager::SendEntry(ReaderFrontend* reader, Value* *vals)
Stream *i = FindStream(reader); Stream *i = FindStream(reader);
if ( i == 0 ) if ( i == 0 )
{ {
reporter->InternalError("Unknown reader in SendEntry"); reporter->InternalWarning("Unknown reader %s in SendEntry",
reader->Name());
return; return;
} }
@ -1041,10 +1051,7 @@ void Manager::SendEntry(ReaderFrontend* reader, Value* *vals)
else else
assert(false); assert(false);
for ( int i = 0; i < readFields; i++ ) delete_value_ptr_array(vals, readFields);
delete vals[i];
delete [] vals;
} }
int Manager::SendEntryTable(Stream* i, const Value* const *vals) int Manager::SendEntryTable(Stream* i, const Value* const *vals)
@ -1242,7 +1249,8 @@ void Manager::EndCurrentSend(ReaderFrontend* reader)
if ( i == 0 ) if ( i == 0 )
{ {
reporter->InternalError("Unknown reader in EndCurrentSend"); reporter->InternalWarning("Unknown reader %s in EndCurrentSend",
reader->Name());
return; return;
} }
@ -1352,7 +1360,8 @@ void Manager::SendEndOfData(ReaderFrontend* reader)
if ( i == 0 ) if ( i == 0 )
{ {
reporter->InternalError("Unknown reader in SendEndOfData"); reporter->InternalWarning("Unknown reader %s in SendEndOfData",
reader->Name());
return; return;
} }
@ -1378,7 +1387,7 @@ void Manager::Put(ReaderFrontend* reader, Value* *vals)
Stream *i = FindStream(reader); Stream *i = FindStream(reader);
if ( i == 0 ) if ( i == 0 )
{ {
reporter->InternalError("Unknown reader in Put"); reporter->InternalWarning("Unknown reader %s in Put", reader->Name());
return; return;
} }
@ -1410,10 +1419,7 @@ void Manager::Put(ReaderFrontend* reader, Value* *vals)
else else
assert(false); assert(false);
for ( int i = 0; i < readFields; i++ ) delete_value_ptr_array(vals, readFields);
delete vals[i];
delete [] vals;
} }
int Manager::SendEventStreamEvent(Stream* i, EnumVal* type, const Value* const *vals) int Manager::SendEventStreamEvent(Stream* i, EnumVal* type, const Value* const *vals)
@ -1585,7 +1591,8 @@ void Manager::Clear(ReaderFrontend* reader)
Stream *i = FindStream(reader); Stream *i = FindStream(reader);
if ( i == 0 ) if ( i == 0 )
{ {
reporter->InternalError("Unknown reader in Clear"); reporter->InternalWarning("Unknown reader %s in Clear",
reader->Name());
return; return;
} }
@ -1606,7 +1613,7 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
Stream *i = FindStream(reader); Stream *i = FindStream(reader);
if ( i == 0 ) if ( i == 0 )
{ {
reporter->InternalError("Unknown reader in Delete"); reporter->InternalWarning("Unknown reader %s in Delete", reader->Name());
return false; return false;
} }
@ -1686,11 +1693,7 @@ bool Manager::Delete(ReaderFrontend* reader, Value* *vals)
return false; return false;
} }
for ( int i = 0; i < readVals; i++ ) delete_value_ptr_array(vals, readVals);
delete vals[i];
delete [] vals;
return success; return success;
} }
@ -1722,6 +1725,7 @@ bool Manager::SendEvent(const string& name, const int num_vals, Value* *vals)
if ( handler == 0 ) if ( handler == 0 )
{ {
reporter->Error("Event %s not found", name.c_str()); reporter->Error("Event %s not found", name.c_str());
delete_value_ptr_array(vals, num_vals);
return false; return false;
} }
@ -1735,6 +1739,7 @@ bool Manager::SendEvent(const string& name, const int num_vals, Value* *vals)
if ( num_vals != num_event_vals ) if ( num_vals != num_event_vals )
{ {
reporter->Error("Wrong number of values for event %s", name.c_str()); reporter->Error("Wrong number of values for event %s", name.c_str());
delete_value_ptr_array(vals, num_vals);
return false; return false;
} }
@ -1744,11 +1749,7 @@ bool Manager::SendEvent(const string& name, const int num_vals, Value* *vals)
mgr.QueueEvent(handler, vl, SOURCE_LOCAL); mgr.QueueEvent(handler, vl, SOURCE_LOCAL);
for ( int i = 0; i < num_vals; i++ ) delete_value_ptr_array(vals, num_vals);
delete vals[i];
delete [] vals;
return true; return true;
} }
@ -1794,12 +1795,6 @@ RecordVal* Manager::ListValToRecordVal(ListVal* list, RecordType *request_type,
{ {
assert(position != 0 ); // we need the pointer to point to data; assert(position != 0 ); // we need the pointer to point to data;
if ( request_type->Tag() != TYPE_RECORD )
{
reporter->InternalError("ListValToRecordVal called on non-record-value.");
return 0;
}
RecordVal* rec = new RecordVal(request_type->AsRecordType()); RecordVal* rec = new RecordVal(request_type->AsRecordType());
assert(list != 0); assert(list != 0);
@ -1830,12 +1825,6 @@ RecordVal* Manager::ValueToRecordVal(const Value* const *vals,
{ {
assert(position != 0); // we need the pointer to point to data. assert(position != 0); // we need the pointer to point to data.
if ( request_type->Tag() != TYPE_RECORD )
{
reporter->InternalError("ValueToRecordVal called on non-record-value.");
return 0;
}
RecordVal* rec = new RecordVal(request_type->AsRecordType()); RecordVal* rec = new RecordVal(request_type->AsRecordType());
for ( int i = 0; i < request_type->NumFields(); i++ ) for ( int i = 0; i < request_type->NumFields(); i++ )
{ {

View file

@ -53,8 +53,8 @@ bool Binary::CloseInput()
{ {
if ( ! in || ! in->is_open() ) if ( ! in || ! in->is_open() )
{ {
InternalError(Fmt("Trying to close closed file for stream %s", InternalWarning(Fmt("Trying to close closed file for stream %s",
fname.c_str())); fname.c_str()));
return false; return false;
} }

View file

@ -299,7 +299,8 @@ bool Raw::CloseInput()
{ {
if ( file == 0 ) if ( file == 0 )
{ {
InternalError(Fmt("Trying to close closed file for stream %s", fname.c_str())); InternalWarning(Fmt("Trying to close closed file for stream %s",
fname.c_str()));
return false; return false;
} }
#ifdef DEBUG #ifdef DEBUG
@ -492,9 +493,6 @@ int64_t Raw::GetLine(FILE* arg_file)
Error(Fmt("Reader encountered unexpected error code %d", errno)); Error(Fmt("Reader encountered unexpected error code %d", errno));
return -3; return -3;
} }
InternalError("Internal control flow execution error in raw reader");
assert(false);
} }
// write to the stdin of the child process // write to the stdin of the child process

View file

@ -44,7 +44,9 @@ void Component::Describe(ODesc* d) const
break; break;
default: default:
reporter->InternalError("unknown component type in plugin::Component::Describe"); reporter->InternalWarning("unknown component type in plugin::Component::Describe");
d->Add("<unknown component type>");
break;
} }
d->Add("]"); d->Add("]");

View file

@ -169,11 +169,12 @@ const char* ComponentManager<T, C>::GetComponentName(T tag) const
C* c = Lookup(tag); C* c = Lookup(tag);
if ( ! c ) if ( c )
reporter->InternalError("request for name of unknown component tag %s", return c->CanonicalName();
tag.AsString().c_str());
return c->CanonicalName(); reporter->InternalWarning("requested name of unknown component tag %s",
tag.AsString().c_str());
return error;
} }
template <class T, class C> template <class T, class C>

View file

@ -294,7 +294,9 @@ bool Value::Read(SerializationFormat* fmt)
} }
default: default:
reporter->InternalError("unsupported type %s in Value::Write", type_name(type)); reporter->InternalError("unsupported type %s in Value::Read",
type_name(type));
return false;
} }
return false; return false;
@ -398,7 +400,9 @@ bool Value::Write(SerializationFormat* fmt) const
} }
default: default:
reporter->InternalError("unsupported type %s in Value::REad", type_name(type)); reporter->InternalError("unsupported type %s in Value::Write",
type_name(type));
return false;
} }
return false; return false;

View file

@ -345,9 +345,9 @@ unsigned char encode_hex(int h)
'9', 'A', 'B', 'C', 'D', 'E', 'F' '9', 'A', 'B', 'C', 'D', 'E', 'F'
}; };
if ( h < 0 || h >= 16 ) if ( h < 0 || h > 15 )
{ {
reporter->InternalError("illegal value for encode_hex: %d", h); reporter->InternalWarning("illegal value for encode_hex: %d", h);
return 'X'; return 'X';
} }