чување 05c9e93ba8f529262e825ceb4e0af9268a1a66ac
родитељ 6579c3ea142cb4178480ac26edc4aa3caf190fcc
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Sun, 9 Jun 2024 18:25:29 +0200
Bugfix: Handle relative symlinks; use limits[L_PATH_MAX] for state.real_filename
Diffstat:
| M | sled.c | | | 36 | ++++++++++++++++++++++++++++++------ |
измењених датотека: 1, додавања: 30(+), брисања: 6(-)
diff --git a/sled.c b/sled.c
@@ -2493,6 +2493,7 @@ main(int argc, char** argv)
char* dir = NULL;
char* pdir = NULL;
char* temp = NULL;
+ char* rfn = NULL;
*error = 0;
*action = 0;
@@ -2607,8 +2608,7 @@ main(int argc, char** argv)
{
if (S_ISLNK(st.st_mode))
{
- if (!(state.real_filename
- = calloc(limits[L_PATH_MAX], 1)))
+ if (!(rfn = malloc(limits[L_PATH_MAX])))
{
free(filename);
free(dir);
@@ -2617,11 +2617,35 @@ main(int argc, char** argv)
"memory?)");
}
- state.rfn_len = readlink(state.filename,
- state.real_filename, limits[L_PATH_MAX]);
+ if (!(state.real_filename = malloc(limits[L_PATH_MAX])))
+ {
+ free(filename);
+ free(dir);
+ return print_error(1,
+ "Allocation failed (out of "
+ "memory?)");
+ }
+
+ state.rfn_len = readlink(state.filename, rfn,
+ limits[L_PATH_MAX]);
if (state.rfn_len == -1)
goto file_error;
- state.real_filename[state.rfn_len] = 0;
+
+ rfn[state.rfn_len] = 0;
+
+ if (*rfn == '/') /* rfn is absolute */
+ MEMCCPY(state.real_filename, rfn,
+ limits[L_PATH_MAX], temp);
+ else /* rfn is relative */
+ {
+ MEMCCPY(state.real_filename, dir,
+limits[L_PATH_MAX], temp);
+ *(temp-1) = '/';
+ MEMCCPY_EXT(temp, state.real_filename, rfn,
+limits[L_PATH_MAX], temp);
+ state.rfn_len = temp - state.real_filename - 1;
+ }
+ free(rfn);
#ifdef __OpenBSD__
if (unveil(state.real_filename, "rwc") < 0)
{
@@ -2682,7 +2706,7 @@ main(int argc, char** argv)
}
dir = pdir;
*dir = 0;
- (void)dirname(dir, state.real_filename, state.rfn_len + 1);
+ (void)dirname(dir, state.real_filename, limits[L_PATH_MAX]);
#ifdef __OpenBSD__
if (unveil(dir, "rwc") < 0)
{