gnu: glib: Fix CVE-2021-27218 and CVE-2021-27219.
* gnu/packages/patches/glib-CVE-2021-27218.patch, gnu/packages/patches/glib-CVE-2021-27219-01.patch, gnu/packages/patches/glib-CVE-2021-27219-02.patch, gnu/packages/patches/glib-CVE-2021-27219-03.patch, gnu/packages/patches/glib-CVE-2021-27219-04.patch, gnu/packages/patches/glib-CVE-2021-27219-05.patch, gnu/packages/patches/glib-CVE-2021-27219-06.patch, gnu/packages/patches/glib-CVE-2021-27219-07.patch, gnu/packages/patches/glib-CVE-2021-27219-08.patch, gnu/packages/patches/glib-CVE-2021-27219-09.patch, gnu/packages/patches/glib-CVE-2021-27219-10.patch, gnu/packages/patches/glib-CVE-2021-27219-11.patch, gnu/packages/patches/glib-CVE-2021-27219-12.patch, gnu/packages/patches/glib-CVE-2021-27219-13.patch, gnu/packages/patches/glib-CVE-2021-27219-14.patch, gnu/packages/patches/glib-CVE-2021-27219-15.patch, gnu/packages/patches/glib-CVE-2021-27219-16.patch, gnu/packages/patches/glib-CVE-2021-27219-17.patch, gnu/packages/patches/glib-CVE-2021-27219-18.patch: New files. * gnu/local.mk (dist_patch_DATA): Add them. * gnu/packages/glib.scm (glib)[replacement]: New field. (glib/fixed): New variable.master
parent
500189b4d2
commit
21b3b75515
21
gnu/local.mk
21
gnu/local.mk
|
@ -2,7 +2,7 @@
|
||||||
# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
# Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Andreas Enge <andreas@enge.fr>
|
# Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Andreas Enge <andreas@enge.fr>
|
||||||
# Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
|
# Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
|
||||||
# Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Mark H Weaver <mhw@netris.org>
|
# Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Mark H Weaver <mhw@netris.org>
|
||||||
# Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
|
# Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
|
||||||
# Copyright © 2016, 2017, 2018 Kei Kebreau <kkebreau@posteo.net>
|
# Copyright © 2016, 2017, 2018 Kei Kebreau <kkebreau@posteo.net>
|
||||||
# Copyright © 2016, 2017 Rene Saavedra <rennes@openmailbox.org>
|
# Copyright © 2016, 2017 Rene Saavedra <rennes@openmailbox.org>
|
||||||
|
@ -1076,6 +1076,25 @@ dist_patch_DATA = \
|
||||||
%D%/packages/patches/ghostscript-no-header-creationdate.patch \
|
%D%/packages/patches/ghostscript-no-header-creationdate.patch \
|
||||||
%D%/packages/patches/glib-appinfo-watch.patch \
|
%D%/packages/patches/glib-appinfo-watch.patch \
|
||||||
%D%/packages/patches/glib-tests-timer.patch \
|
%D%/packages/patches/glib-tests-timer.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27218.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-01.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-02.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-03.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-04.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-05.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-06.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-07.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-08.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-09.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-10.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-11.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-12.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-13.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-14.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-15.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-16.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-17.patch \
|
||||||
|
%D%/packages/patches/glib-CVE-2021-27219-18.patch \
|
||||||
%D%/packages/patches/glibc-CVE-2018-11236.patch \
|
%D%/packages/patches/glibc-CVE-2018-11236.patch \
|
||||||
%D%/packages/patches/glibc-CVE-2018-11237.patch \
|
%D%/packages/patches/glibc-CVE-2018-11237.patch \
|
||||||
%D%/packages/patches/glibc-CVE-2019-7309.patch \
|
%D%/packages/patches/glibc-CVE-2019-7309.patch \
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
;;; Copyright © 2013, 2014, 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2013, 2014, 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2013, 2015 Andreas Enge <andreas@enge.fr>
|
;;; Copyright © 2013, 2015 Andreas Enge <andreas@enge.fr>
|
||||||
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
|
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
|
||||||
;;; Copyright © 2014, 2015, 2016, 2017, 2018 Mark H Weaver <mhw@netris.org>
|
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2021 Mark H Weaver <mhw@netris.org>
|
||||||
;;; Copyright © 2016, 2020 Efraim Flashner <efraim@flashner.co.il>
|
;;; Copyright © 2016, 2020 Efraim Flashner <efraim@flashner.co.il>
|
||||||
;;; Copyright © 2016 Lukas Gradl <lgradl@openmailbox.org>
|
;;; Copyright © 2016 Lukas Gradl <lgradl@openmailbox.org>
|
||||||
;;; Copyright © 2017, 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
|
;;; Copyright © 2017, 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
|
||||||
|
@ -172,6 +172,7 @@ shared NFS home directories.")
|
||||||
(package
|
(package
|
||||||
(name "glib")
|
(name "glib")
|
||||||
(version "2.62.6")
|
(version "2.62.6")
|
||||||
|
(replacement glib/fixed)
|
||||||
(source (origin
|
(source (origin
|
||||||
(method url-fetch)
|
(method url-fetch)
|
||||||
(uri (string-append "mirror://gnome/sources/"
|
(uri (string-append "mirror://gnome/sources/"
|
||||||
|
@ -390,6 +391,33 @@ dynamic loading, and an object system.")
|
||||||
(home-page "https://developer.gnome.org/glib/")
|
(home-page "https://developer.gnome.org/glib/")
|
||||||
(license license:lgpl2.1+)))
|
(license license:lgpl2.1+)))
|
||||||
|
|
||||||
|
(define glib/fixed
|
||||||
|
(package
|
||||||
|
(inherit glib)
|
||||||
|
(source (origin
|
||||||
|
(inherit (package-source glib))
|
||||||
|
(patches
|
||||||
|
(append (search-patches "glib-CVE-2021-27218.patch"
|
||||||
|
"glib-CVE-2021-27219-01.patch"
|
||||||
|
"glib-CVE-2021-27219-02.patch"
|
||||||
|
"glib-CVE-2021-27219-03.patch"
|
||||||
|
"glib-CVE-2021-27219-04.patch"
|
||||||
|
"glib-CVE-2021-27219-05.patch"
|
||||||
|
"glib-CVE-2021-27219-06.patch"
|
||||||
|
"glib-CVE-2021-27219-07.patch"
|
||||||
|
"glib-CVE-2021-27219-08.patch"
|
||||||
|
"glib-CVE-2021-27219-09.patch"
|
||||||
|
"glib-CVE-2021-27219-10.patch"
|
||||||
|
"glib-CVE-2021-27219-11.patch"
|
||||||
|
"glib-CVE-2021-27219-12.patch"
|
||||||
|
"glib-CVE-2021-27219-13.patch"
|
||||||
|
"glib-CVE-2021-27219-14.patch"
|
||||||
|
"glib-CVE-2021-27219-15.patch"
|
||||||
|
"glib-CVE-2021-27219-16.patch"
|
||||||
|
"glib-CVE-2021-27219-17.patch"
|
||||||
|
"glib-CVE-2021-27219-18.patch")
|
||||||
|
(origin-patches (package-source glib))))))))
|
||||||
|
|
||||||
(define-public glib-with-documentation
|
(define-public glib-with-documentation
|
||||||
;; glib's doc must be built in a separate package since it requires gtk-doc,
|
;; glib's doc must be built in a separate package since it requires gtk-doc,
|
||||||
;; which in turn depends on glib.
|
;; which in turn depends on glib.
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
Backport of:
|
||||||
|
|
||||||
|
From 0f384c88a241bbbd884487b1c40b7b75f1e638d3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Krzesimir Nowak <qdlacz@gmail.com>
|
||||||
|
Date: Wed, 10 Feb 2021 23:51:07 +0100
|
||||||
|
Subject: [PATCH] gbytearray: Do not accept too large byte arrays
|
||||||
|
|
||||||
|
GByteArray uses guint for storing the length of the byte array, but it
|
||||||
|
also has a constructor (g_byte_array_new_take) that takes length as a
|
||||||
|
gsize. gsize may be larger than guint (64 bits for gsize vs 32 bits
|
||||||
|
for guint). It is possible to call the function with a value greater
|
||||||
|
than G_MAXUINT, which will result in silent length truncation. This
|
||||||
|
may happen as a result of unreffing GBytes into GByteArray, so rather
|
||||||
|
be loud about it.
|
||||||
|
|
||||||
|
(Test case tweaked by Philip Withnall.)
|
||||||
|
|
||||||
|
(Backport 2.66: Add #include gstrfuncsprivate.h in the test case for
|
||||||
|
`g_memdup2()`.)
|
||||||
|
---
|
||||||
|
glib/garray.c | 6 ++++++
|
||||||
|
glib/gbytes.c | 4 ++++
|
||||||
|
glib/tests/bytes.c | 35 ++++++++++++++++++++++++++++++++++-
|
||||||
|
3 files changed, 44 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/glib/garray.c b/glib/garray.c
|
||||||
|
index 942e74c9f..fb1a42aaf 100644
|
||||||
|
--- a/glib/garray.c
|
||||||
|
+++ b/glib/garray.c
|
||||||
|
@@ -2013,6 +2013,10 @@ g_byte_array_new (void)
|
||||||
|
* Create byte array containing the data. The data will be owned by the array
|
||||||
|
* and will be freed with g_free(), i.e. it could be allocated using g_strdup().
|
||||||
|
*
|
||||||
|
+ * Do not use it if @len is greater than %G_MAXUINT. #GByteArray
|
||||||
|
+ * stores the length of its data in #guint, which may be shorter than
|
||||||
|
+ * #gsize.
|
||||||
|
+ *
|
||||||
|
* Since: 2.32
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a new #GByteArray
|
||||||
|
@@ -2024,6 +2028,8 @@ g_byte_array_new_take (guint8 *data,
|
||||||
|
GByteArray *array;
|
||||||
|
GRealArray *real;
|
||||||
|
|
||||||
|
+ g_return_val_if_fail (len <= G_MAXUINT, NULL);
|
||||||
|
+
|
||||||
|
array = g_byte_array_new ();
|
||||||
|
real = (GRealArray *)array;
|
||||||
|
g_assert (real->data == NULL);
|
||||||
|
diff --git a/glib/gbytes.c b/glib/gbytes.c
|
||||||
|
index 7b72886e5..d56abe6c3 100644
|
||||||
|
--- a/glib/gbytes.c
|
||||||
|
+++ b/glib/gbytes.c
|
||||||
|
@@ -519,6 +519,10 @@ g_bytes_unref_to_data (GBytes *bytes,
|
||||||
|
* g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all
|
||||||
|
* other cases the data is copied.
|
||||||
|
*
|
||||||
|
+ * Do not use it if @bytes contains more than %G_MAXUINT
|
||||||
|
+ * bytes. #GByteArray stores the length of its data in #guint, which
|
||||||
|
+ * may be shorter than #gsize, that @bytes is using.
|
||||||
|
+ *
|
||||||
|
* Returns: (transfer full): a new mutable #GByteArray containing the same byte data
|
||||||
|
*
|
||||||
|
* Since: 2.32
|
||||||
|
diff --git a/glib/tests/bytes.c b/glib/tests/bytes.c
|
||||||
|
index 5ea5c2b35..15a6aaad6 100644
|
||||||
|
--- a/glib/tests/bytes.c
|
||||||
|
+++ b/glib/tests/bytes.c
|
||||||
|
@@ -10,12 +10,12 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef G_DISABLE_ASSERT
|
||||||
|
-#undef G_LOG_DOMAIN
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "glib.h"
|
||||||
|
+#include "glib/gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
/* Keep in sync with glib/gbytes.c */
|
||||||
|
struct _GBytes
|
||||||
|
@@ -333,6 +333,38 @@ test_to_array_transferred (void)
|
||||||
|
g_byte_array_unref (array);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+test_to_array_transferred_oversize (void)
|
||||||
|
+{
|
||||||
|
+ g_test_message ("g_bytes_unref_to_array() can only take GBytes up to "
|
||||||
|
+ "G_MAXUINT in length; test that longer ones are rejected");
|
||||||
|
+
|
||||||
|
+ if (sizeof (guint) >= sizeof (gsize))
|
||||||
|
+ {
|
||||||
|
+ g_test_skip ("Skipping test as guint is not smaller than gsize");
|
||||||
|
+ }
|
||||||
|
+ else if (g_test_undefined ())
|
||||||
|
+ {
|
||||||
|
+ GByteArray *array = NULL;
|
||||||
|
+ GBytes *bytes = NULL;
|
||||||
|
+ gpointer data = g_memdup2 (NYAN, N_NYAN);
|
||||||
|
+ gsize len = ((gsize) G_MAXUINT) + 1;
|
||||||
|
+
|
||||||
|
+ bytes = g_bytes_new_take (data, len);
|
||||||
|
+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
|
||||||
|
+ "g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed");
|
||||||
|
+ array = g_bytes_unref_to_array (g_steal_pointer (&bytes));
|
||||||
|
+ g_test_assert_expected_messages ();
|
||||||
|
+ g_assert_null (array);
|
||||||
|
+
|
||||||
|
+ g_free (data);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ g_test_skip ("Skipping test as testing undefined behaviour is disabled");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
test_to_array_two_refs (void)
|
||||||
|
{
|
||||||
|
@@ -410,6 +442,7 @@ main (int argc, char *argv[])
|
||||||
|
g_test_add_func ("/bytes/to-array/transfered", test_to_array_transferred);
|
||||||
|
g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
|
||||||
|
g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
|
||||||
|
+ g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
|
||||||
|
g_test_add_func ("/bytes/null", test_null);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
Backport of:
|
||||||
|
|
||||||
|
From 5e5f75a77e399c638be66d74e5daa8caeb433e00 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 13:30:52 +0000
|
||||||
|
Subject: [PATCH 01/11] gstrfuncs: Add internal g_memdup2() function
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This will replace the existing `g_memdup()` function for use within
|
||||||
|
GLib. It has an unavoidable security flaw of taking its `byte_size`
|
||||||
|
argument as a `guint` rather than as a `gsize`. Most callers will
|
||||||
|
expect it to be a `gsize`, and may pass in large values which could
|
||||||
|
silently be truncated, resulting in an undersize allocation compared
|
||||||
|
to what the caller expects.
|
||||||
|
|
||||||
|
This could lead to a classic buffer overflow vulnerability for many
|
||||||
|
callers of `g_memdup()`.
|
||||||
|
|
||||||
|
`g_memdup2()`, in comparison, takes its `byte_size` as a `gsize`.
|
||||||
|
|
||||||
|
Spotted by Kevin Backhouse of GHSL.
|
||||||
|
|
||||||
|
In GLib 2.68, `g_memdup2()` will be a new public API. In this version
|
||||||
|
for backport to older stable releases, it’s a new `static inline` API
|
||||||
|
in a private header, so that use of `g_memdup()` within GLib can be
|
||||||
|
fixed without adding a new API in a stable release series.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: GHSL-2021-045
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
docs/reference/glib/meson.build | 1 +
|
||||||
|
glib/gstrfuncsprivate.h | 55 +++++++++++++++++++++++++++++++++
|
||||||
|
glib/meson.build | 1 +
|
||||||
|
glib/tests/strfuncs.c | 23 ++++++++++++++
|
||||||
|
4 files changed, 80 insertions(+)
|
||||||
|
create mode 100644 glib/gstrfuncsprivate.h
|
||||||
|
|
||||||
|
diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build
|
||||||
|
index bba7649f0..ee39f6d04 100644
|
||||||
|
--- a/docs/reference/glib/meson.build
|
||||||
|
+++ b/docs/reference/glib/meson.build
|
||||||
|
@@ -22,6 +22,7 @@ if get_option('gtk_doc')
|
||||||
|
'gprintfint.h',
|
||||||
|
'gmirroringtable.h',
|
||||||
|
'gscripttable.h',
|
||||||
|
+ 'gstrfuncsprivate.h',
|
||||||
|
'glib-mirroring-tab',
|
||||||
|
'gnulib',
|
||||||
|
'pcre',
|
||||||
|
diff --git a/glib/gstrfuncsprivate.h b/glib/gstrfuncsprivate.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..85c88328a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/glib/gstrfuncsprivate.h
|
||||||
|
@@ -0,0 +1,55 @@
|
||||||
|
+/* GLIB - Library of useful routines for C programming
|
||||||
|
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||||
|
+ *
|
||||||
|
+ * This library is free software; you can redistribute it and/or
|
||||||
|
+ * modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ * License as published by the Free Software Foundation; either
|
||||||
|
+ * version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * This library is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ * Lesser General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <glib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * g_memdup2:
|
||||||
|
+ * @mem: (nullable): the memory to copy.
|
||||||
|
+ * @byte_size: the number of bytes to copy.
|
||||||
|
+ *
|
||||||
|
+ * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
|
||||||
|
+ * from @mem. If @mem is %NULL it returns %NULL.
|
||||||
|
+ *
|
||||||
|
+ * This replaces g_memdup(), which was prone to integer overflows when
|
||||||
|
+ * converting the argument from a #gsize to a #guint.
|
||||||
|
+ *
|
||||||
|
+ * This static inline version is a backport of the new public API from
|
||||||
|
+ * GLib 2.68, kept internal to GLib for backport to older stable releases.
|
||||||
|
+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319.
|
||||||
|
+ *
|
||||||
|
+ * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
|
||||||
|
+ * or %NULL if @mem is %NULL.
|
||||||
|
+ * Since: 2.68
|
||||||
|
+ */
|
||||||
|
+static inline gpointer
|
||||||
|
+g_memdup2 (gconstpointer mem,
|
||||||
|
+ gsize byte_size)
|
||||||
|
+{
|
||||||
|
+ gpointer new_mem;
|
||||||
|
+
|
||||||
|
+ if (mem && byte_size != 0)
|
||||||
|
+ {
|
||||||
|
+ new_mem = g_malloc (byte_size);
|
||||||
|
+ memcpy (new_mem, mem, byte_size);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ new_mem = NULL;
|
||||||
|
+
|
||||||
|
+ return new_mem;
|
||||||
|
+}
|
||||||
|
diff --git a/glib/meson.build b/glib/meson.build
|
||||||
|
index aaf5f00f5..5a6eea397 100644
|
||||||
|
--- a/glib/meson.build
|
||||||
|
+++ b/glib/meson.build
|
||||||
|
@@ -268,6 +268,7 @@ glib_sources = files(
|
||||||
|
'gslist.c',
|
||||||
|
'gstdio.c',
|
||||||
|
'gstrfuncs.c',
|
||||||
|
+ 'gstrfuncsprivate.h',
|
||||||
|
'gstring.c',
|
||||||
|
'gstringchunk.c',
|
||||||
|
'gtestutils.c',
|
||||||
|
diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c
|
||||||
|
index e1f9619c7..d968afff9 100644
|
||||||
|
--- a/glib/tests/strfuncs.c
|
||||||
|
+++ b/glib/tests/strfuncs.c
|
||||||
|
@@ -32,6 +32,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include "glib.h"
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
+
|
||||||
|
#if defined (_MSC_VER) && (_MSC_VER <= 1800)
|
||||||
|
#define isnan(x) _isnan(x)
|
||||||
|
|
||||||
|
@@ -219,6 +221,26 @@ test_memdup (void)
|
||||||
|
g_free (str_dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Testing g_memdup2() function with various positive and negative cases */
|
||||||
|
+static void
|
||||||
|
+test_memdup2 (void)
|
||||||
|
+{
|
||||||
|
+ gchar *str_dup = NULL;
|
||||||
|
+ const gchar *str = "The quick brown fox jumps over the lazy dog";
|
||||||
|
+
|
||||||
|
+ /* Testing negative cases */
|
||||||
|
+ g_assert_null (g_memdup2 (NULL, 1024));
|
||||||
|
+ g_assert_null (g_memdup2 (str, 0));
|
||||||
|
+ g_assert_null (g_memdup2 (NULL, 0));
|
||||||
|
+
|
||||||
|
+ /* Testing normal usage cases */
|
||||||
|
+ str_dup = g_memdup2 (str, strlen (str) + 1);
|
||||||
|
+ g_assert_nonnull (str_dup);
|
||||||
|
+ g_assert_cmpstr (str, ==, str_dup);
|
||||||
|
+
|
||||||
|
+ g_free (str_dup);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Testing g_strpcpy() function with various positive and negative cases */
|
||||||
|
static void
|
||||||
|
test_stpcpy (void)
|
||||||
|
@@ -2523,6 +2545,7 @@ main (int argc,
|
||||||
|
g_test_add_func ("/strfuncs/has-prefix", test_has_prefix);
|
||||||
|
g_test_add_func ("/strfuncs/has-suffix", test_has_suffix);
|
||||||
|
g_test_add_func ("/strfuncs/memdup", test_memdup);
|
||||||
|
+ g_test_add_func ("/strfuncs/memdup2", test_memdup2);
|
||||||
|
g_test_add_func ("/strfuncs/stpcpy", test_stpcpy);
|
||||||
|
g_test_add_func ("/strfuncs/str_match_string", test_str_match_string);
|
||||||
|
g_test_add_func ("/strfuncs/str_tokenize_and_fold", test_str_tokenize_and_fold);
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,264 @@
|
||||||
|
Backport of:
|
||||||
|
|
||||||
|
From be8834340a2d928ece82025463ae23dee2c333d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 13:37:56 +0000
|
||||||
|
Subject: [PATCH 02/11] gio: Use g_memdup2() instead of g_memdup() in obvious
|
||||||
|
places
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Convert all the call sites which use `g_memdup()`’s length argument
|
||||||
|
trivially (for example, by passing a `sizeof()`), so that they use
|
||||||
|
`g_memdup2()` instead.
|
||||||
|
|
||||||
|
In almost all of these cases the use of `g_memdup()` would not have
|
||||||
|
caused problems, but it will soon be deprecated, so best port away from
|
||||||
|
it.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
gio/gdbusconnection.c | 5 +++--
|
||||||
|
gio/gdbusinterfaceskeleton.c | 3 ++-
|
||||||
|
gio/gfile.c | 7 ++++---
|
||||||
|
gio/gsettingsschema.c | 5 +++--
|
||||||
|
gio/gwin32registrykey.c | 8 +++++---
|
||||||
|
gio/tests/async-close-output-stream.c | 6 ++++--
|
||||||
|
gio/tests/gdbus-export.c | 5 +++--
|
||||||
|
gio/win32/gwinhttpfile.c | 9 +++++----
|
||||||
|
8 files changed, 29 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||||
|
index f1f0921d4..d56453486 100644
|
||||||
|
--- a/gio/gdbusconnection.c
|
||||||
|
+++ b/gio/gdbusconnection.c
|
||||||
|
@@ -110,6 +110,7 @@
|
||||||
|
#include "gasyncinitable.h"
|
||||||
|
#include "giostream.h"
|
||||||
|
#include "gasyncresult.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtask.h"
|
||||||
|
#include "gmarshal-internal.h"
|
||||||
|
|
||||||
|
@@ -3997,7 +3998,7 @@ _g_dbus_interface_vtable_copy (const GDBusInterfaceVTable *vtable)
|
||||||
|
/* Don't waste memory by copying padding - remember to update this
|
||||||
|
* when changing struct _GDBusInterfaceVTable in gdbusconnection.h
|
||||||
|
*/
|
||||||
|
- return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
|
||||||
|
+ return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -4014,7 +4015,7 @@ _g_dbus_subtree_vtable_copy (const GDBusSubtreeVTable *vtable)
|
||||||
|
/* Don't waste memory by copying padding - remember to update this
|
||||||
|
* when changing struct _GDBusSubtreeVTable in gdbusconnection.h
|
||||||
|
*/
|
||||||
|
- return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
|
||||||
|
+ return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c
|
||||||
|
index 4a06516c1..4a4b719a5 100644
|
||||||
|
--- a/gio/gdbusinterfaceskeleton.c
|
||||||
|
+++ b/gio/gdbusinterfaceskeleton.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
#include "gdbusmethodinvocation.h"
|
||||||
|
#include "gdbusconnection.h"
|
||||||
|
#include "gmarshal-internal.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtask.h"
|
||||||
|
#include "gioerror.h"
|
||||||
|
|
||||||
|
@@ -701,7 +702,7 @@ add_connection_locked (GDBusInterfaceSkeleton *interface_,
|
||||||
|
* properly before building the hooked_vtable, so we create it
|
||||||
|
* once at the last minute.
|
||||||
|
*/
|
||||||
|
- interface_->priv->hooked_vtable = g_memdup (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
|
||||||
|
+ interface_->priv->hooked_vtable = g_memdup2 (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
|
||||||
|
interface_->priv->hooked_vtable->method_call = skeleton_intercept_handle_method_call;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/gio/gfile.c b/gio/gfile.c
|
||||||
|
index ba93f7c75..88b341e7d 100644
|
||||||
|
--- a/gio/gfile.c
|
||||||
|
+++ b/gio/gfile.c
|
||||||
|
@@ -60,6 +60,7 @@
|
||||||
|
#include "gasyncresult.h"
|
||||||
|
#include "gioerror.h"
|
||||||
|
#include "glibintl.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -7884,7 +7885,7 @@ measure_disk_usage_progress (gboolean reporting,
|
||||||
|
g_main_context_invoke_full (g_task_get_context (task),
|
||||||
|
g_task_get_priority (task),
|
||||||
|
measure_disk_usage_invoke_progress,
|
||||||
|
- g_memdup (&progress, sizeof progress),
|
||||||
|
+ g_memdup2 (&progress, sizeof progress),
|
||||||
|
g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -7902,7 +7903,7 @@ measure_disk_usage_thread (GTask *task,
|
||||||
|
data->progress_callback ? measure_disk_usage_progress : NULL, task,
|
||||||
|
&result.disk_usage, &result.num_dirs, &result.num_files,
|
||||||
|
&error))
|
||||||
|
- g_task_return_pointer (task, g_memdup (&result, sizeof result), g_free);
|
||||||
|
+ g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free);
|
||||||
|
else
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
}
|
||||||
|
@@ -7926,7 +7927,7 @@ g_file_real_measure_disk_usage_async (GFile *file,
|
||||||
|
|
||||||
|
task = g_task_new (file, cancellable, callback, user_data);
|
||||||
|
g_task_set_source_tag (task, g_file_real_measure_disk_usage_async);
|
||||||
|
- g_task_set_task_data (task, g_memdup (&data, sizeof data), g_free);
|
||||||
|
+ g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free);
|
||||||
|
g_task_set_priority (task, io_priority);
|
||||||
|
|
||||||
|
g_task_run_in_thread (task, measure_disk_usage_thread);
|
||||||
|
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
|
||||||
|
index 3a60b8c64..dded9b1ca 100644
|
||||||
|
--- a/gio/gsettingsschema.c
|
||||||
|
+++ b/gio/gsettingsschema.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
|
||||||
|
#include "gsettingsschema-internal.h"
|
||||||
|
#include "gsettings.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
#include "gvdb/gvdb-reader.h"
|
||||||
|
#include "strinfo.c"
|
||||||
|
@@ -1058,9 +1059,9 @@ g_settings_schema_list_children (GSettingsSchema *schema)
|
||||||
|
|
||||||
|
if (g_str_has_suffix (key, "/"))
|
||||||
|
{
|
||||||
|
- gint length = strlen (key);
|
||||||
|
+ gsize length = strlen (key);
|
||||||
|
|
||||||
|
- strv[j] = g_memdup (key, length);
|
||||||
|
+ strv[j] = g_memdup2 (key, length);
|
||||||
|
strv[j][length - 1] = '\0';
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c
|
||||||
|
index c19fede4e..619fd48af 100644
|
||||||
|
--- a/gio/gwin32registrykey.c
|
||||||
|
+++ b/gio/gwin32registrykey.c
|
||||||
|
@@ -28,6 +28,8 @@
|
||||||
|
#include <ntstatus.h>
|
||||||
|
#include <winternl.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
+
|
||||||
|
#ifndef _WDMDDK_
|
||||||
|
typedef enum _KEY_INFORMATION_CLASS {
|
||||||
|
KeyBasicInformation,
|
||||||
|
@@ -247,7 +249,7 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter)
|
||||||
|
new_iter->value_name_size = iter->value_name_size;
|
||||||
|
|
||||||
|
if (iter->value_data != NULL)
|
||||||
|
- new_iter->value_data = g_memdup (iter->value_data, iter->value_data_size);
|
||||||
|
+ new_iter->value_data = g_memdup2 (iter->value_data, iter->value_data_size);
|
||||||
|
|
||||||
|
new_iter->value_data_size = iter->value_data_size;
|
||||||
|
|
||||||
|
@@ -268,8 +270,8 @@ g_win32_registry_value_iter_copy (const GWin32RegistryValueIter *iter)
|
||||||
|
new_iter->value_data_expanded_charsize = iter->value_data_expanded_charsize;
|
||||||
|
|
||||||
|
if (iter->value_data_expanded_u8 != NULL)
|
||||||
|
- new_iter->value_data_expanded_u8 = g_memdup (iter->value_data_expanded_u8,
|
||||||
|
- iter->value_data_expanded_charsize);
|
||||||
|
+ new_iter->value_data_expanded_u8 = g_memdup2 (iter->value_data_expanded_u8,
|
||||||
|
+ iter->value_data_expanded_charsize);
|
||||||
|
|
||||||
|
new_iter->value_data_expanded_u8_size = iter->value_data_expanded_charsize;
|
||||||
|
|
||||||
|
diff --git a/gio/tests/async-close-output-stream.c b/gio/tests/async-close-output-stream.c
|
||||||
|
index 5f6620275..d3f97a119 100644
|
||||||
|
--- a/gio/tests/async-close-output-stream.c
|
||||||
|
+++ b/gio/tests/async-close-output-stream.c
|
||||||
|
@@ -24,6 +24,8 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
+
|
||||||
|
#define DATA_TO_WRITE "Hello world\n"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
@@ -147,9 +149,9 @@ prepare_data (SetupData *data,
|
||||||
|
|
||||||
|
data->expected_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream));
|
||||||
|
|
||||||
|
- g_assert_cmpint (data->expected_size, >, 0);
|
||||||
|
+ g_assert_cmpuint (data->expected_size, >, 0);
|
||||||
|
|
||||||
|
- data->expected_output = g_memdup (written, (guint)data->expected_size);
|
||||||
|
+ data->expected_output = g_memdup2 (written, data->expected_size);
|
||||||
|
|
||||||
|
/* then recreate the streams and prepare them for the asynchronous close */
|
||||||
|
destroy_streams (data);
|
||||||
|
diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c
|
||||||
|
index 506c7458a..5513306f8 100644
|
||||||
|
--- a/gio/tests/gdbus-export.c
|
||||||
|
+++ b/gio/tests/gdbus-export.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gdbus-tests.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
/* all tests rely on a shared mainloop */
|
||||||
|
static GMainLoop *loop = NULL;
|
||||||
|
@@ -671,7 +672,7 @@ subtree_introspect (GDBusConnection *connection,
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
- return g_memdup (interfaces, 2 * sizeof (void *));
|
||||||
|
+ return g_memdup2 (interfaces, 2 * sizeof (void *));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GDBusInterfaceVTable *
|
||||||
|
@@ -727,7 +728,7 @@ dynamic_subtree_introspect (GDBusConnection *connection,
|
||||||
|
{
|
||||||
|
const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL };
|
||||||
|
|
||||||
|
- return g_memdup (interfaces, 2 * sizeof (void *));
|
||||||
|
+ return g_memdup2 (interfaces, 2 * sizeof (void *));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GDBusInterfaceVTable *
|
||||||
|
diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
|
||||||
|
index cf5eed31d..040ee8564 100644
|
||||||
|
--- a/gio/win32/gwinhttpfile.c
|
||||||
|
+++ b/gio/win32/gwinhttpfile.c
|
||||||
|
@@ -29,6 +29,7 @@
|
||||||
|
#include "gio/gfile.h"
|
||||||
|
#include "gio/gfileattribute.h"
|
||||||
|
#include "gio/gfileinfo.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gwinhttpfile.h"
|
||||||
|
#include "gwinhttpfileinputstream.h"
|
||||||
|
#include "gwinhttpfileoutputstream.h"
|
||||||
|
@@ -393,10 +394,10 @@ g_winhttp_file_resolve_relative_path (GFile *file,
|
||||||
|
child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
|
||||||
|
child->vfs = winhttp_file->vfs;
|
||||||
|
child->url = winhttp_file->url;
|
||||||
|
- child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
|
||||||
|
- child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
|
||||||
|
- child->url.lpszUserName = g_memdup (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
|
||||||
|
- child->url.lpszPassword = g_memdup (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
|
||||||
|
+ child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
|
||||||
|
+ child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
|
||||||
|
+ child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
|
||||||
|
+ child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
|
||||||
|
child->url.lpszUrlPath = wnew_path;
|
||||||
|
child->url.dwUrlPathLength = wcslen (wnew_path);
|
||||||
|
child->url.lpszExtraInfo = NULL;
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
From 6110caea45b235420b98cd41d845cc92238f6781 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 13:39:25 +0000
|
||||||
|
Subject: [PATCH 03/11] gobject: Use g_memdup2() instead of g_memdup() in
|
||||||
|
obvious places
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Convert all the call sites which use `g_memdup()`’s length argument
|
||||||
|
trivially (for example, by passing a `sizeof()`), so that they use
|
||||||
|
`g_memdup2()` instead.
|
||||||
|
|
||||||
|
In almost all of these cases the use of `g_memdup()` would not have
|
||||||
|
caused problems, but it will soon be deprecated, so best port away from
|
||||||
|
it.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
gobject/gsignal.c | 3 ++-
|
||||||
|
gobject/gtype.c | 9 +++++----
|
||||||
|
gobject/gtypemodule.c | 3 ++-
|
||||||
|
gobject/tests/param.c | 4 +++-
|
||||||
|
4 files changed, 12 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
|
||||||
|
index 77d8f211e..41c54ab57 100644
|
||||||
|
--- a/gobject/gsignal.c
|
||||||
|
+++ b/gobject/gsignal.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "gsignal.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtype-private.h"
|
||||||
|
#include "gbsearcharray.h"
|
||||||
|
#include "gvaluecollector.h"
|
||||||
|
@@ -1730,7 +1731,7 @@ g_signal_newv (const gchar *signal_name,
|
||||||
|
node->single_va_closure_is_valid = FALSE;
|
||||||
|
node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
|
||||||
|
node->n_params = n_params;
|
||||||
|
- node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
|
||||||
|
+ node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params);
|
||||||
|
node->return_type = return_type;
|
||||||
|
node->class_closure_bsa = NULL;
|
||||||
|
if (accumulator)
|
||||||
|
diff --git a/gobject/gtype.c b/gobject/gtype.c
|
||||||
|
index 7d3789400..8441b90e9 100644
|
||||||
|
--- a/gobject/gtype.c
|
||||||
|
+++ b/gobject/gtype.c
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
|
||||||
|
#include "glib-private.h"
|
||||||
|
#include "gconstructor.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
@@ -1470,7 +1471,7 @@ type_add_interface_Wm (TypeNode *node,
|
||||||
|
iholder->next = iface_node_get_holders_L (iface);
|
||||||
|
iface_node_set_holders_W (iface, iholder);
|
||||||
|
iholder->instance_type = NODE_TYPE (node);
|
||||||
|
- iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
|
||||||
|
+ iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL;
|
||||||
|
iholder->plugin = plugin;
|
||||||
|
|
||||||
|
/* create an iface entry for this type */
|
||||||
|
@@ -1731,7 +1732,7 @@ type_iface_retrieve_holder_info_Wm (TypeNode *iface,
|
||||||
|
INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
|
||||||
|
|
||||||
|
check_interface_info_I (iface, instance_type, &tmp_info);
|
||||||
|
- iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
|
||||||
|
+ iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
return iholder; /* we don't modify write lock upon returning NULL */
|
||||||
|
@@ -2016,10 +2017,10 @@ type_iface_vtable_base_init_Wm (TypeNode *iface,
|
||||||
|
IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
|
||||||
|
|
||||||
|
if (pentry)
|
||||||
|
- vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);
|
||||||
|
+ vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size);
|
||||||
|
}
|
||||||
|
if (!vtable)
|
||||||
|
- vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
|
||||||
|
+ vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
|
||||||
|
entry->vtable = vtable;
|
||||||
|
vtable->g_type = NODE_TYPE (iface);
|
||||||
|
vtable->g_instance_type = NODE_TYPE (node);
|
||||||
|
diff --git a/gobject/gtypemodule.c b/gobject/gtypemodule.c
|
||||||
|
index 4ecaf8c88..20911fafd 100644
|
||||||
|
--- a/gobject/gtypemodule.c
|
||||||
|
+++ b/gobject/gtypemodule.c
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtypeplugin.h"
|
||||||
|
#include "gtypemodule.h"
|
||||||
|
|
||||||
|
@@ -436,7 +437,7 @@ g_type_module_register_type (GTypeModule *module,
|
||||||
|
module_type_info->loaded = TRUE;
|
||||||
|
module_type_info->info = *type_info;
|
||||||
|
if (type_info->value_table)
|
||||||
|
- module_type_info->info.value_table = g_memdup (type_info->value_table,
|
||||||
|
+ module_type_info->info.value_table = g_memdup2 (type_info->value_table,
|
||||||
|
sizeof (GTypeValueTable));
|
||||||
|
|
||||||
|
return module_type_info->type;
|
||||||
|
diff --git a/gobject/tests/param.c b/gobject/tests/param.c
|
||||||
|
index 758289bf8..971cff162 100644
|
||||||
|
--- a/gobject/tests/param.c
|
||||||
|
+++ b/gobject/tests/param.c
|
||||||
|
@@ -2,6 +2,8 @@
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
test_param_value (void)
|
||||||
|
{
|
||||||
|
@@ -851,7 +853,7 @@ main (int argc, char *argv[])
|
||||||
|
test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
|
||||||
|
data.change_this_flag, data.change_this_type,
|
||||||
|
data.use_this_flag, data.use_this_type);
|
||||||
|
- test_data = g_memdup (&data, sizeof (TestParamImplementData));
|
||||||
|
+ test_data = g_memdup2 (&data, sizeof (TestParamImplementData));
|
||||||
|
g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free);
|
||||||
|
g_free (test_path);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,308 @@
|
||||||
|
Backport of:
|
||||||
|
|
||||||
|
From 0736b7c1e7cf4232c5d7eb2b0fbfe9be81bd3baa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 13:41:21 +0000
|
||||||
|
Subject: [PATCH 04/11] glib: Use g_memdup2() instead of g_memdup() in obvious
|
||||||
|
places
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Convert all the call sites which use `g_memdup()`’s length argument
|
||||||
|
trivially (for example, by passing a `sizeof()` or an existing `gsize`
|
||||||
|
variable), so that they use `g_memdup2()` instead.
|
||||||
|
|
||||||
|
In almost all of these cases the use of `g_memdup()` would not have
|
||||||
|
caused problems, but it will soon be deprecated, so best port away from
|
||||||
|
it
|
||||||
|
|
||||||
|
In particular, this fixes an overflow within `g_bytes_new()`, identified
|
||||||
|
as GHSL-2021-045 by GHSL team member Kevin Backhouse.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Fixes: GHSL-2021-045
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
glib/gbytes.c | 6 ++++--
|
||||||
|
glib/gdir.c | 3 ++-
|
||||||
|
glib/ghash.c | 7 ++++---
|
||||||
|
glib/giochannel.c | 3 ++-
|
||||||
|
glib/gslice.c | 3 ++-
|
||||||
|
glib/gtestutils.c | 3 ++-
|
||||||
|
glib/gvariant.c | 7 ++++---
|
||||||
|
glib/gvarianttype.c | 3 ++-
|
||||||
|
glib/tests/array-test.c | 4 +++-
|
||||||
|
glib/tests/option-context.c | 6 ++++--
|
||||||
|
10 files changed, 29 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/glib/gbytes.c b/glib/gbytes.c
|
||||||
|
index d56abe6c3..dee494820 100644
|
||||||
|
--- a/glib/gbytes.c
|
||||||
|
+++ b/glib/gbytes.c
|
||||||
|
@@ -34,6 +34,8 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* GBytes:
|
||||||
|
*
|
||||||
|
@@ -95,7 +97,7 @@ g_bytes_new (gconstpointer data,
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (data != NULL || size == 0, NULL);
|
||||||
|
|
||||||
|
- return g_bytes_new_take (g_memdup (data, size), size);
|
||||||
|
+ return g_bytes_new_take (g_memdup2 (data, size), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -499,7 +501,7 @@ g_bytes_unref_to_data (GBytes *bytes,
|
||||||
|
* Copy: Non g_malloc (or compatible) allocator, or static memory,
|
||||||
|
* so we have to copy, and then unref.
|
||||||
|
*/
|
||||||
|
- result = g_memdup (bytes->data, bytes->size);
|
||||||
|
+ result = g_memdup2 (bytes->data, bytes->size);
|
||||||
|
*size = bytes->size;
|
||||||
|
g_bytes_unref (bytes);
|
||||||
|
}
|
||||||
|
diff --git a/glib/gdir.c b/glib/gdir.c
|
||||||
|
index 6b85e99c8..6747a8c6f 100644
|
||||||
|
--- a/glib/gdir.c
|
||||||
|
+++ b/glib/gdir.c
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
#include "gconvert.h"
|
||||||
|
#include "gfileutils.h"
|
||||||
|
#include "gstrfuncs.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtestutils.h"
|
||||||
|
#include "glibintl.h"
|
||||||
|
|
||||||
|
@@ -112,7 +113,7 @@ g_dir_open_with_errno (const gchar *path,
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- return g_memdup (&dir, sizeof dir);
|
||||||
|
+ return g_memdup2 (&dir, sizeof dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/glib/ghash.c b/glib/ghash.c
|
||||||
|
index e61b03788..26f26062b 100644
|
||||||
|
--- a/glib/ghash.c
|
||||||
|
+++ b/glib/ghash.c
|
||||||
|
@@ -34,6 +34,7 @@
|
||||||
|
#include "gmacros.h"
|
||||||
|
#include "glib-private.h"
|
||||||
|
#include "gstrfuncs.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gatomic.h"
|
||||||
|
#include "gtestutils.h"
|
||||||
|
#include "gslice.h"
|
||||||
|
@@ -964,7 +965,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer
|
||||||
|
if (hash_table->have_big_keys)
|
||||||
|
{
|
||||||
|
if (key != value)
|
||||||
|
- hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
|
||||||
|
+ hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
|
||||||
|
/* Keys and values are both big now, so no need for further checks */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -972,7 +973,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer
|
||||||
|
{
|
||||||
|
if (key != value)
|
||||||
|
{
|
||||||
|
- hash_table->values = g_memdup (hash_table->keys, sizeof (guint) * hash_table->size);
|
||||||
|
+ hash_table->values = g_memdup2 (hash_table->keys, sizeof (guint) * hash_table->size);
|
||||||
|
is_a_set = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1000,7 +1001,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer
|
||||||
|
|
||||||
|
/* Just split if necessary */
|
||||||
|
if (is_a_set && key != value)
|
||||||
|
- hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
|
||||||
|
+ hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
diff --git a/glib/giochannel.c b/glib/giochannel.c
|
||||||
|
index 1956e9dc6..15927c391 100644
|
||||||
|
--- a/glib/giochannel.c
|
||||||
|
+++ b/glib/giochannel.c
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
#include "giochannel.h"
|
||||||
|
|
||||||
|
#include "gstrfuncs.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtestutils.h"
|
||||||
|
#include "glibintl.h"
|
||||||
|
|
||||||
|
@@ -892,7 +893,7 @@ g_io_channel_set_line_term (GIOChannel *channel,
|
||||||
|
length = strlen (line_term);
|
||||||
|
|
||||||
|
g_free (channel->line_term);
|
||||||
|
- channel->line_term = line_term ? g_memdup (line_term, length) : NULL;
|
||||||
|
+ channel->line_term = line_term ? g_memdup2 (line_term, length) : NULL;
|
||||||
|
channel->line_term_len = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/glib/gslice.c b/glib/gslice.c
|
||||||
|
index 4c758c3be..bcdbb8853 100644
|
||||||
|
--- a/glib/gslice.c
|
||||||
|
+++ b/glib/gslice.c
|
||||||
|
@@ -41,6 +41,7 @@
|
||||||
|
#include "gmain.h"
|
||||||
|
#include "gmem.h" /* gslice.h */
|
||||||
|
#include "gstrfuncs.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gutils.h"
|
||||||
|
#include "gtrashstack.h"
|
||||||
|
#include "gtestutils.h"
|
||||||
|
@@ -350,7 +351,7 @@ g_slice_get_config_state (GSliceConfig ckey,
|
||||||
|
array[i++] = allocator->contention_counters[address];
|
||||||
|
array[i++] = allocator_get_magazine_threshold (allocator, address);
|
||||||
|
*n_values = i;
|
||||||
|
- return g_memdup (array, sizeof (array[0]) * *n_values);
|
||||||
|
+ return g_memdup2 (array, sizeof (array[0]) * *n_values);
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
diff --git a/glib/gtestutils.c b/glib/gtestutils.c
|
||||||
|
index dd789482f..5887ecc36 100644
|
||||||
|
--- a/glib/gtestutils.c
|
||||||
|
+++ b/glib/gtestutils.c
|
||||||
|
@@ -49,6 +49,7 @@
|
||||||
|
#include "gpattern.h"
|
||||||
|
#include "grand.h"
|
||||||
|
#include "gstrfuncs.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtimer.h"
|
||||||
|
#include "gslice.h"
|
||||||
|
#include "gspawn.h"
|
||||||
|
@@ -3798,7 +3799,7 @@ g_test_log_extract (GTestLogBuffer *tbuffer)
|
||||||
|
if (p <= tbuffer->data->str + mlength)
|
||||||
|
{
|
||||||
|
g_string_erase (tbuffer->data, 0, mlength);
|
||||||
|
- tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg)));
|
||||||
|
+ tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg)));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/glib/gvariant.c b/glib/gvariant.c
|
||||||
|
index b61bf7278..d6f68a9ea 100644
|
||||||
|
--- a/glib/gvariant.c
|
||||||
|
+++ b/glib/gvariant.c
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:gvariant
|
||||||
|
@@ -725,7 +726,7 @@ g_variant_new_variant (GVariant *value)
|
||||||
|
g_variant_ref_sink (value);
|
||||||
|
|
||||||
|
return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT,
|
||||||
|
- g_memdup (&value, sizeof value),
|
||||||
|
+ g_memdup2 (&value, sizeof value),
|
||||||
|
1, g_variant_is_trusted (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1229,7 +1230,7 @@ g_variant_new_fixed_array (const GVariantType *element_type,
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- data = g_memdup (elements, n_elements * element_size);
|
||||||
|
+ data = g_memdup2 (elements, n_elements * element_size);
|
||||||
|
value = g_variant_new_from_data (array_type, data,
|
||||||
|
n_elements * element_size,
|
||||||
|
FALSE, g_free, data);
|
||||||
|
@@ -1908,7 +1909,7 @@ g_variant_dup_bytestring (GVariant *value,
|
||||||
|
if (length)
|
||||||
|
*length = size;
|
||||||
|
|
||||||
|
- return g_memdup (original, size + 1);
|
||||||
|
+ return g_memdup2 (original, size + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/glib/gvarianttype.c b/glib/gvarianttype.c
|
||||||
|
index 1a228f73b..07659ff12 100644
|
||||||
|
--- a/glib/gvarianttype.c
|
||||||
|
+++ b/glib/gvarianttype.c
|
||||||
|
@@ -28,6 +28,7 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:gvarianttype
|
||||||
|
@@ -1181,7 +1182,7 @@ g_variant_type_new_tuple (const GVariantType * const *items,
|
||||||
|
g_assert (offset < sizeof buffer);
|
||||||
|
buffer[offset++] = ')';
|
||||||
|
|
||||||
|
- return (GVariantType *) g_memdup (buffer, offset);
|
||||||
|
+ return (GVariantType *) g_memdup2 (buffer, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
|
||||||
|
index 3fcf1136a..11982f822 100644
|
||||||
|
--- a/glib/tests/array-test.c
|
||||||
|
+++ b/glib/tests/array-test.c
|
||||||
|
@@ -29,6 +29,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include "glib.h"
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
+
|
||||||
|
/* Test data to be passed to any function which calls g_array_new(), providing
|
||||||
|
* the parameters for that call. Most #GArray tests should be repeated for all
|
||||||
|
* possible values of #ArrayTestData. */
|
||||||
|
@@ -1642,7 +1644,7 @@ byte_array_new_take (void)
|
||||||
|
GByteArray *gbarray;
|
||||||
|
guint8 *data;
|
||||||
|
|
||||||
|
- data = g_memdup ("woooweeewow", 11);
|
||||||
|
+ data = g_memdup2 ("woooweeewow", 11);
|
||||||
|
gbarray = g_byte_array_new_take (data, 11);
|
||||||
|
g_assert (gbarray->data == data);
|
||||||
|
g_assert_cmpuint (gbarray->len, ==, 11);
|
||||||
|
diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c
|
||||||
|
index 149d22353..88d2b80d1 100644
|
||||||
|
--- a/glib/tests/option-context.c
|
||||||
|
+++ b/glib/tests/option-context.c
|
||||||
|
@@ -27,6 +27,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
+
|
||||||
|
static GOptionEntry main_entries[] = {
|
||||||
|
{ "main-switch", 0, 0,
|
||||||
|
G_OPTION_ARG_NONE, NULL,
|
||||||
|
@@ -256,7 +258,7 @@ join_stringv (int argc, char **argv)
|
||||||
|
static char **
|
||||||
|
copy_stringv (char **argv, int argc)
|
||||||
|
{
|
||||||
|
- return g_memdup (argv, sizeof (char *) * (argc + 1));
|
||||||
|
+ return g_memdup2 (argv, sizeof (char *) * (argc + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -2323,7 +2325,7 @@ test_group_parse (void)
|
||||||
|
g_option_context_add_group (context, group);
|
||||||
|
|
||||||
|
argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc);
|
||||||
|
- orig_argv = g_memdup (argv, (argc + 1) * sizeof (char *));
|
||||||
|
+ orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *));
|
||||||
|
|
||||||
|
retval = g_option_context_parse (context, &argc, &argv, &error);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
From 0cbad673215ec8a049b7fe2ff44b0beed31b376e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 16:12:24 +0000
|
||||||
|
Subject: [PATCH 05/11] gwinhttpfile: Avoid arithmetic overflow when
|
||||||
|
calculating a size
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The members of `URL_COMPONENTS` (`winhttp_file->url`) are `DWORD`s, i.e.
|
||||||
|
32-bit unsigned integers. Adding to and multiplying them may cause them
|
||||||
|
to overflow the unsigned integer bounds, even if the result is passed to
|
||||||
|
`g_memdup2()` which accepts a `gsize`.
|
||||||
|
|
||||||
|
Cast the `URL_COMPONENTS` members to `gsize` first to ensure that the
|
||||||
|
arithmetic is done in terms of `gsize`s rather than unsigned integers.
|
||||||
|
|
||||||
|
Spotted by Sebastian Dröge.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
gio/win32/gwinhttpfile.c | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
|
||||||
|
index 040ee8564..246ec0578 100644
|
||||||
|
--- a/gio/win32/gwinhttpfile.c
|
||||||
|
+++ b/gio/win32/gwinhttpfile.c
|
||||||
|
@@ -394,10 +394,10 @@ g_winhttp_file_resolve_relative_path (GFile *file,
|
||||||
|
child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
|
||||||
|
child->vfs = winhttp_file->vfs;
|
||||||
|
child->url = winhttp_file->url;
|
||||||
|
- child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
|
||||||
|
- child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
|
||||||
|
- child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
|
||||||
|
- child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
|
||||||
|
+ child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, ((gsize) winhttp_file->url.dwSchemeLength + 1) * 2);
|
||||||
|
+ child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, ((gsize) winhttp_file->url.dwHostNameLength + 1) * 2);
|
||||||
|
+ child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, ((gsize) winhttp_file->url.dwUserNameLength + 1) * 2);
|
||||||
|
+ child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, ((gsize) winhttp_file->url.dwPasswordLength + 1) * 2);
|
||||||
|
child->url.lpszUrlPath = wnew_path;
|
||||||
|
child->url.dwUrlPathLength = wcslen (wnew_path);
|
||||||
|
child->url.lpszExtraInfo = NULL;
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
From f9ee2275cbc312c0b4cdbc338a4fbb76eb36fb9a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 13:49:00 +0000
|
||||||
|
Subject: [PATCH 06/11] gdatainputstream: Handle stop_chars_len internally as
|
||||||
|
gsize
|
||||||
|
|
||||||
|
Previously it was handled as a `gssize`, which meant that if the
|
||||||
|
`stop_chars` string was longer than `G_MAXSSIZE` there would be an
|
||||||
|
overflow.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
gio/gdatainputstream.c | 25 +++++++++++++++++--------
|
||||||
|
1 file changed, 17 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c
|
||||||
|
index 2e7750cb5..2cdcbda19 100644
|
||||||
|
--- a/gio/gdatainputstream.c
|
||||||
|
+++ b/gio/gdatainputstream.c
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
#include "gioenumtypes.h"
|
||||||
|
#include "gioerror.h"
|
||||||
|
#include "glibintl.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
@@ -856,7 +857,7 @@ static gssize
|
||||||
|
scan_for_chars (GDataInputStream *stream,
|
||||||
|
gsize *checked_out,
|
||||||
|
const char *stop_chars,
|
||||||
|
- gssize stop_chars_len)
|
||||||
|
+ gsize stop_chars_len)
|
||||||
|
{
|
||||||
|
GBufferedInputStream *bstream;
|
||||||
|
const char *buffer;
|
||||||
|
@@ -952,7 +953,7 @@ typedef struct
|
||||||
|
gsize checked;
|
||||||
|
|
||||||
|
gchar *stop_chars;
|
||||||
|
- gssize stop_chars_len;
|
||||||
|
+ gsize stop_chars_len;
|
||||||
|
gsize length;
|
||||||
|
} GDataInputStreamReadData;
|
||||||
|
|
||||||
|
@@ -1078,12 +1079,17 @@ g_data_input_stream_read_async (GDataInputStream *stream,
|
||||||
|
{
|
||||||
|
GDataInputStreamReadData *data;
|
||||||
|
GTask *task;
|
||||||
|
+ gsize stop_chars_len_unsigned;
|
||||||
|
|
||||||
|
data = g_slice_new0 (GDataInputStreamReadData);
|
||||||
|
- if (stop_chars_len == -1)
|
||||||
|
- stop_chars_len = strlen (stop_chars);
|
||||||
|
- data->stop_chars = g_memdup (stop_chars, stop_chars_len);
|
||||||
|
- data->stop_chars_len = stop_chars_len;
|
||||||
|
+
|
||||||
|
+ if (stop_chars_len < 0)
|
||||||
|
+ stop_chars_len_unsigned = strlen (stop_chars);
|
||||||
|
+ else
|
||||||
|
+ stop_chars_len_unsigned = (gsize) stop_chars_len;
|
||||||
|
+
|
||||||
|
+ data->stop_chars = g_memdup2 (stop_chars, stop_chars_len_unsigned);
|
||||||
|
+ data->stop_chars_len = stop_chars_len_unsigned;
|
||||||
|
data->last_saw_cr = FALSE;
|
||||||
|
|
||||||
|
task = g_task_new (stream, cancellable, callback, user_data);
|
||||||
|
@@ -1338,17 +1344,20 @@ g_data_input_stream_read_upto (GDataInputStream *stream,
|
||||||
|
gssize found_pos;
|
||||||
|
gssize res;
|
||||||
|
char *data_until;
|
||||||
|
+ gsize stop_chars_len_unsigned;
|
||||||
|
|
||||||
|
g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
|
||||||
|
|
||||||
|
if (stop_chars_len < 0)
|
||||||
|
- stop_chars_len = strlen (stop_chars);
|
||||||
|
+ stop_chars_len_unsigned = strlen (stop_chars);
|
||||||
|
+ else
|
||||||
|
+ stop_chars_len_unsigned = (gsize) stop_chars_len;
|
||||||
|
|
||||||
|
bstream = G_BUFFERED_INPUT_STREAM (stream);
|
||||||
|
|
||||||
|
checked = 0;
|
||||||
|
|
||||||
|
- while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len)) == -1)
|
||||||
|
+ while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len_unsigned)) == -1)
|
||||||
|
{
|
||||||
|
if (g_buffered_input_stream_get_available (bstream) ==
|
||||||
|
g_buffered_input_stream_get_buffer_size (bstream))
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
Backport of:
|
||||||
|
|
||||||
|
From 2aaf593a9eb96d84fe3be740aca2810a97d95592 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 13:50:37 +0000
|
||||||
|
Subject: [PATCH 07/11] gwin32: Use gsize internally in g_wcsdup()
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This allows it to handle strings up to length `G_MAXSIZE` — previously
|
||||||
|
it would overflow with such strings.
|
||||||
|
|
||||||
|
Update the several copies of it identically.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
gio/gwin32appinfo.c | 33 ++++++++++++++++++++++++++-------
|
||||||
|
gio/gwin32registrykey.c | 34 ++++++++++++++++++++++++++--------
|
||||||
|
2 files changed, 52 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/gio/gwin32appinfo.c b/gio/gwin32appinfo.c
|
||||||
|
index 9f335b370..dd7a96a4a 100644
|
||||||
|
--- a/gio/gwin32appinfo.c
|
||||||
|
+++ b/gio/gwin32appinfo.c
|
||||||
|
@@ -464,15 +464,34 @@ static GWin32RegistryKey *applications_key;
|
||||||
|
/* Watch this key */
|
||||||
|
static GWin32RegistryKey *classes_root_key;
|
||||||
|
|
||||||
|
+static gsize
|
||||||
|
+g_utf16_len (const gunichar2 *str)
|
||||||
|
+{
|
||||||
|
+ gsize result;
|
||||||
|
+
|
||||||
|
+ for (result = 0; str[0] != 0; str++, result++)
|
||||||
|
+ ;
|
||||||
|
+
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gunichar2 *
|
||||||
|
-g_wcsdup (const gunichar2 *str, gssize str_size)
|
||||||
|
+g_wcsdup (const gunichar2 *str, gssize str_len)
|
||||||
|
{
|
||||||
|
- if (str_size == -1)
|
||||||
|
- {
|
||||||
|
- str_size = wcslen (str) + 1;
|
||||||
|
- str_size *= sizeof (gunichar2);
|
||||||
|
- }
|
||||||
|
- return g_memdup (str, str_size);
|
||||||
|
+ gsize str_len_unsigned;
|
||||||
|
+ gsize str_size;
|
||||||
|
+
|
||||||
|
+ g_return_val_if_fail (str != NULL, NULL);
|
||||||
|
+
|
||||||
|
+ if (str_len < 0)
|
||||||
|
+ str_len_unsigned = g_utf16_len (str);
|
||||||
|
+ else
|
||||||
|
+ str_len_unsigned = (gsize) str_len;
|
||||||
|
+
|
||||||
|
+ g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1);
|
||||||
|
+ str_size = (str_len_unsigned + 1) * sizeof (gunichar2);
|
||||||
|
+
|
||||||
|
+ return g_memdup2 (str, str_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define URL_ASSOCIATIONS L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\"
|
||||||
|
diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c
|
||||||
|
index 619fd48af..fbd65311a 100644
|
||||||
|
--- a/gio/gwin32registrykey.c
|
||||||
|
+++ b/gio/gwin32registrykey.c
|
||||||
|
@@ -127,16 +127,34 @@ typedef enum
|
||||||
|
G_WIN32_REGISTRY_UPDATED_PATH = 1,
|
||||||
|
} GWin32RegistryKeyUpdateFlag;
|
||||||
|
|
||||||
|
+static gsize
|
||||||
|
+g_utf16_len (const gunichar2 *str)
|
||||||
|
+{
|
||||||
|
+ gsize result;
|
||||||
|
+
|
||||||
|
+ for (result = 0; str[0] != 0; str++, result++)
|
||||||
|
+ ;
|
||||||
|
+
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gunichar2 *
|
||||||
|
-g_wcsdup (const gunichar2 *str,
|
||||||
|
- gssize str_size)
|
||||||
|
+g_wcsdup (const gunichar2 *str, gssize str_len)
|
||||||
|
{
|
||||||
|
- if (str_size == -1)
|
||||||
|
- {
|
||||||
|
- str_size = wcslen (str) + 1;
|
||||||
|
- str_size *= sizeof (gunichar2);
|
||||||
|
- }
|
||||||
|
- return g_memdup (str, str_size);
|
||||||
|
+ gsize str_len_unsigned;
|
||||||
|
+ gsize str_size;
|
||||||
|
+
|
||||||
|
+ g_return_val_if_fail (str != NULL, NULL);
|
||||||
|
+
|
||||||
|
+ if (str_len < 0)
|
||||||
|
+ str_len_unsigned = g_utf16_len (str);
|
||||||
|
+ else
|
||||||
|
+ str_len_unsigned = (gsize) str_len;
|
||||||
|
+
|
||||||
|
+ g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1);
|
||||||
|
+ str_size = (str_len_unsigned + 1) * sizeof (gunichar2);
|
||||||
|
+
|
||||||
|
+ return g_memdup2 (str, str_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
From ba8ca443051f93a74c0d03d62e70402036f967a5 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/11] 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 cd5765afd..25b057672 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.30.1
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
From 65ec7f4d6e8832c481f6e00e2eb007b9a60024ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 14:00:53 +0000
|
||||||
|
Subject: [PATCH 09/11] gsocket: Use gsize to track native sockaddr's size
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Don’t use an `int`, that’s potentially too small. In practical terms,
|
||||||
|
this is not a problem, since no socket address is going to be that big.
|
||||||
|
|
||||||
|
By making these changes we can use `g_memdup2()` without warnings,
|
||||||
|
though. Fewer warnings is good.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
gio/gsocket.c | 16 ++++++++++------
|
||||||
|
1 file changed, 10 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/gio/gsocket.c b/gio/gsocket.c
|
||||||
|
index 66073af83..a3af149e8 100644
|
||||||
|
--- a/gio/gsocket.c
|
||||||
|
+++ b/gio/gsocket.c
|
||||||
|
@@ -75,6 +75,7 @@
|
||||||
|
#include "gcredentialsprivate.h"
|
||||||
|
#include "glibintl.h"
|
||||||
|
#include "gioprivate.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
/* For Windows XP runtime compatibility, but use the system's if_nametoindex() if available */
|
||||||
|
@@ -174,7 +175,7 @@ static gboolean g_socket_datagram_based_condition_wait (GDatagramBased
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
static GSocketAddress *
|
||||||
|
-cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len);
|
||||||
|
+cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len);
|
||||||
|
|
||||||
|
static gssize
|
||||||
|
g_socket_receive_message_with_timeout (GSocket *socket,
|
||||||
|
@@ -260,7 +261,7 @@ struct _GSocketPrivate
|
||||||
|
struct {
|
||||||
|
GSocketAddress *addr;
|
||||||
|
struct sockaddr *native;
|
||||||
|
- gint native_len;
|
||||||
|
+ gsize native_len;
|
||||||
|
guint64 last_used;
|
||||||
|
} recv_addr_cache[RECV_ADDR_CACHE_SIZE];
|
||||||
|
};
|
||||||
|
@@ -5211,14 +5212,14 @@ g_socket_send_messages_with_timeout (GSocket *socket,
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSocketAddress *
|
||||||
|
-cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len)
|
||||||
|
+cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len)
|
||||||
|
{
|
||||||
|
GSocketAddress *saddr;
|
||||||
|
gint i;
|
||||||
|
guint64 oldest_time = G_MAXUINT64;
|
||||||
|
gint oldest_index = 0;
|
||||||
|
|
||||||
|
- if (native_len <= 0)
|
||||||
|
+ if (native_len == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
saddr = NULL;
|
||||||
|
@@ -5226,7 +5227,7 @@ cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len)
|
||||||
|
{
|
||||||
|
GSocketAddress *tmp = socket->priv->recv_addr_cache[i].addr;
|
||||||
|
gpointer tmp_native = socket->priv->recv_addr_cache[i].native;
|
||||||
|
- gint tmp_native_len = socket->priv->recv_addr_cache[i].native_len;
|
||||||
|
+ gsize tmp_native_len = socket->priv->recv_addr_cache[i].native_len;
|
||||||
|
|
||||||
|
if (!tmp)
|
||||||
|
continue;
|
||||||
|
@@ -5256,7 +5257,7 @@ cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len)
|
||||||
|
g_free (socket->priv->recv_addr_cache[oldest_index].native);
|
||||||
|
}
|
||||||
|
|
||||||
|
- socket->priv->recv_addr_cache[oldest_index].native = g_memdup (native, native_len);
|
||||||
|
+ socket->priv->recv_addr_cache[oldest_index].native = g_memdup2 (native, native_len);
|
||||||
|
socket->priv->recv_addr_cache[oldest_index].native_len = native_len;
|
||||||
|
socket->priv->recv_addr_cache[oldest_index].addr = g_object_ref (saddr);
|
||||||
|
socket->priv->recv_addr_cache[oldest_index].last_used = g_get_monotonic_time ();
|
||||||
|
@@ -5404,6 +5405,9 @@ g_socket_receive_message_with_timeout (GSocket *socket,
|
||||||
|
/* do it */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
+ /* addrlen has to be of type int because that’s how WSARecvFrom() is defined */
|
||||||
|
+ G_STATIC_ASSERT (sizeof addr <= G_MAXINT);
|
||||||
|
+
|
||||||
|
addrlen = sizeof addr;
|
||||||
|
if (address)
|
||||||
|
result = WSARecvFrom (socket->priv->fd,
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
From 777b95a88f006d39d9fe6d3321db17e7b0d4b9a4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 14:07:39 +0000
|
||||||
|
Subject: [PATCH 10/11] gtlspassword: Forbid very long TLS passwords
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The public API `g_tls_password_set_value_full()` (and the vfunc it
|
||||||
|
invokes) can only accept a `gssize` length. Ensure that nul-terminated
|
||||||
|
strings passed to `g_tls_password_set_value()` can’t exceed that length.
|
||||||
|
Use `g_memdup2()` to avoid an overflow if they’re longer than
|
||||||
|
`G_MAXUINT` similarly.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
gio/gtlspassword.c | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c
|
||||||
|
index 1e437a7b6..dbcec41a8 100644
|
||||||
|
--- a/gio/gtlspassword.c
|
||||||
|
+++ b/gio/gtlspassword.c
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
#include "glibintl.h"
|
||||||
|
|
||||||
|
#include "gioenumtypes.h"
|
||||||
|
+#include "gstrfuncsprivate.h"
|
||||||
|
#include "gtlspassword.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
@@ -287,9 +288,14 @@ g_tls_password_set_value (GTlsPassword *password,
|
||||||
|
g_return_if_fail (G_IS_TLS_PASSWORD (password));
|
||||||
|
|
||||||
|
if (length < 0)
|
||||||
|
- length = strlen ((gchar *)value);
|
||||||
|
+ {
|
||||||
|
+ /* FIXME: g_tls_password_set_value_full() doesn’t support unsigned gsize */
|
||||||
|
+ gsize length_unsigned = strlen ((gchar *) value);
|
||||||
|
+ g_return_if_fail (length_unsigned > G_MAXSSIZE);
|
||||||
|
+ length = (gssize) length_unsigned;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- g_tls_password_set_value_full (password, g_memdup (value, length), length, g_free);
|
||||||
|
+ g_tls_password_set_value_full (password, g_memdup2 (value, (gsize) length), length, g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
From ecdf91400e9a538695a0895b95ad7e8abcdf1749 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Thu, 4 Feb 2021 14:09:40 +0000
|
||||||
|
Subject: [PATCH 11/11] giochannel: Forbid very long line terminator strings
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The public API `GIOChannel.line_term_len` is only a `guint`. Ensure that
|
||||||
|
nul-terminated strings passed to `g_io_channel_set_line_term()` can’t
|
||||||
|
exceed that length. Use `g_memdup2()` to avoid a warning (`g_memdup()`
|
||||||
|
is due to be deprecated), but not to avoid a bug, since it’s also
|
||||||
|
limited to `G_MAXUINT`.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Helps: #2319
|
||||||
|
---
|
||||||
|
glib/giochannel.c | 17 +++++++++++++----
|
||||||
|
1 file changed, 13 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/glib/giochannel.c b/glib/giochannel.c
|
||||||
|
index 15927c391..66c6591f0 100644
|
||||||
|
--- a/glib/giochannel.c
|
||||||
|
+++ b/glib/giochannel.c
|
||||||
|
@@ -884,16 +884,25 @@ g_io_channel_set_line_term (GIOChannel *channel,
|
||||||
|
const gchar *line_term,
|
||||||
|
gint length)
|
||||||
|
{
|
||||||
|
+ guint length_unsigned;
|
||||||
|
+
|
||||||
|
g_return_if_fail (channel != NULL);
|
||||||
|
g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
|
||||||
|
|
||||||
|
if (line_term == NULL)
|
||||||
|
- length = 0;
|
||||||
|
- else if (length < 0)
|
||||||
|
- length = strlen (line_term);
|
||||||
|
+ length_unsigned = 0;
|
||||||
|
+ else if (length >= 0)
|
||||||
|
+ length_unsigned = (guint) length;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* FIXME: We’re constrained by line_term_len being a guint here */
|
||||||
|
+ gsize length_size = strlen (line_term);
|
||||||
|
+ g_return_if_fail (length_size > G_MAXUINT);
|
||||||
|
+ length_unsigned = (guint) length_size;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
g_free (channel->line_term);
|
||||||
|
- channel->line_term = line_term ? g_memdup2 (line_term, length) : NULL;
|
||||||
|
+ channel->line_term = line_term ? g_memdup2 (line_term, length_unsigned) : NULL;
|
||||||
|
channel->line_term_len = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
From f8273b9aded135fe07094faebd527e43851aaf6e Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
|
||||||
|
Date: Sun, 7 Feb 2021 23:32:40 +0100
|
||||||
|
Subject: [PATCH 1/5] giochannel: Fix length_size bounds check
|
||||||
|
|
||||||
|
The inverted condition is an obvious error introduced by ecdf91400e9a.
|
||||||
|
|
||||||
|
Fixes https://gitlab.gnome.org/GNOME/glib/-/issues/2323
|
||||||
|
|
||||||
|
(cherry picked from commit a149bf2f9030168051942124536e303af8ba6176)
|
||||||
|
---
|
||||||
|
glib/giochannel.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/glib/giochannel.c b/glib/giochannel.c
|
||||||
|
index 66c6591f0..0d9d5f223 100644
|
||||||
|
--- a/glib/giochannel.c
|
||||||
|
+++ b/glib/giochannel.c
|
||||||
|
@@ -897,7 +897,7 @@ g_io_channel_set_line_term (GIOChannel *channel,
|
||||||
|
{
|
||||||
|
/* FIXME: We’re constrained by line_term_len being a guint here */
|
||||||
|
gsize length_size = strlen (line_term);
|
||||||
|
- g_return_if_fail (length_size > G_MAXUINT);
|
||||||
|
+ g_return_if_fail (length_size <= G_MAXUINT);
|
||||||
|
length_unsigned = (guint) length_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
From e069c50467712e6d607822afd6b6c15c2c343dff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon McVittie <smcv@collabora.com>
|
||||||
|
Date: Mon, 8 Feb 2021 10:34:50 +0000
|
||||||
|
Subject: [PATCH 2/5] giochannel: Don't store negative line_term_len in
|
||||||
|
GIOChannel struct
|
||||||
|
|
||||||
|
Adding test coverage indicated that this was another bug in 0cc11f74.
|
||||||
|
|
||||||
|
Fixes: 0cc11f74 "giochannel: Forbid very long line terminator strings"
|
||||||
|
Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2323
|
||||||
|
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||||
|
(cherry picked from commit 5dc8b0014c03e7491d93b90275ab442e888a9628)
|
||||||
|
---
|
||||||
|
glib/giochannel.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/glib/giochannel.c b/glib/giochannel.c
|
||||||
|
index 0d9d5f223..4c39b9dc0 100644
|
||||||
|
--- a/glib/giochannel.c
|
||||||
|
+++ b/glib/giochannel.c
|
||||||
|
@@ -903,7 +903,7 @@ g_io_channel_set_line_term (GIOChannel *channel,
|
||||||
|
|
||||||
|
g_free (channel->line_term);
|
||||||
|
channel->line_term = line_term ? g_memdup2 (line_term, length_unsigned) : NULL;
|
||||||
|
- channel->line_term_len = length;
|
||||||
|
+ channel->line_term_len = length_unsigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
From 4506d1859a863087598c8d122740bae25b65b099 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon McVittie <smcv@collabora.com>
|
||||||
|
Date: Mon, 8 Feb 2021 10:04:48 +0000
|
||||||
|
Subject: [PATCH 4/5] gtlspassword: Fix inverted assertion
|
||||||
|
|
||||||
|
The intention here was to assert that the length of the password fits
|
||||||
|
in a gssize. Passwords more than half the size of virtual memory are
|
||||||
|
probably excessive.
|
||||||
|
|
||||||
|
Fixes: a8b204ff "gtlspassword: Forbid very long TLS passwords"
|
||||||
|
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||||
|
(cherry picked from commit 61bb52ec42de1082bfb06ce1c737fc295bfe60b8)
|
||||||
|
---
|
||||||
|
gio/gtlspassword.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c
|
||||||
|
index dbcec41a8..bd86a6dfe 100644
|
||||||
|
--- a/gio/gtlspassword.c
|
||||||
|
+++ b/gio/gtlspassword.c
|
||||||
|
@@ -291,7 +291,7 @@ g_tls_password_set_value (GTlsPassword *password,
|
||||||
|
{
|
||||||
|
/* FIXME: g_tls_password_set_value_full() doesn’t support unsigned gsize */
|
||||||
|
gsize length_unsigned = strlen ((gchar *) value);
|
||||||
|
- g_return_if_fail (length_unsigned > G_MAXSSIZE);
|
||||||
|
+ g_return_if_fail (length_unsigned <= G_MAXSSIZE);
|
||||||
|
length = (gssize) length_unsigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
From 3d1550354c3c6a8491c39881752d51cb7515f2c2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon McVittie <smcv@collabora.com>
|
||||||
|
Date: Mon, 8 Feb 2021 10:22:39 +0000
|
||||||
|
Subject: [PATCH 5/5] tls-interaction: Add test coverage for various ways to
|
||||||
|
set the password
|
||||||
|
|
||||||
|
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||||
|
(cherry picked from commit df4501316ca3903072400504a5ea76498db19538)
|
||||||
|
---
|
||||||
|
gio/tests/tls-interaction.c | 55 +++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 55 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/gio/tests/tls-interaction.c b/gio/tests/tls-interaction.c
|
||||||
|
index 4f0737d7e..5661e8e0d 100644
|
||||||
|
--- a/gio/tests/tls-interaction.c
|
||||||
|
+++ b/gio/tests/tls-interaction.c
|
||||||
|
@@ -174,6 +174,38 @@ test_interaction_ask_password_finish_failure (GTlsInteraction *interaction,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+/* Return a copy of @str that is allocated in a silly way, to exercise
|
||||||
|
+ * custom free-functions. The returned pointer points to a copy of @str
|
||||||
|
+ * in a buffer of the form "BEFORE \0 str \0 AFTER". */
|
||||||
|
+static guchar *
|
||||||
|
+special_dup (const char *str)
|
||||||
|
+{
|
||||||
|
+ GString *buf = g_string_new ("BEFORE");
|
||||||
|
+ guchar *ret;
|
||||||
|
+
|
||||||
|
+ g_string_append_c (buf, '\0');
|
||||||
|
+ g_string_append (buf, str);
|
||||||
|
+ g_string_append_c (buf, '\0');
|
||||||
|
+ g_string_append (buf, "AFTER");
|
||||||
|
+ ret = (guchar *) g_string_free (buf, FALSE);
|
||||||
|
+ return ret + strlen ("BEFORE") + 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* Free a copy of @str that was made with special_dup(), after asserting
|
||||||
|
+ * that it has not been corrupted. */
|
||||||
|
+static void
|
||||||
|
+special_free (gpointer p)
|
||||||
|
+{
|
||||||
|
+ gchar *s = p;
|
||||||
|
+ gchar *buf = s - strlen ("BEFORE") - 1;
|
||||||
|
+
|
||||||
|
+ g_assert_cmpstr (buf, ==, "BEFORE");
|
||||||
|
+ g_assert_cmpstr (s + strlen (s) + 1, ==, "AFTER");
|
||||||
|
+ g_free (buf);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static GTlsInteractionResult
|
||||||
|
test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
|
||||||
|
GTlsPassword *password,
|
||||||
|
@@ -181,6 +213,8 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
TestInteraction *self;
|
||||||
|
+ const guchar *value;
|
||||||
|
+ gsize len;
|
||||||
|
|
||||||
|
g_assert (TEST_IS_INTERACTION (interaction));
|
||||||
|
self = TEST_INTERACTION (interaction);
|
||||||
|
@@ -192,6 +226,27 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
|
||||||
|
g_assert (error != NULL);
|
||||||
|
g_assert (*error == NULL);
|
||||||
|
|
||||||
|
+ /* Exercise different ways to set the value */
|
||||||
|
+ g_tls_password_set_value (password, (const guchar *) "foo", 4);
|
||||||
|
+ len = 0;
|
||||||
|
+ value = g_tls_password_get_value (password, &len);
|
||||||
|
+ g_assert_cmpmem (value, len, "foo", 4);
|
||||||
|
+
|
||||||
|
+ g_tls_password_set_value (password, (const guchar *) "bar", -1);
|
||||||
|
+ len = 0;
|
||||||
|
+ value = g_tls_password_get_value (password, &len);
|
||||||
|
+ g_assert_cmpmem (value, len, "bar", 3);
|
||||||
|
+
|
||||||
|
+ g_tls_password_set_value_full (password, special_dup ("baa"), 4, special_free);
|
||||||
|
+ len = 0;
|
||||||
|
+ value = g_tls_password_get_value (password, &len);
|
||||||
|
+ g_assert_cmpmem (value, len, "baa", 4);
|
||||||
|
+
|
||||||
|
+ g_tls_password_set_value_full (password, special_dup ("baz"), -1, special_free);
|
||||||
|
+ len = 0;
|
||||||
|
+ value = g_tls_password_get_value (password, &len);
|
||||||
|
+ g_assert_cmpmem (value, len, "baz", 3);
|
||||||
|
+
|
||||||
|
/* Don't do this in real life. Include a null terminator for testing */
|
||||||
|
g_tls_password_set_value (password, (const guchar *)"the password", 13);
|
||||||
|
return G_TLS_INTERACTION_HANDLED;
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
From cb9ee701ef46c1819eed4e2a4dc181682bdfc176 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Wed, 10 Feb 2021 21:16:39 +0000
|
||||||
|
Subject: [PATCH 1/3] gkeyfilesettingsbackend: Fix basename handling when group
|
||||||
|
is unset
|
||||||
|
|
||||||
|
Fix an effective regression in commit
|
||||||
|
7781a9cbd2fd0aa84bee0f4eee88470640ff6706, which happens when
|
||||||
|
`convert_path()` is called with a `key` which contains no slashes. In
|
||||||
|
that case, the `key` is entirely the `basename`.
|
||||||
|
|
||||||
|
Prior to commit 7781a9cb, the code worked through a fluke of `i == -1`
|
||||||
|
cancelling out with the various additions in the `g_memdup()` call, and
|
||||||
|
effectively resulting in `g_strdup (key)`.
|
||||||
|
|
||||||
|
Spotted by Guido Berhoerster.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
---
|
||||||
|
gio/gkeyfilesettingsbackend.c | 7 ++++++-
|
||||||
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
|
||||||
|
index 25b057672..861c3a661 100644
|
||||||
|
--- a/gio/gkeyfilesettingsbackend.c
|
||||||
|
+++ b/gio/gkeyfilesettingsbackend.c
|
||||||
|
@@ -185,7 +185,12 @@ convert_path (GKeyfileSettingsBackend *kfsb,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basename)
|
||||||
|
- *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
|
||||||
|
+ {
|
||||||
|
+ if (last_slash != NULL)
|
||||||
|
+ *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
|
||||||
|
+ else
|
||||||
|
+ *basename = g_strdup (key);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
From 31e0d403ba635dbbacbfbff74295e5db02558d76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Wed, 10 Feb 2021 21:19:30 +0000
|
||||||
|
Subject: [PATCH 2/3] gkeyfilesettingsbackend: Disallow empty key or group
|
||||||
|
names
|
||||||
|
|
||||||
|
These should never have been allowed; they will result in precondition
|
||||||
|
failures from the `GKeyFile` later on in the code.
|
||||||
|
|
||||||
|
A test will be added for this shortly.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
---
|
||||||
|
gio/gkeyfilesettingsbackend.c | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
|
||||||
|
index 861c3a661..de216e615 100644
|
||||||
|
--- a/gio/gkeyfilesettingsbackend.c
|
||||||
|
+++ b/gio/gkeyfilesettingsbackend.c
|
||||||
|
@@ -158,6 +158,13 @@ convert_path (GKeyfileSettingsBackend *kfsb,
|
||||||
|
|
||||||
|
last_slash = strrchr (key, '/');
|
||||||
|
|
||||||
|
+ /* Disallow empty group names or key names */
|
||||||
|
+ if (key_len == 0 ||
|
||||||
|
+ (last_slash != NULL &&
|
||||||
|
+ (*(last_slash + 1) == '\0' ||
|
||||||
|
+ last_slash == key)))
|
||||||
|
+ return FALSE;
|
||||||
|
+
|
||||||
|
if (kfsb->root_group)
|
||||||
|
{
|
||||||
|
/* if a root_group was specified, make sure the user hasn't given
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,232 @@
|
||||||
|
Backport of:
|
||||||
|
|
||||||
|
From 221c26685354dea2b2732df94404e8e5e77a1591 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
Date: Wed, 10 Feb 2021 21:21:36 +0000
|
||||||
|
Subject: [PATCH 3/3] tests: Add tests for key name handling in the keyfile
|
||||||
|
backend
|
||||||
|
|
||||||
|
This tests the two recent commits.
|
||||||
|
|
||||||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
||||||
|
---
|
||||||
|
gio/tests/gsettings.c | 171 +++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 170 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
|
||||||
|
index baadca8f5..afe594a23 100644
|
||||||
|
--- a/gio/tests/gsettings.c
|
||||||
|
+++ b/gio/tests/gsettings.c
|
||||||
|
@@ -1,3 +1,4 @@
|
||||||
|
+#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
@@ -1740,6 +1741,14 @@ key_changed_cb (GSettings *settings, const gchar *key, gpointer data)
|
||||||
|
(*b) = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+typedef struct
|
||||||
|
+{
|
||||||
|
+ const gchar *path;
|
||||||
|
+ const gchar *root_group;
|
||||||
|
+ const gchar *keyfile_group;
|
||||||
|
+ const gchar *root_path;
|
||||||
|
+} KeyfileTestData;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Test that using a keyfile works
|
||||||
|
*/
|
||||||
|
@@ -1834,7 +1843,11 @@ test_keyfile (Fixture *fixture,
|
||||||
|
g_free (str);
|
||||||
|
|
||||||
|
g_settings_set (settings, "farewell", "s", "cheerio");
|
||||||
|
-
|
||||||
|
+
|
||||||
|
+ /* Check that empty keys/groups are not allowed. */
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, ""));
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, "/"));
|
||||||
|
+
|
||||||
|
/* When executing as root, changing the mode of the keyfile will have
|
||||||
|
* no effect on the writability of the settings.
|
||||||
|
*/
|
||||||
|
@@ -1866,6 +1879,149 @@ test_keyfile (Fixture *fixture,
|
||||||
|
g_free (keyfile_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Test that using a keyfile works with a schema with no path set.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+test_keyfile_no_path (Fixture *fixture,
|
||||||
|
+ gconstpointer user_data)
|
||||||
|
+{
|
||||||
|
+ const KeyfileTestData *test_data = user_data;
|
||||||
|
+ GSettingsBackend *kf_backend;
|
||||||
|
+ GSettings *settings;
|
||||||
|
+ GKeyFile *keyfile;
|
||||||
|
+ gboolean writable;
|
||||||
|
+ gchar *key = NULL;
|
||||||
|
+ GError *error = NULL;
|
||||||
|
+ gchar *keyfile_path = NULL, *store_path = NULL;
|
||||||
|
+
|
||||||
|
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
|
||||||
|
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
|
||||||
|
+ kf_backend = g_keyfile_settings_backend_new (store_path, test_data->root_path, test_data->root_group);
|
||||||
|
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, test_data->path);
|
||||||
|
+ g_object_unref (kf_backend);
|
||||||
|
+
|
||||||
|
+ g_settings_reset (settings, "test-boolean");
|
||||||
|
+ g_assert_true (g_settings_get_boolean (settings, "test-boolean"));
|
||||||
|
+
|
||||||
|
+ writable = g_settings_is_writable (settings, "test-boolean");
|
||||||
|
+ g_assert_true (writable);
|
||||||
|
+ g_settings_set (settings, "test-boolean", "b", FALSE);
|
||||||
|
+
|
||||||
|
+ g_assert_false (g_settings_get_boolean (settings, "test-boolean"));
|
||||||
|
+
|
||||||
|
+ g_settings_delay (settings);
|
||||||
|
+ g_settings_set (settings, "test-boolean", "b", TRUE);
|
||||||
|
+ g_settings_apply (settings);
|
||||||
|
+
|
||||||
|
+ keyfile = g_key_file_new ();
|
||||||
|
+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
|
||||||
|
+
|
||||||
|
+ g_assert_true (g_key_file_get_boolean (keyfile, test_data->keyfile_group, "test-boolean", NULL));
|
||||||
|
+
|
||||||
|
+ g_key_file_free (keyfile);
|
||||||
|
+
|
||||||
|
+ g_settings_reset (settings, "test-boolean");
|
||||||
|
+ g_settings_apply (settings);
|
||||||
|
+ keyfile = g_key_file_new ();
|
||||||
|
+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
|
||||||
|
+
|
||||||
|
+ g_assert_false (g_key_file_get_string (keyfile, test_data->keyfile_group, "test-boolean", &error));
|
||||||
|
+ g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
|
||||||
|
+ g_clear_error (&error);
|
||||||
|
+
|
||||||
|
+ /* Check that empty keys/groups are not allowed. */
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, ""));
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, "/"));
|
||||||
|
+
|
||||||
|
+ /* Keys which ghost the root group name are not allowed. This can only be
|
||||||
|
+ * tested when the path is `/` as otherwise it acts as a prefix and prevents
|
||||||
|
+ * any ghosting. */
|
||||||
|
+ if (g_str_equal (test_data->path, "/"))
|
||||||
|
+ {
|
||||||
|
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "");
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, key));
|
||||||
|
+ g_free (key);
|
||||||
|
+
|
||||||
|
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "/");
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, key));
|
||||||
|
+ g_free (key);
|
||||||
|
+
|
||||||
|
+ key = g_strdup_printf ("%s/%s", test_data->root_group, "test-boolean");
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, key));
|
||||||
|
+ g_free (key);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ g_key_file_free (keyfile);
|
||||||
|
+ g_object_unref (settings);
|
||||||
|
+
|
||||||
|
+ /* Clean up the temporary directory. */
|
||||||
|
+ g_assert_cmpint (g_chmod (keyfile_path, 0777) == 0 ? 0 : errno, ==, 0);
|
||||||
|
+ g_assert_cmpint (g_remove (store_path) == 0 ? 0 : errno, ==, 0);
|
||||||
|
+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
|
||||||
|
+ g_free (store_path);
|
||||||
|
+ g_free (keyfile_path);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Test that a keyfile rejects writes to keys outside its root path.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+test_keyfile_outside_root_path (Fixture *fixture,
|
||||||
|
+ gconstpointer user_data)
|
||||||
|
+{
|
||||||
|
+ GSettingsBackend *kf_backend;
|
||||||
|
+ GSettings *settings;
|
||||||
|
+ gchar *keyfile_path = NULL, *store_path = NULL;
|
||||||
|
+
|
||||||
|
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
|
||||||
|
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
|
||||||
|
+ kf_backend = g_keyfile_settings_backend_new (store_path, "/tests/basic-types/", "root");
|
||||||
|
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/tests/");
|
||||||
|
+ g_object_unref (kf_backend);
|
||||||
|
+
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
|
||||||
|
+
|
||||||
|
+ g_object_unref (settings);
|
||||||
|
+
|
||||||
|
+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
|
||||||
|
+ * don’t error on failure. */
|
||||||
|
+ g_remove (store_path);
|
||||||
|
+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
|
||||||
|
+ g_free (store_path);
|
||||||
|
+ g_free (keyfile_path);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Test that a keyfile rejects writes to keys in the root if no root group is set.
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+test_keyfile_no_root_group (Fixture *fixture,
|
||||||
|
+ gconstpointer user_data)
|
||||||
|
+{
|
||||||
|
+ GSettingsBackend *kf_backend;
|
||||||
|
+ GSettings *settings;
|
||||||
|
+ gchar *keyfile_path = NULL, *store_path = NULL;
|
||||||
|
+
|
||||||
|
+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
|
||||||
|
+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
|
||||||
|
+ kf_backend = g_keyfile_settings_backend_new (store_path, "/", NULL);
|
||||||
|
+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/");
|
||||||
|
+ g_object_unref (kf_backend);
|
||||||
|
+
|
||||||
|
+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
|
||||||
|
+ g_assert_true (g_settings_is_writable (settings, "child/test-boolean"));
|
||||||
|
+
|
||||||
|
+ g_object_unref (settings);
|
||||||
|
+
|
||||||
|
+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
|
||||||
|
+ * don’t error on failure. */
|
||||||
|
+ g_remove (store_path);
|
||||||
|
+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
|
||||||
|
+ g_free (store_path);
|
||||||
|
+ g_free (keyfile_path);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Test that getting child schemas works
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
@@ -2844,6 +3000,14 @@ main (int argc, char *argv[])
|
||||||
|
gchar *override_text;
|
||||||
|
gchar *enums;
|
||||||
|
gint result;
|
||||||
|
+ const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/", "root", "tests", "/" };
|
||||||
|
+ const KeyfileTestData keyfile_test_data_empty_path = { "/", "root", "root", "/" };
|
||||||
|
+ const KeyfileTestData keyfile_test_data_long_path = {
|
||||||
|
+ "/tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch/",
|
||||||
|
+ "root",
|
||||||
|
+ "tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch",
|
||||||
|
+ "/"
|
||||||
|
+ };
|
||||||
|
|
||||||
|
/* Meson build sets this */
|
||||||
|
#ifdef TEST_LOCALE_PATH
|
||||||
|
@@ -2967,6 +3131,11 @@ main (int argc, char *argv[])
|
||||||
|
}
|
||||||
|
|
||||||
|
g_test_add ("/gsettings/keyfile", Fixture, NULL, setup, test_keyfile, teardown);
|
||||||
|
+ g_test_add ("/gsettings/keyfile/explicit-path", Fixture, &keyfile_test_data_explicit_path, setup, test_keyfile_no_path, teardown);
|
||||||
|
+ g_test_add ("/gsettings/keyfile/empty-path", Fixture, &keyfile_test_data_empty_path, setup, test_keyfile_no_path, teardown);
|
||||||
|
+ g_test_add ("/gsettings/keyfile/long-path", Fixture, &keyfile_test_data_long_path, setup, test_keyfile_no_path, teardown);
|
||||||
|
+ g_test_add ("/gsettings/keyfile/outside-root-path", Fixture, NULL, setup, test_keyfile_outside_root_path, teardown);
|
||||||
|
+ g_test_add ("/gsettings/keyfile/no-root-group", Fixture, NULL, setup, test_keyfile_no_root_group, teardown);
|
||||||
|
g_test_add_func ("/gsettings/child-schema", test_child_schema);
|
||||||
|
g_test_add_func ("/gsettings/strinfo", test_strinfo);
|
||||||
|
g_test_add_func ("/gsettings/enums", test_enums);
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
Reference in New Issue