@@ -4373,6 +4373,29 @@ static char *find_last_unescaped_operator(char *cmd, char operator, const char *
43734373 return last ;
43744374}
43754375
4376+ static char * find_unescaped_double_operator (char * cmd , char operator , const char * quotes ) {
4377+ const char * p = cmd ;
4378+ while ((p = r_str_firstbut_escape (p , operator , quotes ))) {
4379+ if (p [1 ] == operator ) {
4380+ return (char * )p ;
4381+ }
4382+ p ++ ;
4383+ }
4384+ return NULL ;
4385+ }
4386+
4387+ static char * find_unescaped_conditional (char * cmd , const char * quotes ) {
4388+ if (r_str_startswith (cmd , "&&" )) {
4389+ cmd += 2 ;
4390+ }
4391+ char * and = find_unescaped_double_operator (cmd , '&' , quotes );
4392+ char * pipe = (char * )r_str_firstbut_escape (cmd , '|' , quotes );
4393+ if (!pipe || (and && and < pipe )) {
4394+ return and ;
4395+ }
4396+ return pipe [1 ] == '|' ? pipe : NULL ;
4397+ }
4398+
43764399static char * getarg (char * ptr ) {
43774400 if (* ptr == '{' ) {
43784401 char * mander = strdup (ptr + 1 );
@@ -4472,7 +4495,7 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd, char *colon, bool *tmpseek
44724495 RIODesc * tmpdesc = NULL ;
44734496 bool old_iova = r_config_get_b (core -> config , "io.va" );
44744497 bool pamode = (core -> io ? !core -> io -> va : false);
4475- int i , ret = 0 , pipefd ;
4498+ int i , ret = 0 , pipefd , rc = 0 ;
44764499 bool usemyblock = false;
44774500 int scr_html = -1 ;
44784501 int scr_color = -1 ;
@@ -4714,10 +4737,36 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd, char *colon, bool *tmpseek
47144737 if (backtick ) {
47154738 goto escape_redir ;
47164739 }
4740+ ptr = find_unescaped_conditional (cmd , quotestr );
4741+ if (ptr ) {
4742+ bool run = true;
4743+ for (;;) {
4744+ const char condition = * ptr ;
4745+ * ptr = 0 ;
4746+ if (run ) {
4747+ ret = r_core_cmd_subst (core , cmd );
4748+ if (ret < 0 ) {
4749+ r_list_free (tmpenvs );
4750+ return ret ;
4751+ }
4752+ }
4753+ run = condition == '&' ? ret == 0 : ret != 0 ;
4754+ cmd = (char * )r_str_trim_head_ro (ptr + 2 );
4755+ ptr = find_unescaped_conditional (cmd , quotestr );
4756+ if (!ptr ) {
4757+ break ;
4758+ }
4759+ }
4760+ if (run ) {
4761+ ret = r_core_cmd_subst (core , cmd );
4762+ }
4763+ r_list_free (tmpenvs );
4764+ return ret ;
4765+ }
47174766
47184767 /* pipe console to shell process */
47194768 char * raw_operator = (char * )r_str_lastbut (cmd , '|' , quotestr );
4720- ptr = find_last_unescaped_operator (cmd , '|' , quotestr );
4769+ ptr = ( char * ) r_str_firstbut_escape (cmd , '|' , quotestr );
47214770 if (!ptr && raw_operator && is_escaped_operator (cmd , raw_operator )) {
47224771 memmove (raw_operator - 1 , raw_operator , strlen (raw_operator ) + 1 );
47234772 goto escape_pipe ;
@@ -4794,31 +4843,6 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd, char *colon, bool *tmpseek
47944843 }
47954844 }
47964845escape_pipe :
4797-
4798- // TODO must honor " and `
4799- /* bool conditions */
4800- ptr = (char * )r_str_lastbut (cmd , '&' , quotestr );
4801- //ptr = strchr (cmd, '&');
4802- while (ptr && * ptr && ptr [1 ] == '&' ) {
4803- * ptr = '\0' ;
4804- ret = r_cmd_call (core -> rcmd , cmd );
4805- if (ret == -1 ) {
4806- R_LOG_ERROR ("command error(%s)" , cmd );
4807- if (scr_html != -1 ) {
4808- r_config_set_b (core -> config , "scr.html" , scr_html );
4809- }
4810- if (scr_color != -1 ) {
4811- r_config_set_i (core -> config , "scr.color" , scr_color );
4812- }
4813- r_list_free (tmpenvs );
4814- return ret ;
4815- }
4816- for (cmd = ptr + 2 ; cmd && * cmd == ' ' ; cmd ++ ) {
4817- ;
4818- }
4819- ptr = strchr (cmd , '&' );
4820- }
4821-
48224846 ptr = strstr (cmd , "?*" );
48234847 if (ptr && ((ptr - cmd ) == 0 || ((ptr - cmd ) > 0 && ptr [-1 ] != '~' ))) {
48244848 char * pipechar = strchr (ptr , '>' );
@@ -5134,7 +5158,6 @@ repeat:;
51345158 }
51355159
51365160 cmd_tmpseek = core -> tmpseek = ptr ;
5137- int rc = 0 ;
51385161 if (ptr ) {
51395162 char * f , * ptr2 = strchr (ptr + 1 , '!' );
51405163 ut64 addr = core -> addr ;
0 commit comments