xaizek / vifm (License: GPLv2+) (since 2018-12-07)
Vifm is a file manager with curses interface, which provides Vi[m]-like environment for managing objects within file systems, extended with some useful ideas from mutt.
Commit df6c081ca69ddf295f6492e98e2cbf3b896a5ddd

Fix processing of incomplete escapes in commands
The unescape() function used to go past the end of a string.

Thanks to Denis Protivenskiy.
Author: xaizek
Author date (UTC): 2013-04-22 17:57
Committer name: xaizek
Committer date (UTC): 2013-04-22 17:57
Parent(s): 31ea22975355f2c7d386d31aecd79de01d2ae224
Signing key:
Tree: 9df36e2f8564f9945e84c7c1f3936eb4c8c2cd08
File Lines added Lines deleted
src/engine/cmds.c 8 4
src/engine/cmds.h 1 0
tests/commands/test.c 2 0
tests/commands/unescape.c 46 0
tests/commands/user_cmds.c 2 1
File src/engine/cmds.c changed (mode: 100644) (index a431d1057..3467b3dbc)
... ... static cmd_t * insert_cmd(cmd_t *after);
101 101 static int delcommand_cmd(const cmd_info_t *cmd_info); static int delcommand_cmd(const cmd_info_t *cmd_info);
102 102 TSTATIC char ** dispatch_line(const char args[], int *count, char sep, TSTATIC char ** dispatch_line(const char args[], int *count, char sep,
103 103 int regexp, int quotes, int *last_arg, int *last_begin, int *last_end); int regexp, int quotes, int *last_arg, int *last_begin, int *last_end);
104 static void unescape(char s[], int regexp);
104 TSTATIC void unescape(char s[], int regexp);
105 105 static void replace_double_squotes(char s[]); static void replace_double_squotes(char s[]);
106 106 static void replace_esc(char s[]); static void replace_esc(char s[]);
107 107
 
... ... get_last_argument(const char cmd[], size_t *len)
1020 1020 } }
1021 1021
1022 1022 /* Splits argument string into array of strings. Returns NULL if no arguments /* Splits argument string into array of strings. Returns NULL if no arguments
1023 * are found or an error occurred. Allways sets *count (to zero on errors). */
1023 * are found or an error occurred. Always sets *count (to zero on errors). */
1024 1024 TSTATIC char ** TSTATIC char **
1025 1025 dispatch_line(const char args[], int *count, char sep, int regexp, int quotes, dispatch_line(const char args[], int *count, char sep, int regexp, int quotes,
1026 1026 int *last_pos, int *last_begin, int *last_end) int *last_pos, int *last_begin, int *last_end)
 
... ... dispatch_line(const char args[], int *count, char sep, int regexp, int quotes,
1178 1178 return params; return params;
1179 1179 } }
1180 1180
1181 static void
1181 TSTATIC void
1182 1182 unescape(char s[], int regexp) unescape(char s[], int regexp)
1183 1183 { {
1184 1184 char *p; char *p;
 
... ... unescape(char s[], int regexp)
1188 1188 { {
1189 1189 if(s[0] == '\\' && (!regexp || s[1] == '/')) if(s[0] == '\\' && (!regexp || s[1] == '/'))
1190 1190 s++; s++;
1191 *p++ = *s++;
1191 *p++ = s[0];
1192 if(s[0] != '\0')
1193 {
1194 s++;
1195 }
1192 1196 } }
1193 1197 *p = '\0'; *p = '\0';
1194 1198 } }
File src/engine/cmds.h changed (mode: 100644) (index a0f7aaf2f..2d9646518)
... ... TSTATIC_DEFS(
140 140 int add_builtin_cmd(const char name[], int abbr, const cmd_add_t *conf); int add_builtin_cmd(const char name[], int abbr, const cmd_add_t *conf);
141 141 char ** dispatch_line(const char args[], int *count, char sep, int regexp, char ** dispatch_line(const char args[], int *count, char sep, int regexp,
142 142 int quotes, int *last_arg, int *last_begin, int *last_end); int quotes, int *last_arg, int *last_begin, int *last_end);
143 void unescape(char s[], int regexp);
143 144 ) )
144 145
145 146 #endif #endif
File tests/commands/test.c changed (mode: 100644) (index ee7b32424..ab6306b5b)
... ... void ids_tests(void);
29 29 void builtin_tests(void); void builtin_tests(void);
30 30 void one_number_range(void); void one_number_range(void);
31 31 void last_argument_tests(void); void last_argument_tests(void);
32 void unescape_tests(void);
32 33
33 34 cmds_conf_t cmds_conf = { cmds_conf_t cmds_conf = {
34 35 .complete_args = complete_args, .complete_args = complete_args,
 
... ... all_tests(void)
52 53 builtin_tests(); builtin_tests();
53 54 one_number_range(); one_number_range();
54 55 last_argument_tests(); last_argument_tests();
56 unescape_tests();
55 57 } }
56 58
57 59 static int static int
File tests/commands/unescape.c added (mode: 100644) (index 000000000..799040ffc)
1 #include "seatest.h"
2
3 #include "../../src/engine/cmds.h"
4
5 static void
6 test_empty_string_untouched(void)
7 {
8 char escaped[] = "";
9 const char *expected = "";
10 unescape(escaped, 0);
11 assert_string_equal(expected, escaped);
12 }
13
14 static void
15 test_stops_at_the_end(void)
16 {
17 char escaped[] = "a\\\0b";
18 const char *expected = "a";
19 unescape(escaped, 0);
20 assert_string_equal(expected, escaped);
21 assert_int_equal('\0', escaped[2]);
22 }
23
24 static void
25 test_incomplete_escape_sequence_truncated(void)
26 {
27 char escaped[] = "a\\";
28 const char *expected = "a";
29 unescape(escaped, 0);
30 assert_string_equal(expected, escaped);
31 }
32
33 void
34 unescape_tests(void)
35 {
36 test_fixture_start();
37
38 run_test(test_empty_string_untouched);
39 run_test(test_stops_at_the_end);
40 run_test(test_incomplete_escape_sequence_truncated);
41
42 test_fixture_end();
43 }
44
45 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
46 /* vim: set cinoptions+=t0 : */
File tests/commands/user_cmds.c changed (mode: 100644) (index fd263bbd9..57d30396f)
... ... user_cmds_tests(void)
43 43 test_fixture_end(); test_fixture_end();
44 44 } }
45 45
46 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab : */
46 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
47 /* vim: set cinoptions+=t0 : */
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/vifm

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/vifm

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master