File glib2-add-g_canonicalize_filename.patch of Package glib2.23781
diff --unified --recursive --text glib-2.54.3.orig/glib/gtimezone.c glib-2.54.3.new/glib/gtimezone.c
--- glib-2.54.3.orig/glib/gtimezone.c 2020-11-13 09:59:04.801985507 +0800
+++ glib-2.54.3.new/glib/gtimezone.c 2020-11-13 09:59:38.365319402 +0800
@@ -193,6 +193,117 @@
there's no point in getting carried
away. */
+/* We don't want a ABI change so add here as static. */
+static gchar *
+g_canonicalize_filename (const gchar *filename,
+ const gchar *relative_to)
+{
+ gchar *canon, *start, *p, *q;
+ guint i;
+
+ g_return_val_if_fail (relative_to == NULL || g_path_is_absolute (relative_to), NULL);
+
+ if (!g_path_is_absolute (filename))
+ {
+ gchar *cwd_allocated = NULL;
+ const gchar *cwd;
+
+ if (relative_to != NULL)
+ cwd = relative_to;
+ else
+ cwd = cwd_allocated = g_get_current_dir ();
+
+ canon = g_build_filename (cwd, filename, NULL);
+ g_free (cwd_allocated);
+ }
+ else
+ {
+ canon = g_strdup (filename);
+ }
+
+ start = (char *)g_path_skip_root (canon);
+
+ if (start == NULL)
+ {
+ /* This shouldn't really happen, as g_get_current_dir() should
+ return an absolute pathname, but bug 573843 shows this is
+ not always happening */
+ g_free (canon);
+ return g_build_filename (G_DIR_SEPARATOR_S, filename, NULL);
+ }
+
+ /* POSIX allows double slashes at the start to
+ * mean something special (as does windows too).
+ * So, "//" != "/", but more than two slashes
+ * is treated as "/".
+ */
+ i = 0;
+ for (p = start - 1;
+ (p >= canon) &&
+ G_IS_DIR_SEPARATOR (*p);
+ p--)
+ i++;
+ if (i > 2)
+ {
+ i -= 1;
+ start -= i;
+ memmove (start, start+i, strlen (start+i) + 1);
+ }
+
+ /* Make sure we're using the canonical dir separator */
+ p++;
+ while (p < start && G_IS_DIR_SEPARATOR (*p))
+ *p++ = G_DIR_SEPARATOR;
+
+ p = start;
+ while (*p != 0)
+ {
+ if (p[0] == '.' && (p[1] == 0 || G_IS_DIR_SEPARATOR (p[1])))
+ {
+ memmove (p, p+1, strlen (p+1)+1);
+ }
+ else if (p[0] == '.' && p[1] == '.' && (p[2] == 0 || G_IS_DIR_SEPARATOR (p[2])))
+ {
+ q = p + 2;
+ /* Skip previous separator */
+ p = p - 2;
+ if (p < start)
+ p = start;
+ while (p > start && !G_IS_DIR_SEPARATOR (*p))
+ p--;
+ if (G_IS_DIR_SEPARATOR (*p))
+ *p++ = G_DIR_SEPARATOR;
+ memmove (p, q, strlen (q)+1);
+ }
+ else
+ {
+ /* Skip until next separator */
+ while (*p != 0 && !G_IS_DIR_SEPARATOR (*p))
+ p++;
+
+ if (*p != 0)
+ {
+ /* Canonicalize one separator */
+ *p++ = G_DIR_SEPARATOR;
+ }
+ }
+
+ /* Remove additional separators */
+ q = p;
+ while (*q && G_IS_DIR_SEPARATOR (*q))
+ q++;
+
+ if (p != q)
+ memmove (p, q, strlen (q) + 1);
+ }
+
+ /* Remove trailing slashes */
+ if (p > start && G_IS_DIR_SEPARATOR (*(p-1)))
+ *(p-1) = 0;
+
+ return canon;
+}
+
/**
* g_time_zone_unref:
* @tz: a #GTimeZone