@@ -4398,6 +4398,27 @@ static char *find_unescaped_conditional(char *cmd, const char *quotes) {
43984398 return or ;
43994399}
44004400
4401+ static bool is_internal_pipe_segment (const char * pipe , const char * next ) {
4402+ const char * segment = pipe + 1 ;
4403+ size_t length = next - segment ;
4404+ while (length > 0 && IS_WHITECHAR (segment [length - 1 ])) {
4405+ length -- ;
4406+ }
4407+ return length == 0 || (length == 1 && strchr ("DEJHT.?" , * segment ));
4408+ }
4409+
4410+ static char * find_unescaped_system_pipe (char * cmd , const char * quotes ) {
4411+ char * pipe = (char * )r_str_firstbut_escape (cmd , '|' , quotes );
4412+ while (pipe ) {
4413+ char * next = (char * )r_str_firstbut_escape (pipe + 1 , '|' , quotes );
4414+ if (!next || !is_internal_pipe_segment (pipe , next )) {
4415+ return pipe ;
4416+ }
4417+ pipe = next ;
4418+ }
4419+ return NULL ;
4420+ }
4421+
44014422static void unescape_shell_control_operators (char * cmd ) {
44024423 char quote = 0 ;
44034424 char * src = cmd ;
@@ -4410,7 +4431,7 @@ static void unescape_shell_control_operators(char *cmd) {
44104431 continue ;
44114432 }
44124433 if (!quote && (src [1 ] == '&' || src [1 ] == '|' ) &&
4413- src [2 ] == '\\' && src [3 ] == src [1 ]) {
4434+ src [2 ] && src [ 3 ] && src [ 2 ] == '\\' && src [3 ] == src [1 ]) {
44144435 * dst ++ = src [1 ];
44154436 * dst ++ = src [1 ];
44164437 src += 4 ;
@@ -4769,16 +4790,12 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd, char *colon, bool *tmpseek
47694790 return ret ;
47704791 }
47714792 }
4772- if (* cmd == '!' ) {
4773- ret = r_cmd_call (core -> rcmd , cmd );
4774- r_list_free (tmpenvs );
4775- return ret ;
4776- }
4793+ const bool system_command = * cmd == '!' ;
47774794 char * backtick = find_subcmd_begin (cmd , NULL );
47784795 if (backtick ) {
47794796 goto escape_redir ;
47804797 }
4781- ptr = find_unescaped_conditional (cmd , quotestr );
4798+ ptr = system_command ? NULL : find_unescaped_conditional (cmd , quotestr );
47824799 if (ptr ) {
47834800 bool run = true;
47844801 for (;;) {
@@ -4806,8 +4823,8 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd, char *colon, bool *tmpseek
48064823 }
48074824
48084825 /* pipe console to shell process */
4809- char * raw_operator = (char * )r_str_lastbut (cmd , '|' , quotestr );
4810- ptr = ( char * ) r_str_firstbut_escape (cmd , '|' , quotestr );
4826+ char * raw_operator = system_command ? NULL : (char * )r_str_lastbut (cmd , '|' , quotestr );
4827+ ptr = system_command ? NULL : find_unescaped_system_pipe (cmd , quotestr );
48114828 if (!ptr && raw_operator && is_escaped_operator (cmd , raw_operator )) {
48124829 memmove (raw_operator - 1 , raw_operator , strlen (raw_operator ) + 1 );
48134830 goto escape_pipe ;
@@ -4885,6 +4902,9 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd, char *colon, bool *tmpseek
48854902 }
48864903 }
48874904escape_pipe :
4905+ if (system_command ) {
4906+ goto escape_redir ;
4907+ }
48884908 ptr = strstr (cmd , "?*" );
48894909 if (ptr && ((ptr - cmd ) == 0 || ((ptr - cmd ) > 0 && ptr [-1 ] != '~' ))) {
48904910 char * pipechar = strchr (ptr , '>' );
0 commit comments