is_valid_filename (GFile *file, GFile *destination)
{
  g_autoptr (GFile) parent = NULL;
  g_autoptr (GFileInfo) info = NULL;

  if (g_file_equal (file, destination))
    return TRUE;

  if (!g_file_has_prefix (file, destination))
    return FALSE;

  /* Resolve symbolic link ancestors to confirm file is actually inside destination. */
  parent = g_file_get_parent (file);
  info = g_file_query_info (parent,
                            G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
                            G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                            NULL,
                            NULL);
  if (info == NULL)
    return FALSE;

  if (g_file_info_get_is_symlink (info)) {
    g_autoptr (GFile) cwd = NULL;
    const gchar *target;

    target = g_file_info_get_symlink_target (info);
    if (g_path_is_absolute (target))
      return FALSE;

    cwd = g_file_get_parent (parent);
    g_object_unref (parent);
    parent = g_file_resolve_relative_path (cwd, target);
  }

  /* Climb up the path to resolve every symbolic link ancestor found */
  return is_valid_filename (parent, destination);
}
is_valid_filename (GFile *file, GFile *destination)
{
  g_autoptr (GFile) parent = NULL;
  g_autoptr (GFileInfo) info = NULL;

  if (g_file_equal (file, destination))
    return TRUE;

  if (!g_file_has_prefix (file, destination))
    return FALSE;

   
  parent = g_file_get_parent (file);
  info = g_file_query_info (parent,
                            G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
                            G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
                            G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                            NULL,
                            NULL);
  if (info == NULL)
    return FALSE;

  if (g_file_info_get_is_symlink (info)) {
    g_autoptr (GFile) cwd = NULL;
    const gchar *target;

    target = g_file_info_get_symlink_target (info);
    if (g_path_is_absolute (target))
      return FALSE;

    cwd = g_file_get_parent (parent);
    g_object_unref (parent);
    parent = g_file_resolve_relative_path (cwd, target);
  }

   
  return is_valid_filename (parent, destination);
}