add color to error printing + reorganise options

This commit is contained in:
zawz 2021-05-25 16:12:02 +02:00
parent 9ddf23dd4b
commit 05723fe994
7 changed files with 74 additions and 95 deletions

View file

@ -16,12 +16,22 @@ CC=g++
# compiler flags # compiler flags
CXXFLAGS= -I$(IDIR) -Wall -pedantic -std=c++20 CXXFLAGS= -I$(IDIR) -Wall -pedantic -std=c++20
ifeq ($(DEBUG),true) ifeq ($(DEBUG),true)
# debugging flags # debugging flags
CXXFLAGS += -g CXXFLAGS += -g
RODIR = $(ODIR)/debug
else else
# release flags # release flags
CXXFLAGS += -Ofast CXXFLAGS += -Ofast
RODIR = $(ODIR)/release
endif endif
ifeq ($(STATIC),true)
# static links
LDFLAGS += -l:libztd.a
else
# dynamic links
LDFLAGS += -lztd
endif
ifeq ($(PROFILE),true) ifeq ($(PROFILE),true)
CXXFLAGS += -pg CXXFLAGS += -pg
@ -31,51 +41,49 @@ ifneq ($(RELEASE), true)
VSUFFIX=-dev-$(SHA_SHORT) VSUFFIX=-dev-$(SHA_SHORT)
endif endif
ifeq ($(STATIC),true)
# static links
LDFLAGS += -l:libztd.a
else
# dynamic links
LDFLAGS += -lztd
endif
## END CONFIG ## ## END CONFIG ##
$(shell ./generate_version.sh) $(shell ./generate_version.sh)
$(shell ./generate_shellcode.sh) $(shell ./generate_shellcode.sh)
$(shell mkdir -p $(ODIR))
$(shell mkdir -p $(RODIR))
$(shell mkdir -p $(BINDIR)) $(shell mkdir -p $(BINDIR))
# automatically find .h and .hpp # automatically find .h and .hpp
DEPS = $(shell find $(IDIR) -type f -regex '.*\.hp?p?' ! -name 'g_version.h' ! -name 'g_shellcode.h') DEPS = $(shell find $(IDIR) -type f -regex '.*\.hp?p?')
# automatically find .c and .cpp and make the corresponding .o rule # automatically find .c and .cpp and make the corresponding .o rule
OBJ = $(shell find $(SRCDIR) -type f -regex '.*\.cp?p?' | sed 's|\.cpp|.o|g;s|\.c|.o|g;s|^$(SRCDIR)/|$(ODIR)/|g') OBJ = $(shell find $(SRCDIR) -type f -regex '.*\.cp?p?' | sed 's|\.cpp|.o|g;s|\.c|.o|g;s|^$(SRCDIR)/|$(RODIR)/|g')
build: lxsh $(OBJ) $(DEPS) build: $(BINDIR)/$(NAME)
$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS) # specific files for autogenerated headers
$(OBJDIR)/options.o: $(SRCDIR)/options.cpp $(DEPS) $(IDIR)/g_version.h
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS) $(OBJDIR)/shellcode.o: $(SRCDIR)/shellcode.cpp $(DEPS) $(IDIR)/g_shellcode.h
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/options.o: $(SRCDIR)/options.cpp $(DEPS) $(IDIR)/g_version.h $(OBJDIR)/debashify.o: $(SRCDIR)/debashify.cpp $(DEPS) $(IDIR)/g_shellcode.h
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/shellcode.o: $(SRCDIR)/shellcode.cpp $(DEPS) $(IDIR)/g_shellcode.h # generic files
$(RODIR)/%.o: $(SRCDIR)/%.c $(DEPS)
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/debashify.o: $(SRCDIR)/debashify.cpp $(DEPS) $(IDIR)/g_shellcode.h $(RODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
$(CC) $(CXXFLAGS) -c -o $@ $< $(CC) $(CXXFLAGS) -c -o $@ $<
lxsh: $(OBJ)
$(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) $(BINDIR)/$(NAME): $(OBJ)
$(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $^
test: $(BINDIR)/$(NAME) test: $(BINDIR)/$(NAME)
$(BINDIR)/$(NAME) $(BINDIR)/$(NAME)
clean: clean:
rm $(ODIR)/*.o gmon.out rm $(ODIR)/*/*.o
clear: clear:
rm $(BINDIR)/$(NAME) rm $(BINDIR)/$(NAME)

View file

@ -102,14 +102,16 @@ class format_error : public std::exception
{ {
public: public:
//! @brief Conctructor //! @brief Conctructor
inline format_error(const std::string& what, const std::string& origin, const std::string& data, int where) { desc=what; index=where; filename=origin; sdat=data; } inline format_error(const std::string& what, const std::string& origin, const std::string& data, int where, std::string level="error") { desc=what; index=where; filename=origin; sdat=data; severity=level; }
inline format_error(const std::string& what, parse_context const& ctx) { desc=what; index=ctx.i; filename=ctx.filename; sdat=ctx.data; } inline format_error(const std::string& what, parse_context const& ctx, std::string level="error") { desc=what; index=ctx.i; filename=ctx.filename; sdat=ctx.data; severity=level; }
//! @brief Error message //! @brief Error message
inline const char * what () const throw () {return desc.c_str();} inline const char * what () const throw () {return desc.c_str();}
//! @brief Origin of the data, name of imported file, otherwise empty if generated //! @brief Origin of the data, name of imported file, otherwise empty if generated
inline const char * origin() const throw () {return filename.c_str();} inline const char * origin() const throw () {return filename.c_str();}
//! @brief Data causing the exception //! @brief Data causing the exception
inline const char * data() const throw () {return sdat.c_str();} inline const char * data() const throw () {return sdat.c_str();}
//! @brief Severity of the exception
inline const std::string level() const throw () {return severity.c_str();}
//! @brief Where the error is located in the data //! @brief Where the error is located in the data
inline const int where () const throw () {return index;} inline const int where () const throw () {return index;}
private: private:
@ -117,6 +119,7 @@ private:
int index; int index;
std::string filename; std::string filename;
std::string sdat; std::string sdat;
std::string severity;
}; };
// objects // objects

View file

@ -148,8 +148,5 @@ int _exec(std::string const& bin, std::vector<std::string> const& args);
std::string stringReplace(std::string subject, const std::string& search, const std::string& replace); std::string stringReplace(std::string subject, const std::string& search, const std::string& replace);
void printFormatError(format_error const& e, bool print_line=true); void printFormatError(format_error const& e, bool print_line=true);
void printErrorIndex(const char* in, const int index, const std::string& message, const std::string& origin, bool print_line=true);
int execute(shmain* sh, std::vector<std::string>& args);
#endif //UTIL_HPP #endif //UTIL_HPP

View file

@ -30,19 +30,20 @@ ztd::option_set options( {
ztd::option('R', "no-resolve", false, "Don't resolve %resolve commands"), ztd::option('R', "no-resolve", false, "Don't resolve %resolve commands"),
ztd::option("no-extend", false, "Don't add lxsh extension functions"), ztd::option("no-extend", false, "Don't add lxsh extension functions"),
ztd::option("debashify", false, "Attempt to turn a bash-specific script into a POSIX shell script"), ztd::option("debashify", false, "Attempt to turn a bash-specific script into a POSIX shell script"),
ztd::option("\r [var/fct processing]"), ztd::option("remove-unused", false, "Remove unused functions and variables"),
ztd::option("minify-var", false, "Minify variable names"), ztd::option("list-cmd", false, "List all commands invoked in the script"),
ztd::option("minify-fct", false, "Minify function names"), ztd::option("\r [Variable processing]"),
ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing", "list"), ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing", "list"),
ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing", "list"),
ztd::option("no-exclude-reserved",false, "Don't exclude reserved variables"), ztd::option("no-exclude-reserved",false, "Don't exclude reserved variables"),
ztd::option("minify-var", false, "Minify variable names"),
ztd::option("list-var", false, "List all variables set and invoked in the script"), ztd::option("list-var", false, "List all variables set and invoked in the script"),
ztd::option("list-var-def", false, "List all variables set in the script"), ztd::option("list-var-def", false, "List all variables set in the script"),
ztd::option("list-var-call", false, "List all variables invoked in the script"), ztd::option("list-var-call", false, "List all variables invoked in the script"),
ztd::option("list-fct", false, "List all functions defined in the script"), ztd::option("unset-var", false, "Add 'unset' to all variables at the start of the script to avoid environment interference"),
ztd::option("list-cmd", false, "List all commands invoked in the script"), ztd::option("\r [Function processing]"),
ztd::option("remove-unused", false, "Remove unused functions and variables"), ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing", "list"),
ztd::option("unset-var", false, "Add 'unset' to all vars at the start of the script to avoid environment interference") ztd::option("minify-fct", false, "Minify function names"),
ztd::option("list-fct", false, "List all functions defined in the script")
} ); } );
bool g_cd=false; bool g_cd=false;
@ -96,9 +97,8 @@ ztd::option_set create_resolve_opts()
void print_help(const char* arg0) void print_help(const char* arg0)
{ {
printf("%s [options] <file> [arg...]\n", arg0); printf("%s [options] <file> [arg...]\n", arg0);
printf("Link extended shell\n"); printf("Extended shell linker\n");
printf("Include files and resolve commands on build time\n"); printf("Include files, resolve commands on build time, process and minify shell code\n");
printf("See --help-commands for help on linker commands\n");
printf("\n"); printf("\n");
printf("Options:\n"); printf("Options:\n");
options.print_help(4,25); options.print_help(4,25);

View file

@ -41,13 +41,15 @@ std::string unexpected_token(std::string const& s)
void parse_error(std::string const& message, parse_context& ctx) void parse_error(std::string const& message, parse_context& ctx)
{ {
printFormatError(format_error(message, ctx.filename, ctx.data, ctx.i)); printFormatError(format_error(message, ctx));
ctx.has_errored=true; ctx.has_errored=true;
} }
void parse_error(std::string const& message, parse_context& ctx, uint64_t i) void parse_error(std::string const& message, parse_context& ctx, uint64_t i)
{ {
printFormatError(format_error(message, ctx.filename, ctx.data, i)); parse_context newctx = ctx;
newctx.i = i;
printFormatError(format_error(message, newctx));
ctx.has_errored=true; ctx.has_errored=true;
} }

View file

@ -5,7 +5,7 @@
#include "struc_helper.hpp" #include "struc_helper.hpp"
const std::map<const std::string, const lxsh_fct> lxsh_extend_fcts = { const std::map<const std::string, const lxsh_fct> lxsh_extend_fcts = {
{ "_lxsh_random", { "[K]", "Generate a random number between 0 and 2^(k*8). Default 2", RANDOM_SH} }, { "_lxsh_random", { "[K]", "Generate a random number between 0 and 2^(K*8). Default 2", RANDOM_SH} },
{ "_lxsh_random_string", { "[N]", "Generate a random alphanumeric string of length N. Default 20", RANDOM_STRING_SH} }, { "_lxsh_random_string", { "[N]", "Generate a random alphanumeric string of length N. Default 20", RANDOM_STRING_SH} },
{ "_lxsh_random_tmpfile", { "[N]", "Get a random TMP filepath, with N random chars. Default 20", RANDOM_TMPFILE_SH, {"_lxsh_random_string"} } } { "_lxsh_random_tmpfile", { "[N]", "Get a random TMP filepath, with N random chars. Default 20", RANDOM_TMPFILE_SH, {"_lxsh_random_string"} } }
}; };

View file

@ -10,6 +10,7 @@
#include <fstream> #include <fstream>
#include <ztd/shell.hpp> #include <ztd/shell.hpp>
#include <ztd/color.hpp>
std::string indenting_string="\t"; std::string indenting_string="\t";
@ -213,14 +214,13 @@ std::string repeatString(std::string const& str, uint32_t n)
void printFormatError(format_error const& e, bool print_line) void printFormatError(format_error const& e, bool print_line)
{ {
printErrorIndex(e.data(), e.where(), e.what(), e.origin(), print_line); const char* in = e.data();
}
void printErrorIndex(const char* in, const int index, const std::string& message, const std::string& origin, bool print_line) uint64_t index = e.where();
{
int i=0, j=0; // j: last newline uint64_t i=0, j=0; // j: last newline
int line=1; //n: line # uint64_t line=1; //n: line #
int in_size=strlen(in); uint64_t in_size=strlen(in);
if(index >= 0) if(index >= 0)
{ {
while(i < in_size && i < index) while(i < in_size && i < index)
@ -233,56 +233,25 @@ void printErrorIndex(const char* in, const int index, const std::string& message
i++; i++;
} }
while(i < in_size && in[i]!='\n') while(i < in_size && in[i]!='\n')
{
i++; i++;
}
} }
fprintf(stderr, "%s:%u:%u: %s\n", origin.c_str(), line, index-j+1, message.c_str()); std::cerr << ztd::color::b_white;
fprintf(stderr, "%s:%lu:%lu: ", e.origin(), line, index-j+1);
ztd::color level_color;
const std::string& level = e.level();
if(level == "error")
level_color = ztd::color::b_red;
else if(level == "warning")
level_color = ztd::color::b_magenta;
else if(level == "info")
level_color = ztd::color::b_cyan;
std::cerr << level_color << e.level() << ztd::color::none;
fprintf(stderr, ": %s\n", e.what());
if(print_line) if(print_line)
{ {
std::cerr << std::string(in+j, i-j) << std::endl; std::cerr << std::string(in+j, i-j) << std::endl;
std::cerr << repeatString(" ", index-j) << '^' << std::endl; std::cerr << repeatString(" ", index-j) << '^' << std::endl;
} }
} }
int execute(shmain* sh, std::vector<std::string>& args)
{
std::string data=sh->generate();
std::string filename = basename(args[0]);
// generate path
std::string tmpdir = (getenv("TMPDIR") != NULL) ? getenv("TMPDIR") : "/tmp" ;
std::string dirpath = tmpdir + "/lxsh_" + ztd::sh("tr -dc '[:alnum:]' < /dev/urandom | head -c10");
std::string filepath = dirpath+'/'+filename;
// create dir
if(ztd::exec("mkdir", "-p", dirpath).second)
{
throw std::runtime_error("Failed to create directory '"+dirpath+'\'');
}
// create stream
std::ofstream stream(filepath);
if(!stream)
{
ztd::exec("rm", "-rf", dirpath);
throw std::runtime_error("Failed to write to '"+filepath+'\'');
}
// output
stream << data;
stream.close();
if(ztd::exec("chmod", "+x", filepath).second != 0)
{
ztd::exec("rm", "-rf", dirpath);
throw std::runtime_error("Failed to make '"+filepath+"' executable");
}
// exec
int retval=_exec(filepath, args);
ztd::exec("rm", "-rf", dirpath);
return retval;
}