Replace safe_basename/safe_dirname w/ SafeBasename/SafeDirname.

So errors can be better handled.
This commit is contained in:
Jon Siwek 2013-11-04 11:42:39 -06:00
parent 96ed7aed1a
commit 3046013d69
5 changed files with 65 additions and 41 deletions

View file

@ -104,7 +104,7 @@ string IdentifierDocument::GetFieldComments(const string& field) const
ScriptDocument::ScriptDocument(const string& arg_name) ScriptDocument::ScriptDocument(const string& arg_name)
: Document(), : Document(),
name(arg_name), name(arg_name),
is_pkg_loader(safe_basename(name) == PACKAGE_LOADER), is_pkg_loader(SafeBasename(name).result == PACKAGE_LOADER),
dependencies(), module_usages(), comments(), identifier_docs(), redefs() dependencies(), module_usages(), comments(), identifier_docs(), redefs()
{ {
} }

View file

@ -142,7 +142,7 @@ void Manager::File(const string& path)
if ( ! doc->IsPkgLoader() ) if ( ! doc->IsPkgLoader() )
return; return;
name = safe_dirname(name); name = SafeDirname(name).result;
if ( packages.GetDocument(name) ) if ( packages.GetDocument(name) )
{ {

View file

@ -59,7 +59,7 @@ static string find_relative_file(const string& filename, const string& ext)
return string(); return string();
if ( filename[0] == '.' ) if ( filename[0] == '.' )
return find_file(filename, safe_dirname(::filename), ext); return find_file(filename, SafeDirname(::filename).result, ext);
else else
return find_file(filename, bro_path(), ext); return find_file(filename, bro_path(), ext);
} }
@ -275,7 +275,7 @@ when return TOK_WHEN;
@DEBUG return TOK_DEBUG; // marks input for debugger @DEBUG return TOK_DEBUG; // marks input for debugger
@DIR { @DIR {
string rval = safe_dirname(::filename); string rval = SafeDirname(::filename).result;
if ( ! rval.empty() && rval[0] == '.' ) if ( ! rval.empty() && rval[0] == '.' )
{ {
@ -291,15 +291,7 @@ when return TOK_WHEN;
} }
@FILENAME { @FILENAME {
char* filename_copy = copy_string(::filename); RET_CONST(new StringVal(SafeBasename(::filename).result));
const char* bname = basename(filename_copy);
if ( ! bname )
reporter->InternalError("basename failed: %s", strerror(errno));
StringVal* rval = new StringVal(bname);
delete [] filename_copy;
RET_CONST(rval);
} }
@load{WS}{FILE} { @load{WS}{FILE} {

View file

@ -944,34 +944,36 @@ FILE* open_package(string& path, const string& mode)
return 0; return 0;
} }
string safe_dirname(const char* path) SafePathOp::SafePathOp(PathOpFn fn, const char* path, bool error_aborts)
{ {
if ( ! path ) DoFunc(fn, path ? path : "", error_aborts);
return ".";
return safe_dirname(string(path));
} }
string safe_dirname(const string& path) SafePathOp::SafePathOp(PathOpFn fn, const string& path, bool error_aborts)
{
DoFunc(fn, path, error_aborts);
}
void SafePathOp::DoFunc(PathOpFn fn, const string& path, bool error_aborts)
{ {
char* tmp = copy_string(path.c_str()); char* tmp = copy_string(path.c_str());
string rval = dirname(tmp); char* rval = fn(tmp);
delete [] tmp;
return rval;
}
string safe_basename(const char* path) if ( rval )
{ {
if ( ! path ) result = rval;
return "."; error = false;
return safe_basename(string(path)); }
} else
{
if ( error_aborts )
reporter->InternalError("Path operation failed on %s: %s",
tmp ? tmp : "<null>", strerror(errno));
else
error = true;
}
string safe_basename(const string& path)
{
char* tmp = copy_string(path.c_str());
string rval = basename(tmp);
delete [] tmp; delete [] tmp;
return rval;
} }
string flatten_script_name(const string& name, const string& prefix) string flatten_script_name(const string& name, const string& prefix)
@ -981,8 +983,8 @@ string flatten_script_name(const string& name, const string& prefix)
if ( ! rval.empty() ) if ( ! rval.empty() )
rval.append("."); rval.append(".");
if ( safe_basename(name) == PACKAGE_LOADER ) if ( SafeBasename(name).result == PACKAGE_LOADER )
rval.append(safe_dirname(name)); rval.append(SafeDirname(name).result);
else else
rval.append(name); rval.append(name);

View file

@ -22,6 +22,7 @@
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <magic.h> #include <magic.h>
#include <libgen.h>
#include "config.h" #include "config.h"
#if __STDC__ #if __STDC__
@ -208,13 +209,42 @@ extern const char* bro_path();
extern const char* bro_magic_path(); extern const char* bro_magic_path();
extern std::string bro_prefixes(); extern std::string bro_prefixes();
// Wrappers for dirname(3) that won't modify argument. /**
std::string safe_dirname(const char* path); * Wrapper class for functions like dirname(3) or basename(3) that won't
std::string safe_dirname(const std::string& path); * modify the path argument and may optionally abort execution on error.
*/
class SafePathOp {
public:
// Wrappers for basename(3) that won't modify argument. typedef char*(*PathOpFn)(char*);
std::string safe_basename(const char* path);
std::string safe_basename(const std::string& path); SafePathOp(PathOpFn fn, const char* path, bool error_aborts = true);
SafePathOp(PathOpFn fn, const std::string& path, bool error_aborts = true);
std::string result;
bool error;
private:
void DoFunc(PathOpFn fn, const std::string& path, bool error_aborts = true);
};
class SafeDirname : public SafePathOp {
public:
SafeDirname(const char* path, bool error_aborts = true)
: SafePathOp(&dirname, path, error_aborts) { }
SafeDirname(const std::string& path, bool error_aborts = true)
: SafePathOp(&dirname, path, error_aborts) { }
};
class SafeBasename : public SafePathOp {
public:
SafeBasename(const char* path, bool error_aborts = true)
: SafePathOp(&basename, path, error_aborts) { }
SafeBasename(const std::string& path, bool error_aborts = true)
: SafePathOp(&basename, path, error_aborts) { }
};
/** /**
* Flatten a script name by replacing '/' path separators with '.'. * Flatten a script name by replacing '/' path separators with '.'.