Skip to content

Commit

Permalink
Merge branch '2626_escape_autocompletion'
Browse files Browse the repository at this point in the history
* 2626_escape_autocompletion:
  mc_search__translate_replace_glob_to_regex(): Avoid warnings
  Update EN and RU man pages.
  Add tests for mc_search__translate_replace_glob_to_regex() function.
  Ticket #2626: special chars are not escaped in autocompletion of filenames.
  • Loading branch information
aborodin committed Feb 14, 2013
2 parents d35b4b1 + 5445133 commit 11b5a9a
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 14 deletions.
12 changes: 11 additions & 1 deletion doc/man/mc.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -3058,7 +3058,9 @@ Filename, username, variable and hostname completion works on all input
lines, command completion is command line specific. If the completion
is ambiguous (there are more different possibilities), MC beeps and the
following action depends on the setting of the
.I Complete: show all
.\"LINK2"
Complete: show all
.\"Configuration"
option in the
.\"LINK2"
Configuration
Expand All @@ -3083,6 +3085,14 @@ Complete: show all
is disabled, the dialog pops up only if you press
.B Alt\-Tab
for the second time, for the first time MC just beeps.
.PP
Apply escaping of
.BR ? ", " * " and " &
symbols (as
.BR \\? ", " \\* ", " \\& )
in filenames to disallow use them as metasymbols in regular expressions
when substitution is performed in the input line.

.\"NODE "Virtual File System"
.SH "Virtual File System"
The Midnight Commander is provided with a code layer to access the file
Expand Down
24 changes: 17 additions & 7 deletions doc/man/ru/mc.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -2023,7 +2023,7 @@ like regular expressions). Для того, чтобы достичь таког
заменяется на обычную точку. Если опция отключена, то регулярные
выражения должны строиться так, как описано в ed(1).
.PP
.I Дополнение: показывать все.
.I Дополнение: показывать всё.
В процессе ввода команд Midnight Commander может выполнять
.\"LINK2"
Завершение ввода
Expand Down Expand Up @@ -3338,11 +3338,11 @@ Midnight Commander поддерживает возможность одновр
Завершение ввода \- это попытка закончить за вас ввод текста, набранного
до текущей позиции курсора. MC пытается завершить ввод, трактуя уже
введенный текст как переменную (если текст начинается с
.BR $ ),
.BR $ ")",
имя пользователя (если текст начинается с
.BR ~ ),
.BR ~ ")",
имя машины (если текст начинается на
.BR @ )
.BR @ ")"
или как команду (если вы в командной строке в позиции, где вы можете
вводить команду; в этом случае для завершения ввода используются
зарезервированные слова оболочки, в том числе любая из встроенных команд
Expand All @@ -3354,7 +3354,9 @@ Midnight Commander поддерживает возможность одновр
однозначно выполнить завершение ввода невозможно (имеется несколько
вариантов), MC издает звуковой сигнал и выполняет следующие действия, в
зависимости от установки опции
.I Дополнение: показывать все
.\"LINK2"
Дополнение: показывать всё
.\"Configuration"
в пункте меню
.\"LINK2"
Настройки/Конфигурация\&.
Expand All @@ -3373,14 +3375,22 @@ Midnight Commander поддерживает возможность одновр
отказаться от вывода на экран этого окна в любое время, нажав одну из
клавиш
.BR Esc ", " F10
или стрелку влево / вправо. Если опция
или стрелку влево/вправо. Если опция
.\"LINK2"
.I Дополнение: показывать все
Дополнение: показывать всё
.\"Configuration"
отключена, окно с вариантами завершения появляется только тогда, когда
вы нажмете клавиши
.B M\-Tab
второй раз, при первом нажатии MC только издает звуковой сигнал.
.PP
Используйте экранирование символов
.BR ? ", " * " и " &
(как
.BR \\? ", " \\* ", " \\& )
в именах файлов, чтобы они не рассматривались как метасимволы в регулярных
выражениях при подстановках в полях ввода.

.\"NODE "Virtual File System"
.SH "Виртуальные файловые системы"
Программа Midnight Commander содержит подпрограммы, обеспечивающие
Expand Down
10 changes: 6 additions & 4 deletions lib/search/glob.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ mc_search__glob_translate_to_regex (const GString * astr)
/* --------------------------------------------------------------------------------------------- */

static GString *
mc_search__translate_replace_glob_to_regex (gchar * str)
mc_search__translate_replace_glob_to_regex (const char * str)
{
GString *buff;
int cnt = '0';
Expand All @@ -118,9 +118,10 @@ mc_search__translate_replace_glob_to_regex (gchar * str)
if (!escaped_mode)
{
escaped_mode = TRUE;
g_string_append_c (buff, '\\');
continue;
}
g_string_append_c (buff, c);
continue;
break;
case '*':
case '?':
if (!escaped_mode)
Expand All @@ -130,7 +131,8 @@ mc_search__translate_replace_glob_to_regex (gchar * str)
}
break;
case '&':
g_string_append_c (buff, '\\');
if (!escaped_mode)
g_string_append_c (buff, '\\');
break;
}
g_string_append_c (buff, c);
Expand Down
17 changes: 17 additions & 0 deletions lib/widget/input_complete.c
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,23 @@ try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags)

g_free (state.word);

if (matches != NULL &&
(flags & (INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_SHELL_ESC)) !=
(INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_SHELL_ESC))
{
/* FIXME: HACK? INPUT_COMPLETE_SHELL_ESC is used only in command line. */
char **m;

for (m = matches; *m != NULL; m++)
{
char *p;

p = *m;
*m = strutils_shell_escape (*m);
g_free (p);
}
}

return matches;
}

Expand Down
8 changes: 6 additions & 2 deletions tests/lib/search/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ LIBS = @CHECK_LIBS@ $(top_builddir)/lib/libmc.la

TESTS = \
regex_replace_esc_seq \
regex_process_escape_sequence
regex_process_escape_sequence \
translate_replace_glob_to_regex

check_PROGRAMS = $(TESTS)

regex_replace_esc_seq_SOURCES = \
regex_replace_esc_seq.c

regex_process_escape_sequence_SOURCES = \
regex_process_escape_sequence.c
regex_process_escape_sequence.c

translate_replace_glob_to_regex_SOURCES = \
translate_replace_glob_to_regex.c
80 changes: 80 additions & 0 deletions tests/lib/search/translate_replace_glob_to_regex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
libmc - checks for processing esc sequences in replace string
Copyright (C) 2011
The Free Software Foundation, Inc.
Written by:
Andrew Borodin <[email protected]>, 2011
This file is part of the Midnight Commander.
The Midnight Commander is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#define TEST_SUITE_NAME "lib/search/glob"

#include <config.h>

#include <check.h>

#include "glob.c" /* for testing static functions */

/* --------------------------------------------------------------------------------------------- */

static void
test_helper_valid_data (const char *from, const char *etalon)
{
GString *dest_str;

dest_str = mc_search__translate_replace_glob_to_regex (from);
fail_if (strcmp (dest_str->str, etalon), "dest_str(%s) != %s", dest_str->str, etalon);
g_string_free (dest_str, TRUE);
}

/* --------------------------------------------------------------------------------------------- */

START_TEST (test_translate_replace_glob_to_regex)
{
test_helper_valid_data ("a&a?a", "a\\&a\\1a");
test_helper_valid_data ("a\\&a?a", "a\\&a\\1a");
test_helper_valid_data ("a&a\\?a", "a\\&a\\?a");
test_helper_valid_data ("a\\&a\\?a", "a\\&a\\?a");
}
END_TEST

/* --------------------------------------------------------------------------------------------- */

int
main (void)
{
int number_failed;

Suite *s = suite_create (TEST_SUITE_NAME);
TCase *tc_core = tcase_create ("Core");
SRunner *sr;

/* Add new tests here: *************** */
tcase_add_test (tc_core, test_translate_replace_glob_to_regex);
/* *********************************** */

suite_add_tcase (s, tc_core);
sr = srunner_create (s);
srunner_run_all (sr, CK_NORMAL);
number_failed = srunner_ntests_failed (sr);
srunner_free (sr);
return (number_failed == 0) ? 0 : 1;
}

/* --------------------------------------------------------------------------------------------- */

0 comments on commit 11b5a9a

Please sign in to comment.