summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan <mail@3v1n0.net>2023-04-27 09:18:07 +0000
committerMarco Trevisan <mail@3v1n0.net>2023-04-27 09:18:07 +0000
commit59a2235e9d5b39ba61e76ff01a3d37aa9bc244fe (patch)
tree6950cf04778b171ec184f0e15cca7ed843354be7
parent48ac9b32b3cf35ab21e41e2737172361d52760b7 (diff)
parent7a5d4c2bb7d6ab1539508da5c67adebe78b40809 (diff)
downloadglib-59a2235e9d5b39ba61e76ff01a3d37aa9bc244fe.tar.gz
Merge branch '98-current-path' into 'main'
gfileutils: Fix potential integer overflow in g_get_current_dir() Closes #98 See merge request GNOME/glib!3375
-rw-r--r--glib/gfileutils.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/glib/gfileutils.c b/glib/gfileutils.c
index 4ed8171cc..9646c696e 100644
--- a/glib/gfileutils.c
+++ b/glib/gfileutils.c
@@ -2940,7 +2940,7 @@ g_get_current_dir (void)
const gchar *pwd;
gchar *buffer = NULL;
gchar *dir = NULL;
- static gulong max_len = 0;
+ static gsize buffer_size = 0;
struct stat pwdbuf, dotbuf;
pwd = g_getenv ("PWD");
@@ -2949,27 +2949,31 @@ g_get_current_dir (void)
dotbuf.st_dev == pwdbuf.st_dev && dotbuf.st_ino == pwdbuf.st_ino)
return g_strdup (pwd);
- if (max_len == 0)
- max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
+ if (buffer_size == 0)
+ buffer_size = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
- while (max_len < G_MAXULONG / 2)
+ while (buffer_size < G_MAXSIZE / 2)
{
g_free (buffer);
- buffer = g_new (gchar, max_len + 1);
+ buffer = g_new (gchar, buffer_size);
*buffer = 0;
- dir = getcwd (buffer, max_len);
+ dir = getcwd (buffer, buffer_size);
if (dir || errno != ERANGE)
break;
- max_len *= 2;
+ buffer_size *= 2;
}
+ /* Check that getcwd() nul-terminated the string. It should do, but the specs
+ * don’t actually explicitly state that:
+ * https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html */
+ g_assert (dir == NULL || strnlen (dir, buffer_size) < buffer_size);
+
if (!dir || !*buffer)
{
- /* hm, should we g_error() out here?
- * this can happen if e.g. "./" has mode \0000
- */
+ /* Fallback return value */
+ g_assert (buffer_size >= 2);
buffer[0] = G_DIR_SEPARATOR;
buffer[1] = 0;
}