Manual pages: mcmcdiffmceditmcview

root/tests/src/filemanager/has_unquoted_metacharacters.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. START_PARAMETRIZED_TEST
  2. main

   1 /*
   2    src/filemanager - tests for command_has_unquoted_metacharacters()
   3 
   4    Copyright (C) 2026
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Marek Libra <marek.libra@gmail.com>, 2026
   9 
  10    This file is part of the Midnight Commander.
  11 
  12    The Midnight Commander is free software: you can redistribute it
  13    and/or modify it under the terms of the GNU General Public License as
  14    published by the Free Software Foundation, either version 3 of the License,
  15    or (at your option) any later version.
  16 
  17    The Midnight Commander is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21 
  22    You should have received a copy of the GNU General Public License
  23    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  24  */
  25 
  26 #define TEST_SUITE_NAME "/src/filemanager"
  27 
  28 #include "tests/mctest.h"
  29 
  30 /* --------------------------------------------------------------------------------------------- */
  31 
  32 MC_TESTABLE gboolean command_has_unquoted_metacharacters (const char *cmd);
  33 
  34 /* --------------------------------------------------------------------------------------------- */
  35 
  36 /* @DataSource("test_metacharacters_ds") */
  37 static const struct test_metacharacters_ds
  38 {
  39     const char *input_value;
  40     gboolean expected_result;
  41 } test_metacharacters_ds[] = {
  42     /* simple commands - no metacharacters */
  43     { "cd", FALSE },
  44     { "cd /tmp", FALSE },
  45     { "cd ..", FALSE },
  46     { "cd ~/projects", FALSE },
  47     { "cd $HOME", FALSE },
  48     { "cd -", FALSE },
  49     { "cd /path/to/dir", FALSE },
  50     { "cd foo bar", FALSE },
  51 
  52     /* semicolons */
  53     { "cd ..; make", TRUE },
  54     { "cd ..; make; cd -", TRUE },
  55     { "cd /tmp; ls", TRUE },
  56     { "cd ..;ls", TRUE },
  57     { "cd /tmp;ls", TRUE },
  58 
  59     /* && */
  60     { "cd .. && make", TRUE },
  61     { "cd /tmp && ls && pwd", TRUE },
  62     { "cd ..&&ls", TRUE },
  63 
  64     /* || */
  65     { "cd .. || echo fail", TRUE },
  66     { "cd ..||ls", TRUE },
  67 
  68     /* pipe */
  69     { "cd foo | bar", TRUE },
  70     { "cd ..|ls", TRUE },
  71 
  72     /* background / single & */
  73     { "cd &", TRUE },
  74     { "cd a&b", TRUE },
  75 
  76     /* quoted paths - metacharacters inside quotes are literal */
  77     { "cd 'foo bar'", FALSE },
  78     { "cd \"foo bar\"", FALSE },
  79     { "cd 'foo;bar'", FALSE },
  80     { "cd 'foo|bar'", FALSE },
  81     { "cd 'foo&bar'", FALSE },
  82     { "cd \"foo;bar\"", FALSE },
  83     { "cd \"foo|bar\"", FALSE },
  84     { "cd \"foo&bar\"", FALSE },
  85 
  86     /* quoted path followed by a real separator */
  87     { "cd 'foo'; ls", TRUE },
  88 
  89     /* backslash-escaped metacharacters are literal */
  90     { "cd foo\\ bar", FALSE },
  91     { "cd foo\\;bar", FALSE },
  92     { "cd foo\\|bar", FALSE },
  93     { "cd foo\\&bar", FALSE },
  94     { "cd path\\;with\\;semicolons", FALSE },
  95 
  96     /* escaped metacharacter plus a real separator */
  97     { "cd foo\\;bar; make", TRUE },
  98 
  99     /* double-backslash before semicolon: \\; at runtime - first \ escapes second, the ; is real */
 100     { "cd foo\\\\;ls", TRUE },
 101     /* triple-backslash before semicolon: \\\; at runtime - \\ + \; (escaped semicolon) */
 102     { "cd foo\\\\\\;ls", FALSE },
 103 
 104     /* command substitution $(...) - internal cd cannot expand */
 105     { "cd $(echo /tmp)", TRUE },
 106     { "cd $(pwd)", TRUE },
 107     { "cd $(echo foo;echo bar)", TRUE },
 108 
 109     /* command substitution with backticks */
 110     { "cd `echo /tmp`", TRUE },
 111     { "cd `pwd`", TRUE },
 112 
 113     /* single-quoted command substitution - literal, not metacharacters */
 114     { "cd '$(echo /tmp)'", FALSE },
 115     { "cd '`echo /tmp`'", FALSE },
 116 
 117     /* double-quoted command substitution - shell still expands these */
 118     { "cd \"$(echo /tmp)\"", TRUE },
 119     { "cd \"`echo /tmp`\"", TRUE },
 120 
 121     /* escaped $ and backtick */
 122     { "cd \\$(echo /tmp)", FALSE },
 123     { "cd \\`echo /tmp\\`", FALSE },
 124 
 125     /* empty and whitespace-only strings */
 126     { "", FALSE },
 127     { "   ", FALSE },
 128 
 129     /* parameter expansion - not command substitution */
 130     { "cd ${HOME}", FALSE },
 131 
 132     /* arithmetic expansion - triggers $( detection */
 133     { "cd $((1+2))", TRUE },
 134 
 135     /* unterminated quotes - no metachar, shell would error anyway */
 136     { "cd 'foo", FALSE },
 137     { "cd \"foo", FALSE },
 138 };
 139 
 140 /* @Test(dataSource = "test_metacharacters_ds") */
 141 START_PARAMETRIZED_TEST (test_metacharacters, test_metacharacters_ds)
     /* [previous][next][first][last][top][bottom][index][help]  */
 142 {
 143     gboolean actual_result;
 144 
 145     actual_result = command_has_unquoted_metacharacters (data->input_value);
 146 
 147     ck_assert_int_eq (actual_result, data->expected_result);
 148 }
 149 END_PARAMETRIZED_TEST
 150 
 151 /* --------------------------------------------------------------------------------------------- */
 152 
 153 int
 154 main (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 155 {
 156     TCase *tc_core;
 157 
 158     tc_core = tcase_create ("Core");
 159 
 160     /* Add new tests here: *************** */
 161     mctest_add_parameterized_test (tc_core, test_metacharacters, test_metacharacters_ds);
 162     /* *********************************** */
 163 
 164     return mctest_run_all (tc_core);
 165 }
 166 
 167 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */