From f93447e7dccc6c1427c92250682b469f6a01d4b2 Mon Sep 17 00:00:00 2001 From: zawz Date: Fri, 8 Apr 2022 15:38:11 +0200 Subject: [PATCH] fix(parse): fix parse of sequential braces --- include/parse.hpp | 2 +- include/struc.hpp | 2 ++ src/exec.cpp | 15 ++++++++------- src/parse.cpp | 14 ++++++++------ src/struc_helper.cpp | 9 ++++++++- test/brace.sh | 2 ++ test/debashify.bash | 2 +- test/err/brace.sh | 1 + 8 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 test/err/brace.sh diff --git a/include/parse.hpp b/include/parse.hpp index e0ec072..23a944b 100644 --- a/include/parse.hpp +++ b/include/parse.hpp @@ -109,7 +109,7 @@ std::pair parse_arg(parse_context ct, const char* end=ARG // redirect parser std::pair parse_redirect(parse_context ct); // arglist parser -std::pair parse_arglist(parse_context ct, bool hard_error=false, std::vector* redirs=nullptr); +std::pair parse_arglist(parse_context ct, bool hard_error=false, std::vector* redirs=nullptr, bool stop_on_brace=false); // block parsers std::pair parse_block(parse_context ct); std::pair parse_cmd(parse_context ct); diff --git a/include/struc.hpp b/include/struc.hpp index f0e195a..d415514 100644 --- a/include/struc.hpp +++ b/include/struc.hpp @@ -233,6 +233,8 @@ public: std::vector strargs(uint32_t start); + // get first argument as string + std::string first_arg_string(); // potentially expands into more arguments than its size bool can_expand(); diff --git a/src/exec.cpp b/src/exec.cpp index ff3f20d..e69c141 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -236,17 +236,18 @@ int exec_process(std::string const& runtime, std::vector const& arg if(mkfifo(fifopath.c_str(), 0700)<0) throw std::runtime_error("Cannot create fifo "+fifopath); - for(uint32_t i=0; i parse_redirect(parse_context ctx) // must start at a read char // first char has to be read // ends at either &|;\n#() -std::pair parse_arglist(parse_context ctx, bool hard_error, std::vector* redirs) +std::pair parse_arglist(parse_context ctx, bool hard_error, std::vector* redirs, bool stop_on_brace) { arglist_t* ret = nullptr; @@ -895,10 +895,12 @@ std::pair parse_arglist(parse_context ctx, bool hard_ } else { - argparse: + argparse: ; + auto pp=parse_arg(ctx); + if(stop_on_brace && pp.first!=nullptr && pp.first->string() == "}") + return std::make_pair(ret, ctx); if(ret == nullptr) ret = new arglist_t; - auto pp=parse_arg(ctx); ret->add(pp.first); ctx = pp.second; } @@ -941,7 +943,7 @@ std::pair parse_pipeline(parse_context ctx) ret->add(pp.first); ctx = pp.second; ctx.i = skip_chars(ctx, SPACES); - if( ctx.i>=ctx.size || is_in(ctx[ctx.i], PIPELINE_END) || word_eq("||", ctx) ) + if( ctx.i>=ctx.size || is_in(ctx[ctx.i], PIPELINE_END) || word_eq("||", ctx) || ctx[ctx.i] == '}' ) return std::make_pair(ret, ctx); else if( ctx[ctx.i] != '|' ) { @@ -976,7 +978,7 @@ std::pair parse_condlist(parse_context ctx) auto pp=parse_pipeline(ctx); ret->add(pp.first, optype); ctx = pp.second; - if(ctx.i>=ctx.size || is_in(ctx[ctx.i], CONTROL_END) || is_in(ctx[ctx.i], COMMAND_SEPARATOR)) // end here exactly: used for control later + if(ctx.i>=ctx.size || is_in(ctx[ctx.i], CONTROL_END) || is_in(ctx[ctx.i], COMMAND_SEPARATOR) || ctx[ctx.i] == '}') // end here exactly: used for control later { return std::make_pair(ret, ctx); } @@ -1738,7 +1740,7 @@ std::pair parse_block(parse_context ctx) { uint32_t j=skip_chars(ctx, SPACES); ctx.i=j; - auto pp=parse_arglist(ctx, false, &ret->redirs); // in case of redirects + auto pp=parse_arglist(ctx, false, &ret->redirs, true); // in case of redirects if(pp.first != nullptr) { delete pp.first; diff --git a/src/struc_helper.cpp b/src/struc_helper.cpp index b47a5c9..8197542 100644 --- a/src/struc_helper.cpp +++ b/src/struc_helper.cpp @@ -227,10 +227,17 @@ std::string arg_t::string() std::string arg_t::first_sa_string() { if(sa.size() <=0 || sa[0]->type != _obj::subarg_string) - return ""; + return ""; return dynamic_cast(sa[0])->val; } +std::string arglist_t::first_arg_string() +{ + if(args.size()<=0 || args[0] == nullptr) + return ""; + return args[0]->string(); +} + bool arg_t::can_expand() { for(auto it: sa) diff --git a/test/brace.sh b/test/brace.sh index 11e3f57..16d8fe4 100644 --- a/test/brace.sh +++ b/test/brace.sh @@ -3,3 +3,5 @@ { echo tata ; echo a; } | sed 's|a|toto|g' echo a | { grep a && echo b; } + +{ { echo tata ; } } diff --git a/test/debashify.bash b/test/debashify.bash index 06d5e09..21260f0 100644 --- a/test/debashify.bash +++ b/test/debashify.bash @@ -47,4 +47,4 @@ echo ${!TATA} for I in A B C ; do echo "$I" -done > >(grep A) +done 2>&1 > >(grep A) diff --git a/test/err/brace.sh b/test/err/brace.sh new file mode 100644 index 0000000..a14153e --- /dev/null +++ b/test/err/brace.sh @@ -0,0 +1 @@ +{ ; }