File: Fix-1771-Deleting-not-write-protected-symlinks-to-write-p.patch

package info (click to toggle)
geeqie 1%3A2.6.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,992 kB
  • sloc: cpp: 95,956; xml: 11,502; sh: 3,654; awk: 124; perl: 88; python: 80; makefile: 24
file content (105 lines) | stat: -rw-r--r-- 2,744 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
From: Colin Clark <colin.clark@cclark.uk>
Date: Sun, 15 Jun 2025 15:59:19 +0100
Subject: Fix #1771: Deleting (not write protected) symlinks to write
 protected images gives warning

https://github.com/BestImageViewer/geeqie/issues/1771

Function access() was used, but this function follows symlinks.

Instead use lstat for delete/move/rename operations.
---
 src/filedata/filedata.cc | 59 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/src/filedata/filedata.cc b/src/filedata/filedata.cc
index 76f8866..ee779ff 100644
--- a/src/filedata/filedata.cc
+++ b/src/filedata/filedata.cc
@@ -23,6 +23,7 @@
 
 #include "filedata.h"
 
+#include <glib/gstdio.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
@@ -1997,6 +1998,60 @@ gboolean FileData::file_data_sc_update_ci_unspecified_list(GList *fd_list, const
  * it should detect all possible problems with the planned operation
  */
 
+/**
+ * @brief Determine if file is readable, do not follow symlinks
+ * @param path 
+ * @returns 
+ * 
+ * 
+ */
+static gboolean file_is_readable_no_follow(const gchar *path)
+{
+	gboolean readable = FALSE;
+	GStatBuf statbuf;
+
+	if (g_lstat(path, &statbuf) != 0)
+		{
+		log_printf("g_lstat failed: %s\n", strerror(errno));
+
+		return readable;
+		}
+
+	if (S_IRUSR & statbuf.st_mode)
+		{
+		readable = TRUE;
+		}
+
+	return readable;
+}
+
+/**
+ * @brief Determine if file is writable, do not follow symlinks
+ * @param path 
+ * @returns 
+ * 
+ * 
+ */
+static gboolean file_is_writable_no_follow(const gchar *path)
+{
+	gboolean writable = FALSE;
+	GStatBuf statbuf;
+
+	if (g_lstat(path, &statbuf) != 0)
+		{
+		log_printf("g_lstat failed: %s\n", strerror(errno));
+
+		return writable;
+		}
+
+	if (S_IWUSR & statbuf.st_mode)
+		{
+		writable = TRUE;
+		}
+
+	return writable;
+}
+
 gint FileData::file_data_verify_ci(FileData *fd, GList *list)
 {
 	gint ret = CHANGE_OK;
@@ -2032,7 +2087,7 @@ gint FileData::file_data_verify_ci(FileData *fd, GList *list)
 
 	if (fd->change->type != FILEDATA_CHANGE_DELETE &&
 	    fd->change->type != FILEDATA_CHANGE_WRITE_METADATA &&
-	    !access_file(fd->path, R_OK))
+		 !file_is_readable_no_follow(fd->path))
 		{
 		ret |= CHANGE_NO_READ_PERM;
 		DEBUG_1("Change checked: no read permission: %s", fd->path);
@@ -2046,7 +2101,7 @@ gint FileData::file_data_verify_ci(FileData *fd, GList *list)
 	else if (fd->change->type != FILEDATA_CHANGE_COPY &&
 		 fd->change->type != FILEDATA_CHANGE_UNSPECIFIED &&
 		 fd->change->type != FILEDATA_CHANGE_WRITE_METADATA &&
-		 !access_file(fd->path, W_OK))
+		 !file_is_writable_no_follow(fd->path))
 		{
 		ret |= CHANGE_WARN_NO_WRITE_PERM;
 		DEBUG_1("Change checked: no write permission: %s", fd->path);