Skip to content

Commit 5cae1dd

Browse files
committed
Merge branch '4642_fix_overflow'
Signed-off-by: Yury V. Zaytsev <[email protected]>
2 parents fbef24a + ac9a81d commit 5cae1dd

File tree

6 files changed

+158
-32
lines changed

6 files changed

+158
-32
lines changed

lib/strutil.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ char *str_regex_unescape (const char *text);
578578

579579
gboolean str_is_char_escaped (const char *start, const char *current);
580580

581+
void str_rstrip_eol (char *s);
582+
581583
/* --------------------------------------------------------------------------------------------- */
582584
/*** inline functions ****************************************************************************/
583585
/* --------------------------------------------------------------------------------------------- */

lib/strutil/strutil.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,3 +1020,21 @@ parse_integer (const char *str, gboolean *invalid)
10201020
}
10211021

10221022
/* --------------------------------------------------------------------------------------------- */
1023+
1024+
/**
1025+
* Strips single right (trailing) EOL (\\r, \\n, or \\r\\n), NULL-safe
1026+
*/
1027+
void
1028+
str_rstrip_eol (char *s)
1029+
{
1030+
if (s == NULL || *s == '\0')
1031+
return;
1032+
1033+
const size_t len = strlen (s);
1034+
if (len >= 2 && s[len - 2] == '\r' && s[len - 1] == '\n') // removes \r\n
1035+
s[len - 2] = '\0';
1036+
else if (len >= 1 && (s[len - 1] == '\n' || s[len - 1] == '\r')) // removes \n or \r
1037+
s[len - 1] = '\0';
1038+
}
1039+
1040+
/* --------------------------------------------------------------------------------------------- */

lib/vfs/parse_ls_vga.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <stdlib.h>
4141

4242
#include "lib/global.h"
43+
#include "lib/strutil.h"
4344
#include "lib/unixcompat.h" // makedev
4445
#include "lib/widget.h" // message()
4546

@@ -852,16 +853,7 @@ vfs_parse_ls_lga (const char *p, struct stat *s, char **filename, char **linknam
852853
*linkname = NULL;
853854
}
854855

855-
if (t != NULL)
856-
{
857-
size_t p2;
858-
859-
p2 = strlen (t);
860-
if (--p2 > 0 && (t[p2] == '\r' || t[p2] == '\n'))
861-
t[p2] = '\0';
862-
if (--p2 > 0 && (t[p2] == '\r' || t[p2] == '\n'))
863-
t[p2] = '\0';
864-
}
856+
str_rstrip_eol (t);
865857

866858
g_free (p_copy);
867859
return TRUE;

tests/lib/strutil/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ TESTS = \
1616
parse_integer \
1717
str_replace_all \
1818
str_verscmp \
19+
str_rstrip_eol \
1920
filevercmp
2021

2122
check_PROGRAMS = $(TESTS)
@@ -29,5 +30,8 @@ str_replace_all_SOURCES = \
2930
str_verscmp_SOURCES = \
3031
str_verscmp.c
3132

33+
str_rstrip_eol_SOURCES = \
34+
str_rstrip_eol.c
35+
3236
filevercmp_SOURCES = \
3337
filevercmp.c

tests/lib/strutil/str_rstrip_eol.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
lib/strutil - tests for lib/strutil.c:str_rstrip_eol function
3+
4+
Copyright (C) 2025
5+
Free Software Foundation, Inc.
6+
7+
This file is part of the Midnight Commander.
8+
9+
The Midnight Commander is free software: you can redistribute it
10+
and/or modify it under the terms of the GNU General Public License as
11+
published by the Free Software Foundation, either version 3 of the License,
12+
or (at your option) any later version.
13+
14+
The Midnight Commander is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
GNU General Public License for more details.
18+
19+
You should have received a copy of the GNU General Public License
20+
along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
*/
22+
23+
#define TEST_SUITE_NAME "/lib/strutil"
24+
25+
#include "tests/mctest.h"
26+
27+
#include "lib/strutil.h"
28+
29+
/* --------------------------------------------------------------------------------------------- */
30+
31+
/* @Before */
32+
static void
33+
setup (void)
34+
{
35+
}
36+
37+
/* --------------------------------------------------------------------------------------------- */
38+
39+
/* @After */
40+
static void
41+
teardown (void)
42+
{
43+
}
44+
45+
/* --------------------------------------------------------------------------------------------- */
46+
47+
/* @DataSource("str_rstrip_eol_test_ds1") */
48+
/* Testcases are taken from Glib */
49+
static const struct str_rstrip_eol_test_struct
50+
{
51+
const char *input_string;
52+
const char *expected_result;
53+
} str_rstrip_eol_test_ds1[] = {
54+
{
55+
"",
56+
"",
57+
},
58+
{
59+
" \n\r",
60+
" \n",
61+
},
62+
{
63+
" \t\r\n",
64+
" \t",
65+
},
66+
{
67+
"a \r ",
68+
"a \r ",
69+
},
70+
{
71+
" a \n ",
72+
" a \n ",
73+
},
74+
{
75+
"a a\n\r\n",
76+
"a a\n",
77+
},
78+
{
79+
"\na a \r",
80+
"\na a ",
81+
},
82+
};
83+
84+
/* @Test(dataSource = "str_rstrip_eol_test_ds1") */
85+
START_TEST (str_rstrip_eol_test1)
86+
{
87+
/* given */
88+
const struct str_rstrip_eol_test_struct *data = &str_rstrip_eol_test_ds1[_i];
89+
90+
/* when */
91+
char *actual_result = g_strdup (data->input_string);
92+
str_rstrip_eol (actual_result);
93+
94+
/* then */
95+
ck_assert_str_eq (actual_result, data->expected_result);
96+
97+
g_free (actual_result);
98+
}
99+
100+
END_TEST
101+
/* --------------------------------------------------------------------------------------------- */
102+
START_TEST (str_rstrip_eol_test_null)
103+
{
104+
char *ptr = NULL;
105+
str_rstrip_eol (ptr);
106+
ck_assert_ptr_null (ptr);
107+
}
108+
109+
END_TEST
110+
/* --------------------------------------------------------------------------------------------- */
111+
int
112+
main (void)
113+
{
114+
TCase *tc_core;
115+
116+
tc_core = tcase_create ("Core");
117+
118+
tcase_add_checked_fixture (tc_core, setup, teardown);
119+
120+
/* Add new tests here: *************** */
121+
mctest_add_parameterized_test (tc_core, str_rstrip_eol_test1, str_rstrip_eol_test_ds1);
122+
tcase_add_test (tc_core, str_rstrip_eol_test_null);
123+
/* *********************************** */
124+
125+
return mctest_run_all (tc_core);
126+
}
127+
128+
/* --------------------------------------------------------------------------------------------- */

tests/src/vfs/extfs/helpers-list/mc_parse_ls_l.c

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@
4242

4343
#include "lib/vfs/utilvfs.h" // vfs_parse_ls_lga()
4444
#include "lib/util.h" // string_perm()
45-
#include "lib/timefmt.h" // FMT_LOCALTIME
46-
#include "lib/widget.h" // for the prototype of message() only
45+
#include "lib/strutil.h"
46+
#include "lib/timefmt.h" // FMT_LOCALTIME
47+
#include "lib/widget.h" // for the prototype of message() only
4748

4849
/*** global variables ****************************************************************************/
4950

@@ -200,25 +201,6 @@ symbolic_gid (gid_t gid)
200201

201202
/* --------------------------------------------------------------------------------------------- */
202203

203-
/**
204-
* Cuts off a string's line-end (as in Perl).
205-
*/
206-
static void
207-
chomp (char *s)
208-
{
209-
int i;
210-
211-
i = strlen (s);
212-
213-
// Code taken from vfs_parse_ls_lga(), with modifications.
214-
if ((--i >= 0) && (s[i] == '\r' || s[i] == '\n'))
215-
s[i] = '\0';
216-
if ((--i >= 0) && (s[i] == '\r' || s[i] == '\n'))
217-
s[i] = '\0';
218-
}
219-
220-
/* --------------------------------------------------------------------------------------------- */
221-
222204
static const char *
223205
string_date (time_t t)
224206
{
@@ -396,7 +378,7 @@ process_input (FILE *input)
396378

397379
while (fgets (line, sizeof line, input) != NULL)
398380
{
399-
chomp (line); // Not mandatory. Makes error messages nicer.
381+
str_rstrip_eol (line); // Not mandatory. Makes error messages nicer.
400382
if (strncmp (line, "total ", 6) == 0) // Convenience only: makes 'ls -l' parse cleanly.
401383
continue;
402384
process_ls_line (line);

0 commit comments

Comments
 (0)