From 34f26a016a55a742615538dfe5392e53b61fc46d Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 4 Feb 2021 13:58:32 +0000
Subject: [PATCH 08/12] gkeyfilesettingsbackend: Handle long keys when
converting paths
Previously, the code in `convert_path()` could not handle keys longer
than `G_MAXINT`, and would overflow if that was exceeded.
Convert the code to use `gsize` and `g_memdup2()` throughout, and
change from identifying the position of the final slash in the string
using a signed offset `i`, to using a pointer to the character (and
`strrchr()`). This allows the slash to be at any position in a
`G_MAXSIZE`-long string, without sacrificing a bit of the offset for
indicating whether a slash was found.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2319
---
gio/gkeyfilesettingsbackend.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
index f74e3682c..063df1ee7 100644
--- a/gio/gkeyfilesettingsbackend.c
+++ b/gio/gkeyfilesettingsbackend.c
@@ -33,6 +33,7 @@
#include "gfilemonitor.h"
#include "gsimplepermission.h"
#include "gsettingsbackendinternal.h"
+#include "gstrfuncsprivate.h"
#include "giomodule-priv.h"
#include "gportalsupport.h"
@@ -145,8 +146,8 @@ convert_path (GKeyfileSettingsBackend *kfsb,
gchar **group,
gchar **basename)
{
- gint key_len = strlen (key);
- gint i;
+ gsize key_len = strlen (key);
+ const gchar *last_slash;
if (key_len < kfsb->prefix_len ||
memcmp (key, kfsb->prefix, kfsb->prefix_len) != 0)
@@ -155,38 +156,36 @@ convert_path (GKeyfileSettingsBackend *kfsb,
key_len -= kfsb->prefix_len;
key += kfsb->prefix_len;
- for (i = key_len; i >= 0; i--)
- if (key[i] == '/')
- break;
+ last_slash = strrchr (key, '/');
if (kfsb->root_group)
{
/* if a root_group was specified, make sure the user hasn't given
* a path that ghosts that group name
*/
- if (i == kfsb->root_group_len && memcmp (key, kfsb->root_group, i) == 0)
+ if (last_slash != NULL && (last_slash - key) == kfsb->root_group_len && memcmp (key, kfsb->root_group, last_slash - key) == 0)
return FALSE;
}
else
{
/* if no root_group was given, ensure that the user gave a path */
- if (i == -1)
+ if (last_slash == NULL)
return FALSE;
}
if (group)
{
- if (i >= 0)
+ if (last_slash != NULL)
{
- *group = g_memdup (key, i + 1);
- (*group)[i] = '\0';
+ *group = g_memdup2 (key, (last_slash - key) + 1);
+ (*group)[(last_slash - key)] = '\0';
}
else
*group = g_strdup (kfsb->root_group);
}
if (basename)
- *basename = g_memdup (key + i + 1, key_len - i);
+ *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
return TRUE;
}
--
2.31.1