summary refs log tree commit diff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/abseil-cpp-fix-gtest.patch16
-rw-r--r--gnu/packages/patches/abseil-cpp-fix-strerror_test.patch42
-rw-r--r--gnu/packages/patches/aws-c-cal-cmake-prefix.patch13
-rw-r--r--gnu/packages/patches/aws-c-io-cmake-prefix.patch13
-rw-r--r--gnu/packages/patches/aws-c-io-disable-networking-tests.patch81
-rw-r--r--gnu/packages/patches/bsdiff-CVE-2014-9862.patch15
-rw-r--r--gnu/packages/patches/busybox-CVE-2021-28831.patch57
-rw-r--r--gnu/packages/patches/cairo-CVE-2018-19876.patch37
-rw-r--r--gnu/packages/patches/cairo-CVE-2020-35492.patch49
-rw-r--r--gnu/packages/patches/cyrus-sasl-CVE-2019-19906.patch25
-rw-r--r--gnu/packages/patches/efibootmgr-remove-extra-decl.patch27
-rw-r--r--gnu/packages/patches/evolution-CVE-2020-11879.patch122
-rw-r--r--gnu/packages/patches/evolution-data-server-CVE-2020-14928.patch115
-rw-r--r--gnu/packages/patches/evolution-data-server-CVE-2020-16117.patch28
-rw-r--r--gnu/packages/patches/gdk-pixbuf-CVE-2020-29385.patch53
-rw-r--r--gnu/packages/patches/geary-CVE-2020-24661.patch133
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27218.patch132
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-01.patch176
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-02.patch264
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-03.patch136
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-04.patch308
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-05.patch47
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-06.patch94
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-07.patch118
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-08.patch94
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-09.patch98
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-10.patch52
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-11.patch57
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-12.patch30
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-13.patch32
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-14.patch32
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-15.patch95
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-16.patch43
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-17.patch37
-rw-r--r--gnu/packages/patches/glib-CVE-2021-27219-18.patch232
-rw-r--r--gnu/packages/patches/glib-CVE-2021-28153.patch283
-rw-r--r--gnu/packages/patches/glibc-ldd-powerpc.patch10
-rw-r--r--gnu/packages/patches/gnome-shell-CVE-2020-17489.patch46
-rw-r--r--gnu/packages/patches/gnutls-CVE-2021-20231.patch62
-rw-r--r--gnu/packages/patches/gnutls-CVE-2021-20232.patch60
-rw-r--r--gnu/packages/patches/hplip-remove-imageprocessor.patch41
-rw-r--r--gnu/packages/patches/libcaca-CVE-2021-3410-pt1.patch137
-rw-r--r--gnu/packages/patches/libcaca-CVE-2021-3410-pt2.patch96
-rw-r--r--gnu/packages/patches/libcroco-CVE-2020-12825.patch187
-rw-r--r--gnu/packages/patches/mongodb-support-unknown-linux-distributions.patch55
-rw-r--r--gnu/packages/patches/mpg321-CVE-2019-14247.patch23
-rw-r--r--gnu/packages/patches/ppsspp-disable-upgrade-and-gold.patch113
-rw-r--r--gnu/packages/patches/python-shouldbe-0.1.2-cpy3.8.patch82
-rw-r--r--gnu/packages/patches/qemu-build-info-manual.patch201
-rw-r--r--gnu/packages/patches/sdcc-disable-non-free-code.patch257
-rw-r--r--gnu/packages/patches/ungoogled-chromium-system-opus.patch27
-rw-r--r--gnu/packages/patches/unzip-32bit-zipbomb-fix.patch50
-rw-r--r--gnu/packages/patches/unzip-COVSCAN-fix-unterminated-string.patch131
-rw-r--r--gnu/packages/patches/unzip-CVE-2016-9844.patch39
-rw-r--r--gnu/packages/patches/unzip-CVE-2018-1000035.patch34
-rw-r--r--gnu/packages/patches/unzip-CVE-2018-18384.patch35
-rw-r--r--gnu/packages/patches/unzip-alt-iconv-utf8-print.patch381
-rw-r--r--gnu/packages/patches/unzip-alt-iconv-utf8.patch398
-rw-r--r--gnu/packages/patches/unzip-case-insensitive.patch131
-rw-r--r--gnu/packages/patches/unzip-close.patch176
-rw-r--r--gnu/packages/patches/unzip-exec-shield.patch10
-rw-r--r--gnu/packages/patches/unzip-fix-recmatch.patch477
-rw-r--r--gnu/packages/patches/unzip-manpage-fix.patch11
-rw-r--r--gnu/packages/patches/unzip-overflow.patch25
-rw-r--r--gnu/packages/patches/unzip-timestamp.patch41
-rw-r--r--gnu/packages/patches/unzip-valgrind.patch26
-rw-r--r--gnu/packages/patches/unzip-x-option.patch28
-rw-r--r--gnu/packages/patches/unzip-zipbomb-manpage.patch25
-rw-r--r--gnu/packages/patches/unzip-zipbomb-part1.patch25
-rw-r--r--gnu/packages/patches/unzip-zipbomb-part2.patch349
-rw-r--r--gnu/packages/patches/unzip-zipbomb-part3.patch112
-rw-r--r--gnu/packages/patches/vtk-fix-freetypetools-build-failure.patch36
-rw-r--r--gnu/packages/patches/ytnef-CVE-2021-3403.patch32
-rw-r--r--gnu/packages/patches/ytnef-CVE-2021-3404.patch30
74 files changed, 6742 insertions, 443 deletions
diff --git a/gnu/packages/patches/abseil-cpp-fix-gtest.patch b/gnu/packages/patches/abseil-cpp-fix-gtest.patch
new file mode 100644
index 0000000000..38971448f3
--- /dev/null
+++ b/gnu/packages/patches/abseil-cpp-fix-gtest.patch
@@ -0,0 +1,16 @@
+The GTEST_ALLOW_UNINSTANTIATED_PARAMTERIZED_TEST macro was added to googletest
+in commit 0b024bd9 on master. It has been used in an abseil-cpp release before
+a googletest release.
+
+--- a/absl/container/internal/unordered_map_modifiers_test.h
++++ b/absl/container/internal/unordered_map_modifiers_test.h
+@@ -286,7 +286,9 @@ class UniquePtrModifiersTest : public ::testing::Test {
+   }
+ };
+
++#ifdef GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST
+ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UniquePtrModifiersTest);
++#endif
+
+ TYPED_TEST_SUITE_P(UniquePtrModifiersTest);
+
diff --git a/gnu/packages/patches/abseil-cpp-fix-strerror_test.patch b/gnu/packages/patches/abseil-cpp-fix-strerror_test.patch
new file mode 100644
index 0000000000..726149b015
--- /dev/null
+++ b/gnu/packages/patches/abseil-cpp-fix-strerror_test.patch
@@ -0,0 +1,42 @@
+From e2b1bab19a782cb62bb010d1c2925ab7314fb113 Mon Sep 17 00:00:00 2001
+diff --git a/absl/base/internal/strerror.cc b/absl/base/internal/strerror.cc
+index d66ba120..0d6226fd 100644
+--- a/absl/base/internal/strerror.cc
++++ b/absl/base/internal/strerror.cc
+@@ -51,7 +51,6 @@ const char* StrErrorAdaptor(int errnum, char* buf, size_t buflen) {
+ }
+ 
+ std::string StrErrorInternal(int errnum) {
+-  absl::base_internal::ErrnoSaver errno_saver;
+   char buf[100];
+   const char* str = StrErrorAdaptor(errnum, buf, sizeof buf);
+   if (*str == '\0') {
+@@ -76,6 +75,7 @@ std::array<std::string, kSysNerr>* NewStrErrorTable() {
+ }  // namespace
+ 
+ std::string StrError(int errnum) {
++  absl::base_internal::ErrnoSaver errno_saver;
+   static const auto* table = NewStrErrorTable();
+   if (errnum >= 0 && errnum < static_cast<int>(table->size())) {
+     return (*table)[errnum];
+diff --git a/absl/base/internal/strerror_test.cc b/absl/base/internal/strerror_test.cc
+index a53da97f..e32d5b5c 100644
+--- a/absl/base/internal/strerror_test.cc
++++ b/absl/base/internal/strerror_test.cc
+@@ -62,12 +62,14 @@ TEST(StrErrorTest, MultipleThreads) {
+       ++counter;
+       errno = ERANGE;
+       const std::string value = absl::base_internal::StrError(i);
++      // EXPECT_* could change errno. Stash it first.
++      int check_err = errno;
++      EXPECT_THAT(check_err, Eq(ERANGE));
+       // Only the GNU implementation is guaranteed to provide the
+       // string "Unknown error nnn". POSIX doesn't say anything.
+       if (!absl::StartsWith(value, "Unknown error ")) {
+-        EXPECT_THAT(absl::base_internal::StrError(i), Eq(expected_strings[i]));
++        EXPECT_THAT(value, Eq(expected_strings[i]));
+       }
+-      EXPECT_THAT(errno, Eq(ERANGE));
+     }
+   };
+ 
diff --git a/gnu/packages/patches/aws-c-cal-cmake-prefix.patch b/gnu/packages/patches/aws-c-cal-cmake-prefix.patch
new file mode 100644
index 0000000000..1ee7aa851d
--- /dev/null
+++ b/gnu/packages/patches/aws-c-cal-cmake-prefix.patch
@@ -0,0 +1,13 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -10,6 +10,10 @@ endif()
+ 
+ option(BYO_CRYPTO "Set this if you want to provide your own cryptography implementation. This will cause the defaults to not be compiled." OFF)
+ 
++if (DEFINED ENV{CMAKE_PREFIX_PATH})
++    set(CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH})
++endif()
++
+ if (DEFINED CMAKE_PREFIX_PATH)
+     file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH)
+ endif()
diff --git a/gnu/packages/patches/aws-c-io-cmake-prefix.patch b/gnu/packages/patches/aws-c-io-cmake-prefix.patch
new file mode 100644
index 0000000000..da3e4eb4a5
--- /dev/null
+++ b/gnu/packages/patches/aws-c-io-cmake-prefix.patch
@@ -0,0 +1,13 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -6,6 +6,10 @@ if (POLICY CMP0069)
+     cmake_policy(SET CMP0069 NEW) # Enable LTO/IPO if available in the compiler, see AwsCFlags
+ endif()
+ 
++if (DEFINED ENV{CMAKE_PREFIX_PATH})
++    set(CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH})
++endif()
++
+ if (DEFINED CMAKE_PREFIX_PATH)
+     file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH)
+ endif()
diff --git a/gnu/packages/patches/aws-c-io-disable-networking-tests.patch b/gnu/packages/patches/aws-c-io-disable-networking-tests.patch
new file mode 100644
index 0000000000..09fe11310c
--- /dev/null
+++ b/gnu/packages/patches/aws-c-io-disable-networking-tests.patch
@@ -0,0 +1,81 @@
+--- a/tests/CMakeLists.txt
++++ b/tests/CMakeLists.txt
+@@ -52,8 +52,8 @@ add_test_case(local_socket_communication)
+ add_net_test_case(tcp_socket_communication)
+ add_net_test_case(udp_socket_communication)
+ add_test_case(udp_bind_connect_communication)
+-add_net_test_case(connect_timeout)
+-add_net_test_case(connect_timeout_cancelation)
++#add_net_test_case(connect_timeout)
++#add_net_test_case(connect_timeout_cancelation)
+ if (USE_VSOCK)
+ 	add_test_case(vsock_loopback_socket_communication)
+ endif ()
+@@ -64,7 +64,7 @@ add_test_case(incoming_tcp_sock_errors)
+ add_test_case(incoming_duplicate_tcp_bind_errors)
+ add_test_case(incoming_udp_sock_errors)
+ add_test_case(wrong_thread_read_write_fails)
+-add_net_test_case(cleanup_before_connect_or_timeout_doesnt_explode)
++#add_net_test_case(cleanup_before_connect_or_timeout_doesnt_explode)
+ add_test_case(cleanup_in_accept_doesnt_explode)
+ add_test_case(cleanup_in_write_cb_doesnt_explode)
+ add_test_case(sock_write_cb_is_async)
+@@ -81,21 +81,21 @@ add_test_case(channel_tasks_run)
+ add_test_case(channel_rejects_post_shutdown_tasks)
+ add_test_case(channel_cancels_pending_tasks)
+ add_test_case(channel_duplicate_shutdown)
+-add_net_test_case(channel_connect_some_hosts_timeout)
++#add_net_test_case(channel_connect_some_hosts_timeout)
+
+-add_net_test_case(test_default_with_ipv6_lookup)
++#add_net_test_case(test_default_with_ipv6_lookup)
+ add_test_case(test_resolver_ipv6_address_lookup)
+-add_net_test_case(test_default_with_multiple_lookups)
++#add_net_test_case(test_default_with_multiple_lookups)
+ add_test_case(test_resolver_ipv4_address_lookup)
+-add_net_test_case(test_default_with_ipv4_only_lookup)
++#add_net_test_case(test_default_with_ipv4_only_lookup)
+ add_test_case(test_resolver_ttls)
+ add_test_case(test_resolver_connect_failure_recording)
+ add_test_case(test_resolver_ttl_refreshes_on_resolve)
+
+ add_net_test_case(test_resolver_listener_create_destroy)
+-add_net_test_case(test_resolver_add_listener_before_host)
+-add_net_test_case(test_resolver_add_listener_after_host)
+-add_net_test_case(test_resolver_add_multiple_listeners_fn)
++#add_net_test_case(test_resolver_add_listener_before_host)
++#add_net_test_case(test_resolver_add_listener_after_host)
++#add_net_test_case(test_resolver_add_multiple_listeners_fn)
+ add_net_test_case(test_resolver_listener_host_re_add_fn)
+ add_net_test_case(test_resolver_listener_multiple_results)
+ add_net_test_case(test_resolver_listener_address_expired_fn)
+@@ -119,20 +119,20 @@ add_test_case(socket_handler_close)
+ if (NOT BYO_CRYPTO)
+     add_net_test_case(test_concurrent_cert_import)
+     add_test_case(tls_channel_echo_and_backpressure_test)
+-    add_net_test_case(tls_client_channel_negotiation_error_expired)
+-    add_net_test_case(tls_client_channel_negotiation_error_wrong_host)
+-    add_net_test_case(tls_client_channel_negotiation_error_self_signed)
+-    add_net_test_case(tls_client_channel_negotiation_error_untrusted_root)
++    #add_net_test_case(tls_client_channel_negotiation_error_expired)
++    #add_net_test_case(tls_client_channel_negotiation_error_wrong_host)
++    #add_net_test_case(tls_client_channel_negotiation_error_self_signed)
++    #add_net_test_case(tls_client_channel_negotiation_error_untrusted_root)
+     #track these down in s2n and find out why that aren't failing.
+     #add_net_test_case(tls_client_channel_negotiation_error_revoked)
+     #add_net_test_case(tls_client_channel_negotiation_error_pinning)
+-    add_net_test_case(tls_client_channel_negotiation_error_socket_closed)
+-    add_net_test_case(tls_client_channel_negotiation_success)
+-    add_net_test_case(tls_client_channel_negotiation_success_ecc256)
+-    add_net_test_case(tls_client_channel_negotiation_success_ecc384)
++    #add_net_test_case(tls_client_channel_negotiation_error_socket_closed)
++    #add_net_test_case(tls_client_channel_negotiation_success)
++    #add_net_test_case(tls_client_channel_negotiation_success_ecc256)
++    #add_net_test_case(tls_client_channel_negotiation_success_ecc384)
+     add_net_test_case(tls_server_multiple_connections)
+     add_net_test_case(tls_server_hangup_during_negotiation)
+-    add_net_test_case(tls_client_channel_no_verify)
++    #add_net_test_case(tls_client_channel_no_verify)
+     add_net_test_case(test_tls_negotiation_timeout)
+     add_net_test_case(tls_double_channel)
+     add_net_test_case(alpn_successfully_negotiates)
diff --git a/gnu/packages/patches/bsdiff-CVE-2014-9862.patch b/gnu/packages/patches/bsdiff-CVE-2014-9862.patch
new file mode 100644
index 0000000000..7aab818090
--- /dev/null
+++ b/gnu/packages/patches/bsdiff-CVE-2014-9862.patch
@@ -0,0 +1,15 @@
+diff --git a/bspatch.c b/bspatch.c
+index 8d95633..ab77722 100644
+--- a/bspatch.c
++++ b/bspatch.c
+
+@@ -187,6 +187,10 @@
+ 		};
+ 
+ 		/* Sanity-check */
++		if ((ctrl[0] < 0) || (ctrl[1] < 0))
++			errx(1,"Corrupt patch\n");
++
++		/* Sanity-check */
+ 		if(newpos+ctrl[0]>newsize)
+ 			errx(1,"Corrupt patch\n");
diff --git a/gnu/packages/patches/busybox-CVE-2021-28831.patch b/gnu/packages/patches/busybox-CVE-2021-28831.patch
new file mode 100644
index 0000000000..da3107fbb1
--- /dev/null
+++ b/gnu/packages/patches/busybox-CVE-2021-28831.patch
@@ -0,0 +1,57 @@
+From f25d254dfd4243698c31a4f3153d4ac72aa9e9bd Mon Sep 17 00:00:00 2001
+From: Samuel Sapalski <samuel.sapalski@nokia.com>
+Date: Wed, 3 Mar 2021 16:31:22 +0100
+Subject: decompress_gunzip: Fix DoS if gzip is corrupt
+
+On certain corrupt gzip files, huft_build will set the error bit on
+the result pointer. If afterwards abort_unzip is called huft_free
+might run into a segmentation fault or an invalid pointer to
+free(p).
+
+In order to mitigate this, we check in huft_free if the error bit
+is set and clear it before the linked list is freed.
+
+Signed-off-by: Samuel Sapalski <samuel.sapalski@nokia.com>
+Signed-off-by: Peter Kaestle <peter.kaestle@nokia.com>
+Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
+---
+ archival/libarchive/decompress_gunzip.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c
+index eb3b64930..e93cd5005 100644
+--- a/archival/libarchive/decompress_gunzip.c
++++ b/archival/libarchive/decompress_gunzip.c
+@@ -220,10 +220,20 @@ static const uint8_t border[] ALIGN1 = {
+  * each table.
+  * t: table to free
+  */
++#define BAD_HUFT(p) ((uintptr_t)(p) & 1)
++#define ERR_RET     ((huft_t*)(uintptr_t)1)
+ static void huft_free(huft_t *p)
+ {
+ 	huft_t *q;
+ 
++	/*
++	 * If 'p' has the error bit set we have to clear it, otherwise we might run
++	 * into a segmentation fault or an invalid pointer to free(p)
++	 */
++	if (BAD_HUFT(p)) {
++		p = (huft_t*)((uintptr_t)(p) ^ (uintptr_t)(ERR_RET));
++	}
++
+ 	/* Go through linked list, freeing from the malloced (t[-1]) address. */
+ 	while (p) {
+ 		q = (--p)->v.t;
+@@ -289,8 +299,6 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current
+  * or a valid pointer to a Huffman table, ORed with 0x1 if incompete table
+  * is given: "fixed inflate" decoder feeds us such data.
+  */
+-#define BAD_HUFT(p) ((uintptr_t)(p) & 1)
+-#define ERR_RET     ((huft_t*)(uintptr_t)1)
+ static huft_t* huft_build(const unsigned *b, const unsigned n,
+ 			const unsigned s, const struct cp_ext *cp_ext,
+ 			unsigned *m)
+-- 
+cgit v1.2.1
+
diff --git a/gnu/packages/patches/cairo-CVE-2018-19876.patch b/gnu/packages/patches/cairo-CVE-2018-19876.patch
new file mode 100644
index 0000000000..c0fba2ecaa
--- /dev/null
+++ b/gnu/packages/patches/cairo-CVE-2018-19876.patch
@@ -0,0 +1,37 @@
+Copied from Debian.
+
+From: Carlos Garcia Campos <cgarcia@igalia.com>
+Date: Mon, 19 Nov 2018 12:33:07 +0100
+Subject: ft: Use FT_Done_MM_Var instead of free when available in
+ cairo_ft_apply_variations
+
+Fixes a crash when using freetype >= 2.9
+
+[This is considered to be security-sensitive because WebKitGTK+ sets its
+own memory allocator, which is not compatible with system free(), making
+this a remotely triggerable denial of service or memory corruption.]
+
+Origin: upstream, commit:90e85c2493fdfa3551f202ff10282463f1e36645
+Bug: https://gitlab.freedesktop.org/cairo/cairo/merge_requests/5
+Bug-Debian: https://bugs.debian.org/916389
+Bug-CVE: CVE-2018-19876
+---
+ src/cairo-ft-font.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
+index 325dd61..981973f 100644
+--- a/src/cairo-ft-font.c
++++ b/src/cairo-ft-font.c
+@@ -2393,7 +2393,11 @@ skip:
+ done:
+         free (coords);
+         free (current_coords);
++#if HAVE_FT_DONE_MM_VAR
++        FT_Done_MM_Var (face->glyph->library, ft_mm_var);
++#else
+         free (ft_mm_var);
++#endif
+     }
+ }
+ 
diff --git a/gnu/packages/patches/cairo-CVE-2020-35492.patch b/gnu/packages/patches/cairo-CVE-2020-35492.patch
new file mode 100644
index 0000000000..e8b90fa5c5
--- /dev/null
+++ b/gnu/packages/patches/cairo-CVE-2020-35492.patch
@@ -0,0 +1,49 @@
+Copied from Debian.
+
+From 03a820b173ed1fdef6ff14b4468f5dbc02ff59be Mon Sep 17 00:00:00 2001
+From: Heiko Lewin <heiko.lewin@worldiety.de>
+Date: Tue, 15 Dec 2020 16:48:19 +0100
+Subject: [PATCH] Fix mask usage in image-compositor
+
+[trimmed test case, since not used in Debian build]
+
+---
+ src/cairo-image-compositor.c                |   8 ++--
+
+--- cairo-1.16.0.orig/src/cairo-image-compositor.c
++++ cairo-1.16.0/src/cairo-image-compositor.c
+@@ -2601,14 +2601,14 @@ _inplace_src_spans (void *abstract_rende
+ 		    unsigned num_spans)
+ {
+     cairo_image_span_renderer_t *r = abstract_renderer;
+-    uint8_t *m;
++    uint8_t *m, *base = (uint8_t*)pixman_image_get_data(r->mask);
+     int x0;
+ 
+     if (num_spans == 0)
+ 	return CAIRO_STATUS_SUCCESS;
+ 
+     x0 = spans[0].x;
+-    m = r->_buf;
++    m = base;
+     do {
+ 	int len = spans[1].x - spans[0].x;
+ 	if (len >= r->u.composite.run_length && spans[0].coverage == 0xff) {
+@@ -2646,7 +2646,7 @@ _inplace_src_spans (void *abstract_rende
+ 				      spans[0].x, y,
+ 				      spans[1].x - spans[0].x, h);
+ 
+-	    m = r->_buf;
++	    m = base;
+ 	    x0 = spans[1].x;
+ 	} else if (spans[0].coverage == 0x0) {
+ 	    if (spans[0].x != x0) {
+@@ -2675,7 +2675,7 @@ _inplace_src_spans (void *abstract_rende
+ #endif
+ 	    }
+ 
+-	    m = r->_buf;
++	    m = base;
+ 	    x0 = spans[1].x;
+ 	} else {
+ 	    *m++ = spans[0].coverage;
diff --git a/gnu/packages/patches/cyrus-sasl-CVE-2019-19906.patch b/gnu/packages/patches/cyrus-sasl-CVE-2019-19906.patch
new file mode 100644
index 0000000000..acdf682430
--- /dev/null
+++ b/gnu/packages/patches/cyrus-sasl-CVE-2019-19906.patch
@@ -0,0 +1,25 @@
+From dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1 Mon Sep 17 00:00:00 2001
+From: Quanah Gibson-Mount <quanah@symas.com>
+Date: Tue, 18 Feb 2020 19:05:12 +0000
+Subject: [PATCH] Fix #587
+
+Off by one error in common.c, CVE-2019-19906.
+
+Thanks to Stephan Zeisberg for reporting
+---
+ lib/common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/common.c b/lib/common.c
+index bc3bf1df..9969d6aa 100644
+--- a/lib/common.c
++++ b/lib/common.c
+@@ -190,7 +190,7 @@ int _sasl_add_string(char **out, size_t *alloclen,
+ 
+   if (add==NULL) add = "(null)";
+ 
+-  addlen=strlen(add); /* only compute once */
++  addlen=strlen(add)+1; /* only compute once */
+   if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK)
+     return SASL_NOMEM;
+ 
diff --git a/gnu/packages/patches/efibootmgr-remove-extra-decl.patch b/gnu/packages/patches/efibootmgr-remove-extra-decl.patch
new file mode 100644
index 0000000000..eb68108f88
--- /dev/null
+++ b/gnu/packages/patches/efibootmgr-remove-extra-decl.patch
@@ -0,0 +1,27 @@
+From 99b578501643377e0b1994b2a068b790d189d5ad Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Wed, 13 Jun 2018 09:41:01 -0400
+Subject: [PATCH] remove extra decl
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ src/efibootmgr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/efibootmgr.c b/src/efibootmgr.c
+index de38f01..4e1a680 100644
+--- a/src/efibootmgr.c
++++ b/src/efibootmgr.c
+@@ -1536,9 +1536,6 @@ parse_opts(int argc, char **argv)
+ 					       "invalid numeric value %s\n",
+ 					       optarg);
+ 			}
+-                        /* XXX efivar-36 accidentally doesn't have a public
+-                         * header for this */
+-			extern int efi_set_verbose(int verbosity, FILE *errlog);
+ 			efi_set_verbose(opts.verbose - 2, stderr);
+ 			break;
+ 		case 'V':
+-- 
+2.24.0
+
diff --git a/gnu/packages/patches/evolution-CVE-2020-11879.patch b/gnu/packages/patches/evolution-CVE-2020-11879.patch
new file mode 100644
index 0000000000..8c85895aab
--- /dev/null
+++ b/gnu/packages/patches/evolution-CVE-2020-11879.patch
@@ -0,0 +1,122 @@
+From 6489f20d6905cc797e2b2581c415e558c457caa7 Mon Sep 17 00:00:00 2001
+From: Milan Crha <mcrha@redhat.com>
+Date: Wed, 12 Feb 2020 18:59:52 +0100
+Subject: [PATCH] I#784 - Warn about and limit what can be attached using
+ mailto: URI
+
+Closes https://gitlab.gnome.org/GNOME/evolution/issues/784
+---
+ src/composer/e-msg-composer.c | 58 +++++++++++++++++++++++++++++------
+ src/e-util/e-system.error.xml |  7 ++++-
+ 2 files changed, 54 insertions(+), 11 deletions(-)
+
+diff --git a/src/composer/e-msg-composer.c b/src/composer/e-msg-composer.c
+index e4c9ac095e..cd3168d882 100644
+--- a/src/composer/e-msg-composer.c
++++ b/src/composer/e-msg-composer.c
+@@ -4761,7 +4761,8 @@ handle_mailto (EMsgComposer *composer,
+ 	gchar *header, *content, *buf;
+ 	gsize nread, nwritten;
+ 	const gchar *p;
+-	gint len, clen;
++	gint len, clen, has_attachments = 0;
++	gboolean has_blacklisted_attachment = FALSE;
+ 
+ 	table = e_msg_composer_get_header_table (composer);
+ 	view = e_msg_composer_get_attachment_view (composer);
+@@ -4844,22 +4845,36 @@ handle_mailto (EMsgComposer *composer,
+ 			} else if (!g_ascii_strcasecmp (header, "attach") ||
+ 				   !g_ascii_strcasecmp (header, "attachment")) {
+ 				EAttachment *attachment;
++				GFile *file;
+ 
+ 				camel_url_decode (content);
+-				if (file_is_blacklisted (content))
+-					e_alert_submit (
+-						E_ALERT_SINK (e_msg_composer_get_editor (composer)),
+-						"mail:blacklisted-file",
+-						content, NULL);
+ 				if (g_ascii_strncasecmp (content, "file:", 5) == 0)
+ 					attachment = e_attachment_new_for_uri (content);
+ 				else
+ 					attachment = e_attachment_new_for_path (content);
+-				e_attachment_store_add_attachment (store, attachment);
+-				e_attachment_load_async (
+-					attachment, (GAsyncReadyCallback)
+-					e_attachment_load_handle_error, composer);
++				file = e_attachment_ref_file (attachment);
++				if (!file || !g_file_peek_path (file) ||
++				    !g_file_test (g_file_peek_path (file), G_FILE_TEST_EXISTS) ||
++				    g_file_test (g_file_peek_path (file), G_FILE_TEST_IS_DIR)) {
++					/* Do nothing, simply ignore the attachment request */
++				} else {
++					has_attachments++;
++
++					if (file_is_blacklisted (content)) {
++						has_blacklisted_attachment = TRUE;
++						e_alert_submit (
++							E_ALERT_SINK (e_msg_composer_get_editor (composer)),
++							"mail:blacklisted-file",
++							content, NULL);
++					}
++
++					e_attachment_store_add_attachment (store, attachment);
++					e_attachment_load_async (
++						attachment, (GAsyncReadyCallback)
++						e_attachment_load_handle_error, composer);
++				}
+ 				g_object_unref (attachment);
++				g_clear_object (&file);
+ 			} else if (!g_ascii_strcasecmp (header, "from")) {
+ 				/* Ignore */
+ 			} else if (!g_ascii_strcasecmp (header, "reply-to")) {
+@@ -4883,6 +4898,29 @@ handle_mailto (EMsgComposer *composer,
+ 
+ 	g_free (buf);
+ 
++	if (has_attachments && !has_blacklisted_attachment) {
++		const gchar *primary;
++		gchar *secondary;
++
++		primary = g_dngettext (GETTEXT_PACKAGE,
++			"Review attachment before sending.",
++			"Review attachments before sending.",
++			has_attachments);
++
++		secondary = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
++			"There had been added %d attachment. Make sure it does not contain any sensitive information before sending the message.",
++			"There had been added %d attachments. Make sure they do not contain any sensitive information before sending the message.",
++			has_attachments),
++			has_attachments);
++
++		e_alert_submit (
++			E_ALERT_SINK (e_msg_composer_get_editor (composer)),
++			"system:generic-warning",
++			primary, secondary, NULL);
++
++		g_free (secondary);
++	}
++
+ 	merge_always_cc_and_bcc (table, to, &cc, &bcc);
+ 
+ 	tov = destination_list_to_vector (to);
+diff --git a/src/e-util/e-system.error.xml b/src/e-util/e-system.error.xml
+index ddcf989fda..02facb7d26 100644
+--- a/src/e-util/e-system.error.xml
++++ b/src/e-util/e-system.error.xml
+@@ -1,6 +1,11 @@
+ <?xml version="1.0"?>
+ <error-list domain="system">
+-  <error type="error" id="generic-error">
++  <error id="generic-error" type="error">
++    <primary>{0}</primary>
++    <secondary>{1}</secondary>
++  </error>
++
++  <error id="generic-warning" type="warning">
+     <primary>{0}</primary>
+     <secondary>{1}</secondary>
+   </error>
+-- 
+GitLab
+
diff --git a/gnu/packages/patches/evolution-data-server-CVE-2020-14928.patch b/gnu/packages/patches/evolution-data-server-CVE-2020-14928.patch
new file mode 100644
index 0000000000..421f292c9d
--- /dev/null
+++ b/gnu/packages/patches/evolution-data-server-CVE-2020-14928.patch
@@ -0,0 +1,115 @@
+From ba82be72cfd427b5d72ff21f929b3a6d8529c4df Mon Sep 17 00:00:00 2001
+From: Milan Crha <mcrha@redhat.com>
+Date: Mon, 22 Jun 2020 13:40:17 +0200
+Subject: [PATCH] I#226 - CVE-2020-14928: Response Injection via STARTTLS in
+ SMTP and POP3
+
+Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/226
+---
+ src/camel/camel-stream-buffer.c               | 19 +++++++++++++++++++
+ src/camel/camel-stream-buffer.h               |  1 +
+ src/camel/providers/pop3/camel-pop3-store.c   |  2 ++
+ src/camel/providers/pop3/camel-pop3-stream.c  | 11 +++++++++++
+ src/camel/providers/pop3/camel-pop3-stream.h  |  1 +
+ .../providers/smtp/camel-smtp-transport.c     |  2 ++
+ 6 files changed, 36 insertions(+)
+
+diff --git a/src/camel/camel-stream-buffer.c b/src/camel/camel-stream-buffer.c
+index 3e2e0dd36..a6f605ae5 100644
+--- a/src/camel/camel-stream-buffer.c
++++ b/src/camel/camel-stream-buffer.c
+@@ -518,3 +518,22 @@ camel_stream_buffer_read_line (CamelStreamBuffer *sbf,
+ 
+ 	return g_strdup ((gchar *) sbf->priv->linebuf);
+ }
++
++/**
++ * camel_stream_buffer_discard_cache:
++ * @sbf: a #CamelStreamBuffer
++ *
++ * Discards any cached data in the @sbf. The next read reads
++ * from the stream.
++ *
++ * Since: 3.38
++ **/
++void
++camel_stream_buffer_discard_cache (CamelStreamBuffer *sbf)
++{
++	g_return_if_fail (CAMEL_IS_STREAM_BUFFER (sbf));
++
++	sbf->priv->ptr = sbf->priv->buf;
++	sbf->priv->end = sbf->priv->buf;
++	sbf->priv->ptr[0] = '\0';
++}
+diff --git a/src/camel/camel-stream-buffer.h b/src/camel/camel-stream-buffer.h
+index ef92cfd8e..094e9926b 100644
+--- a/src/camel/camel-stream-buffer.h
++++ b/src/camel/camel-stream-buffer.h
+@@ -93,6 +93,7 @@ gint		camel_stream_buffer_gets	(CamelStreamBuffer *sbf,
+ gchar *		camel_stream_buffer_read_line	(CamelStreamBuffer *sbf,
+ 						 GCancellable *cancellable,
+ 						 GError **error);
++void		camel_stream_buffer_discard_cache	(CamelStreamBuffer *sbf);
+ 
+ G_END_DECLS
+ 
+diff --git a/src/camel/providers/pop3/camel-pop3-store.c b/src/camel/providers/pop3/camel-pop3-store.c
+index 81c370f0a..5c9eb1eaa 100644
+--- a/src/camel/providers/pop3/camel-pop3-store.c
++++ b/src/camel/providers/pop3/camel-pop3-store.c
+@@ -205,6 +205,8 @@ connect_to_server (CamelService *service,
+ 
+ 	if (tls_stream != NULL) {
+ 		camel_stream_set_base_stream (stream, tls_stream);
++		/* Truncate any left cached input from the insecure part of the session */
++		camel_pop3_stream_discard_cache (pop3_engine->stream);
+ 		g_object_unref (tls_stream);
+ 	} else {
+ 		g_prefix_error (
+diff --git a/src/camel/providers/pop3/camel-pop3-stream.c b/src/camel/providers/pop3/camel-pop3-stream.c
+index 74bb11e61..c485b9bd6 100644
+--- a/src/camel/providers/pop3/camel-pop3-stream.c
++++ b/src/camel/providers/pop3/camel-pop3-stream.c
+@@ -457,3 +457,14 @@ camel_pop3_stream_getd (CamelPOP3Stream *is,
+ 
+ 	return 1;
+ }
++
++void
++camel_pop3_stream_discard_cache (CamelPOP3Stream *is)
++{
++	if (is) {
++		is->ptr = is->end = is->buf;
++		is->lineptr = is->linebuf;
++		is->lineend = is->linebuf + CAMEL_POP3_STREAM_LINE_SIZE;
++		is->ptr[0] = '\n';
++	}
++}
+diff --git a/src/camel/providers/pop3/camel-pop3-stream.h b/src/camel/providers/pop3/camel-pop3-stream.h
+index bb6dbb903..128c8c45a 100644
+--- a/src/camel/providers/pop3/camel-pop3-stream.h
++++ b/src/camel/providers/pop3/camel-pop3-stream.h
+@@ -87,6 +87,7 @@ gint		camel_pop3_stream_getd		(CamelPOP3Stream *is,
+ 						 guint *len,
+ 						 GCancellable *cancellable,
+ 						 GError **error);
++void		camel_pop3_stream_discard_cache	(CamelPOP3Stream *is);
+ 
+ G_END_DECLS
+ 
+diff --git a/src/camel/providers/smtp/camel-smtp-transport.c b/src/camel/providers/smtp/camel-smtp-transport.c
+index 035baf367..1fc0f3206 100644
+--- a/src/camel/providers/smtp/camel-smtp-transport.c
++++ b/src/camel/providers/smtp/camel-smtp-transport.c
+@@ -323,6 +323,8 @@ connect_to_server (CamelService *service,
+ 
+ 	if (tls_stream != NULL) {
+ 		camel_stream_set_base_stream (stream, tls_stream);
++		/* Truncate any left cached input from the insecure part of the session */
++		camel_stream_buffer_discard_cache (transport->istream);
+ 		g_object_unref (tls_stream);
+ 	} else {
+ 		g_prefix_error (
+-- 
+GitLab
+
diff --git a/gnu/packages/patches/evolution-data-server-CVE-2020-16117.patch b/gnu/packages/patches/evolution-data-server-CVE-2020-16117.patch
new file mode 100644
index 0000000000..b2c0622a90
--- /dev/null
+++ b/gnu/packages/patches/evolution-data-server-CVE-2020-16117.patch
@@ -0,0 +1,28 @@
+From 2cc39592b532cf0dc994fd3694b8e6bf924c9ab5 Mon Sep 17 00:00:00 2001
+From: Milan Crha <mcrha@redhat.com>
+Date: Mon, 10 Feb 2020 10:00:32 +0100
+Subject: [PATCH] I#189 - Crash on malformed server response with minimal
+ capabilities
+
+Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/189
+---
+ src/camel/providers/imapx/camel-imapx-server.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
+index 3c38fb1e9..3883321ec 100644
+--- a/src/camel/providers/imapx/camel-imapx-server.c
++++ b/src/camel/providers/imapx/camel-imapx-server.c
+@@ -3045,7 +3045,8 @@ connected:
+ 
+ 			/* See if we got new capabilities
+ 			 * in the STARTTLS response. */
+-			imapx_free_capability (is->priv->cinfo);
++			if (is->priv->cinfo)
++				imapx_free_capability (is->priv->cinfo);
+ 			is->priv->cinfo = NULL;
+ 			if (ic->status->condition == IMAPX_CAPABILITY) {
+ 				is->priv->cinfo = ic->status->u.cinfo;
+-- 
+GitLab
+
diff --git a/gnu/packages/patches/gdk-pixbuf-CVE-2020-29385.patch b/gnu/packages/patches/gdk-pixbuf-CVE-2020-29385.patch
new file mode 100644
index 0000000000..e6ac4de00b
--- /dev/null
+++ b/gnu/packages/patches/gdk-pixbuf-CVE-2020-29385.patch
@@ -0,0 +1,53 @@
+Fix CVE-2020-29385.  Note that we omit the binary test file
+tests/test-images/fail/hang_114.gif from the following commit, to avoid
+requiring 'git' to apply the patch.
+
+
+From bdd3acbd48a575d418ba6bf1b32d7bda2fae1c81 Mon Sep 17 00:00:00 2001
+From: Robert Ancell <robert.ancell@canonical.com>
+Date: Mon, 30 Nov 2020 12:26:12 +1300
+Subject: [PATCH] gif: Fix LZW decoder accepting invalid LZW code.
+
+The code value after a reset wasn't being validated, which means we would
+accept invalid codes. This could cause an infinite loop in the decoder.
+
+Fixes CVE-2020-29385
+
+Fixes https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/issues/164
+---
+ gdk-pixbuf/lzw.c                    |  13 +++++++------
+ tests/test-images/fail/hang_114.gif | Bin 0 -> 5561 bytes
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+ create mode 100644 tests/test-images/fail/hang_114.gif
+
+diff --git a/gdk-pixbuf/lzw.c b/gdk-pixbuf/lzw.c
+index 9e052a6f7..105daf2b1 100644
+--- a/gdk-pixbuf/lzw.c
++++ b/gdk-pixbuf/lzw.c
+@@ -195,19 +195,20 @@ lzw_decoder_feed (LZWDecoder *self,
+                                 if (self->last_code != self->clear_code && self->code_table_size < MAX_CODES) {
+                                         if (self->code < self->code_table_size)
+                                                 add_code (self, self->code);
+-                                        else if (self->code == self->code_table_size)
++                                        else
+                                                 add_code (self, self->last_code);
+-                                        else {
+-                                                /* Invalid code received - just stop here */
+-                                                self->last_code = self->eoi_code;
+-                                                return output_length;
+-                                        }
+ 
+                                         /* When table is full increase code size */
+                                         if (self->code_table_size == (1 << self->code_size) && self->code_size < LZW_CODE_MAX)
+                                                 self->code_size++;
+                                 }
+ 
++                                /* Invalid code received - just stop here */
++                                if (self->code >= self->code_table_size) {
++                                        self->last_code = self->eoi_code;
++                                        return output_length;
++                                }
++
+                                 /* Convert codeword into indexes */
+                                 n_written += write_indexes (self, output + n_written, output_length - n_written);
+                         }
diff --git a/gnu/packages/patches/geary-CVE-2020-24661.patch b/gnu/packages/patches/geary-CVE-2020-24661.patch
new file mode 100644
index 0000000000..6cbc224786
--- /dev/null
+++ b/gnu/packages/patches/geary-CVE-2020-24661.patch
@@ -0,0 +1,133 @@
+From d4e86dc91e1d8a940dc40872fe94ef9ac0fed1b5 Mon Sep 17 00:00:00 2001
+From: Michael Gratton <mike@vee.net>
+Date: Tue, 25 Aug 2020 03:54:09 +0000
+Subject: [PATCH] Merge branch 'mjog/866-self-signed-certificates' into
+ 'mainline'
+
+Fix invalid certificate pinning when GCR support is unavailable
+
+Closes #866
+
+See merge request GNOME/geary!529
+
+(cherry picked from commit 423a55b00f1dc6bee9dc17e67c0aea6f42387a77)
+
+5088adfe Application.CertificateManager: Rename some methods for clarity
+0d957559 Application.CertificateManager: Check locally pinned certs for equality
+---
+ .../application-certificate-manager.vala      | 44 +++++++++----------
+ 1 file changed, 22 insertions(+), 22 deletions(-)
+
+diff --git a/src/client/application/application-certificate-manager.vala b/src/client/application/application-certificate-manager.vala
+index 4881d73c0..65f6af4fa 100644
+--- a/src/client/application/application-certificate-manager.vala
++++ b/src/client/application/application-certificate-manager.vala
+@@ -381,8 +381,8 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+         GLib.TlsCertificateFlags ret = this.parent.verify_chain(
+             chain, purpose, identity, interaction, flags, cancellable
+         );
+-        if (should_verify(ret, purpose, identity) &&
+-            verify(chain, identity, cancellable)) {
++        if (check_pinned(ret, purpose, identity) &&
++            is_pinned(chain, identity, cancellable)) {
+             ret = 0;
+         }
+         return ret;
+@@ -399,16 +399,16 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+         GLib.TlsCertificateFlags ret = yield this.parent.verify_chain_async(
+             chain, purpose, identity, interaction, flags, cancellable
+         );
+-        if (should_verify(ret, purpose, identity) &&
+-            yield verify_async(chain, identity, cancellable)) {
++        if (check_pinned(ret, purpose, identity) &&
++            yield is_pinned_async(chain, identity, cancellable)) {
+             ret = 0;
+         }
+         return ret;
+     }
+ 
+-    private inline bool should_verify(GLib.TlsCertificateFlags parent_ret,
+-                                      string purpose,
+-                                      GLib.SocketConnectable? identity) {
++    private inline bool check_pinned(GLib.TlsCertificateFlags parent_ret,
++                                     string purpose,
++                                     GLib.SocketConnectable? identity) {
+         // If the parent didn't verify, check for a locally pinned
+         // cert if it looks like we should, but always reject revoked
+         // certs
+@@ -420,22 +420,22 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+         );
+     }
+ 
+-    private bool verify(GLib.TlsCertificate chain,
+-                        GLib.SocketConnectable identity,
+-                        GLib.Cancellable? cancellable)
++    private bool is_pinned(GLib.TlsCertificate chain,
++                           GLib.SocketConnectable identity,
++                           GLib.Cancellable? cancellable)
+         throws GLib.Error {
+-        bool is_verified = false;
++        bool is_pinned = false;
+         string id = to_name(identity);
+         TrustContext? context = null;
+         lock (this.pinned_certs) {
+             context = this.pinned_certs.get(id);
+             if (context != null) {
+-                is_verified = true;
++                is_pinned = context.certificate.is_same(chain);
+             } else {
+                 // Cert not found in memory, check with GCR if
+                 // enabled.
+                 if (this.use_gcr) {
+-                    is_verified = gcr_trust_is_certificate_pinned(
++                    is_pinned = gcr_trust_is_certificate_pinned(
+                         new Gcr.SimpleCertificate(chain.certificate.data),
+                         GLib.TlsDatabase.PURPOSE_AUTHENTICATE_SERVER,
+                         id,
+@@ -443,7 +443,7 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+                     );
+                 }
+ 
+-                if (!is_verified) {
++                if (!is_pinned) {
+                     // Cert is not pinned in memory or in GCR, so look
+                     // for it on disk. Do this even if GCR support is
+                     // enabled, since if the cert was previously saved
+@@ -453,7 +453,7 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+                             this.store_dir, id, cancellable
+                         );
+                         this.pinned_certs.set(id, context);
+-                        is_verified = true;
++                        is_pinned = context.certificate.is_same(chain);
+                     } catch (GLib.IOError.NOT_FOUND err) {
+                         // Cert was not found saved, so it not pinned
+                     } catch (GLib.Error err) {
+@@ -465,18 +465,18 @@ private class Application.TlsDatabase : GLib.TlsDatabase {
+                 }
+             }
+         }
+-        return is_verified;
++        return is_pinned;
+     }
+ 
+-    private async bool verify_async(GLib.TlsCertificate chain,
+-                                    GLib.SocketConnectable identity,
+-                                    GLib.Cancellable? cancellable)
++    private async bool is_pinned_async(GLib.TlsCertificate chain,
++                                       GLib.SocketConnectable identity,
++                                       GLib.Cancellable? cancellable)
+         throws GLib.Error {
+-        bool is_valid = false;
++        bool pinned = false;
+         yield Geary.Nonblocking.Concurrent.global.schedule_async(() => {
+-                is_valid = verify(chain, identity, cancellable);
++                pinned = is_pinned(chain, identity, cancellable);
+             }, cancellable);
+-        return is_valid;
++        return pinned;
+     }
+ 
+     private TrustContext? lookup_id(string id) {
+-- 
+GitLab
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27218.patch b/gnu/packages/patches/glib-CVE-2021-27218.patch
new file mode 100644
index 0000000000..00fa5ebf79
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27218.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-01.patch b/gnu/packages/patches/glib-CVE-2021-27219-01.patch
new file mode 100644
index 0000000000..5db360d468
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-01.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-02.patch b/gnu/packages/patches/glib-CVE-2021-27219-02.patch
new file mode 100644
index 0000000000..431959fa8f
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-02.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-03.patch b/gnu/packages/patches/glib-CVE-2021-27219-03.patch
new file mode 100644
index 0000000000..99e849c43c
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-03.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-04.patch b/gnu/packages/patches/glib-CVE-2021-27219-04.patch
new file mode 100644
index 0000000000..3ae01f34b1
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-04.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-05.patch b/gnu/packages/patches/glib-CVE-2021-27219-05.patch
new file mode 100644
index 0000000000..62bce1b188
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-05.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-06.patch b/gnu/packages/patches/glib-CVE-2021-27219-06.patch
new file mode 100644
index 0000000000..4e2435f5fd
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-06.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-07.patch b/gnu/packages/patches/glib-CVE-2021-27219-07.patch
new file mode 100644
index 0000000000..dad3d285f4
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-07.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-08.patch b/gnu/packages/patches/glib-CVE-2021-27219-08.patch
new file mode 100644
index 0000000000..2c021ad317
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-08.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-09.patch b/gnu/packages/patches/glib-CVE-2021-27219-09.patch
new file mode 100644
index 0000000000..4de0c1b349
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-09.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-10.patch b/gnu/packages/patches/glib-CVE-2021-27219-10.patch
new file mode 100644
index 0000000000..36198b8eef
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-10.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-11.patch b/gnu/packages/patches/glib-CVE-2021-27219-11.patch
new file mode 100644
index 0000000000..4413cb9827
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-11.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-12.patch b/gnu/packages/patches/glib-CVE-2021-27219-12.patch
new file mode 100644
index 0000000000..4fdbb81750
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-12.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-13.patch b/gnu/packages/patches/glib-CVE-2021-27219-13.patch
new file mode 100644
index 0000000000..6a287cc3a2
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-13.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-14.patch b/gnu/packages/patches/glib-CVE-2021-27219-14.patch
new file mode 100644
index 0000000000..78de2846da
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-14.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-15.patch b/gnu/packages/patches/glib-CVE-2021-27219-15.patch
new file mode 100644
index 0000000000..37ef85b4fa
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-15.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-16.patch b/gnu/packages/patches/glib-CVE-2021-27219-16.patch
new file mode 100644
index 0000000000..43635e72ed
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-16.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-17.patch b/gnu/packages/patches/glib-CVE-2021-27219-17.patch
new file mode 100644
index 0000000000..3153979071
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-17.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-27219-18.patch b/gnu/packages/patches/glib-CVE-2021-27219-18.patch
new file mode 100644
index 0000000000..c18d44ddeb
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-27219-18.patch
@@ -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
+
diff --git a/gnu/packages/patches/glib-CVE-2021-28153.patch b/gnu/packages/patches/glib-CVE-2021-28153.patch
new file mode 100644
index 0000000000..54443186d9
--- /dev/null
+++ b/gnu/packages/patches/glib-CVE-2021-28153.patch
@@ -0,0 +1,283 @@
+Backport of:
+
+From 317b3b587058a05dca95d56dac26568c5b098d33 Mon Sep 17 00:00:00 2001
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Wed, 24 Feb 2021 17:35:40 +0000
+Subject: [PATCH] glocalfileoutputstream: Fix CREATE_REPLACE_DESTINATION
+ with symlinks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The `G_FILE_CREATE_REPLACE_DESTINATION` flag is equivalent to unlinking
+the destination file and re-creating it from scratch. That did
+previously work, but in the process the code would call `open(O_CREAT)`
+on the file. If the file was a dangling symlink, this would create the
+destination file (empty). That’s not an intended side-effect, and has
+security implications if the symlink is controlled by a lower-privileged
+process.
+
+Fix that by not opening the destination file if it’s a symlink, and
+adjusting the rest of the code to cope with
+ - the fact that `fd == -1` is not an error iff `is_symlink` is true,
+ - and that `original_stat` will contain the `lstat()` results for the
+   symlink now, rather than the `stat()` results for its target (again,
+   iff `is_symlink` is true).
+
+This means that the target of the dangling symlink is no longer created,
+which was the bug. The symlink itself continues to be replaced (as
+before) with the new file — this is the intended behaviour of
+`g_file_replace()`.
+
+The behaviour for non-symlink cases, or cases where the symlink was not
+dangling, should be unchanged.
+
+Includes a unit test.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+
+Fixes: #2325
+---
+ gio/glocalfileoutputstream.c |  70 ++++++++++++++++-------
+ gio/tests/file.c             | 108 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 158 insertions(+), 20 deletions(-)
+
+diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
+index a3dd62172..553fcbbae 100644
+--- a/gio/glocalfileoutputstream.c
++++ b/gio/glocalfileoutputstream.c
+@@ -874,16 +874,22 @@ handle_overwrite_open (const char    *filename,
+       /* Could be a symlink, or it could be a regular ELOOP error,
+        * but then the next open will fail too. */
+       is_symlink = TRUE;
+-      fd = g_open (filename, open_flags, mode);
++      if (!(flags & G_FILE_CREATE_REPLACE_DESTINATION))
++        fd = g_open (filename, open_flags, mode);
+     }
+-#else
+-  fd = g_open (filename, open_flags, mode);
+-  errsv = errno;
++#else  /* if !O_NOFOLLOW */
+   /* This is racy, but we do it as soon as possible to minimize the race */
+   is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK);
++
++  if (!is_symlink || !(flags & G_FILE_CREATE_REPLACE_DESTINATION))
++    {
++      fd = g_open (filename, open_flags, mode);
++      errsv = errno;
++    }
+ #endif
+ 
+-  if (fd == -1)
++  if (fd == -1 &&
++      (!is_symlink || !(flags & G_FILE_CREATE_REPLACE_DESTINATION)))
+     {
+       char *display_name = g_filename_display_name (filename);
+       g_set_error (error, G_IO_ERROR,
+@@ -893,13 +899,25 @@ handle_overwrite_open (const char    *filename,
+       g_free (display_name);
+       return -1;
+     }
+-  
++
++  if (!is_symlink)
++    {
+ #ifdef G_OS_WIN32
+-  res = GLIB_PRIVATE_CALL (g_win32_fstat) (fd, &original_stat);
++      res = GLIB_PRIVATE_CALL (g_win32_fstat) (fd, &original_stat);
+ #else
+-  res = fstat (fd, &original_stat);
++      res = fstat (fd, &original_stat);
+ #endif
+-  errsv = errno;
++      errsv = errno;
++    }
++  else
++    {
++#ifdef G_OS_WIN32
++      res = GLIB_PRIVATE_CALL (g_win32_lstat_utf8) (filename, &original_stat);
++#else
++      res = g_lstat (filename, &original_stat);
++#endif
++      errsv = errno;
++    }
+ 
+   if (res != 0)
+     {
+@@ -916,16 +934,27 @@ handle_overwrite_open (const char    *filename,
+   if (!S_ISREG (original_stat.st_mode))
+     {
+       if (S_ISDIR (original_stat.st_mode))
+-	g_set_error_literal (error,
+-                             G_IO_ERROR,
+-                             G_IO_ERROR_IS_DIRECTORY,
+-                             _("Target file is a directory"));
+-      else
+-	g_set_error_literal (error,
+-                             G_IO_ERROR,
+-                             G_IO_ERROR_NOT_REGULAR_FILE,
+-                             _("Target file is not a regular file"));
+-      goto err_out;
++        {
++          g_set_error_literal (error,
++                               G_IO_ERROR,
++                               G_IO_ERROR_IS_DIRECTORY,
++                               _("Target file is a directory"));
++          goto err_out;
++        }
++      else if (!is_symlink ||
++#ifdef S_ISLNK
++               !S_ISLNK (original_stat.st_mode)
++#else
++               FALSE
++#endif
++               )
++        {
++          g_set_error_literal (error,
++                               G_IO_ERROR,
++                               G_IO_ERROR_NOT_REGULAR_FILE,
++                               _("Target file is not a regular file"));
++          goto err_out;
++        }
+     }
+   
+   if (etag != NULL)
+@@ -1006,7 +1035,8 @@ handle_overwrite_open (const char    *filename,
+ 	    }
+ 	}
+ 
+-      g_close (fd, NULL);
++      if (fd >= 0)
++        g_close (fd, NULL);
+       *temp_filename = tmp_filename;
+       return tmpfd;
+     }
+diff --git a/gio/tests/file.c b/gio/tests/file.c
+index efb2eaadd..bc55f3af4 100644
+--- a/gio/tests/file.c
++++ b/gio/tests/file.c
+@@ -804,6 +804,113 @@ test_replace_cancel (void)
+   g_object_unref (tmpdir);
+ }
+ 
++static void
++test_replace_symlink (void)
++{
++#ifdef G_OS_UNIX
++  gchar *tmpdir_path = NULL;
++  GFile *tmpdir = NULL, *source_file = NULL, *target_file = NULL;
++  GFileOutputStream *stream = NULL;
++  const gchar *new_contents = "this is a test message which should be written to source and not target";
++  gsize n_written;
++  GFileEnumerator *enumerator = NULL;
++  GFileInfo *info = NULL;
++  gchar *contents = NULL;
++  gsize length = 0;
++  GError *local_error = NULL;
++
++  g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2325");
++  g_test_summary ("Test that G_FILE_CREATE_REPLACE_DESTINATION doesn’t follow symlinks");
++
++  /* Create a fresh, empty working directory. */
++  tmpdir_path = g_dir_make_tmp ("g_file_replace_symlink_XXXXXX", &local_error);
++  g_assert_no_error (local_error);
++  tmpdir = g_file_new_for_path (tmpdir_path);
++
++  g_test_message ("Using temporary directory %s", tmpdir_path);
++  g_free (tmpdir_path);
++
++  /* Create symlink `source` which points to `target`. */
++  source_file = g_file_get_child (tmpdir, "source");
++  target_file = g_file_get_child (tmpdir, "target");
++  g_file_make_symbolic_link (source_file, "target", NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  /* Ensure that `target` doesn’t exist */
++  g_assert_false (g_file_query_exists (target_file, NULL));
++
++  /* Replace the `source` symlink with a regular file using
++   * %G_FILE_CREATE_REPLACE_DESTINATION, which should replace it *without*
++   * following the symlink */
++  stream = g_file_replace (source_file, NULL, FALSE  /* no backup */,
++                           G_FILE_CREATE_REPLACE_DESTINATION, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_output_stream_write_all (G_OUTPUT_STREAM (stream), new_contents, strlen (new_contents),
++                             &n_written, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_assert_cmpint (n_written, ==, strlen (new_contents));
++
++  g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_clear_object (&stream);
++
++  /* At this point, there should still only be one file: `source`. It should
++   * now be a regular file. `target` should not exist. */
++  enumerator = g_file_enumerate_children (tmpdir,
++                                          G_FILE_ATTRIBUTE_STANDARD_NAME ","
++                                          G_FILE_ATTRIBUTE_STANDARD_TYPE,
++                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  info = g_file_enumerator_next_file (enumerator, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_assert_nonnull (info);
++
++  g_assert_cmpstr (g_file_info_get_name (info), ==, "source");
++  g_assert_cmpint (g_file_info_get_file_type (info), ==, G_FILE_TYPE_REGULAR);
++
++  g_clear_object (&info);
++
++  info = g_file_enumerator_next_file (enumerator, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_assert_null (info);
++
++  g_file_enumerator_close (enumerator, NULL, &local_error);
++  g_assert_no_error (local_error);
++  g_clear_object (&enumerator);
++
++  /* Double-check that `target` doesn’t exist */
++  g_assert_false (g_file_query_exists (target_file, NULL));
++
++  /* Check the content of `source`. */
++  g_file_load_contents (source_file,
++                        NULL,
++                        &contents,
++                        &length,
++                        NULL,
++                        &local_error);
++  g_assert_no_error (local_error);
++  g_assert_cmpstr (contents, ==, new_contents);
++  g_assert_cmpuint (length, ==, strlen (new_contents));
++  g_free (contents);
++
++  /* Tidy up. */
++  g_file_delete (source_file, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_file_delete (tmpdir, NULL, &local_error);
++  g_assert_no_error (local_error);
++
++  g_clear_object (&target_file);
++  g_clear_object (&source_file);
++  g_clear_object (&tmpdir);
++#else  /* if !G_OS_UNIX */
++  g_test_skip ("Symlink replacement tests can only be run on Unix")
++#endif
++}
++
+ static void
+ on_file_deleted (GObject      *object,
+ 		 GAsyncResult *result,
+@@ -1754,6 +1861,7 @@ main (int argc, char *argv[])
+   g_test_add_data_func ("/file/async-create-delete/4096", GINT_TO_POINTER (4096), test_create_delete);
+   g_test_add_func ("/file/replace-load", test_replace_load);
+   g_test_add_func ("/file/replace-cancel", test_replace_cancel);
++  g_test_add_func ("/file/replace-symlink", test_replace_symlink);
+   g_test_add_func ("/file/async-delete", test_async_delete);
+ #ifdef G_OS_UNIX
+   g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode);
+-- 
+2.30.1
+
diff --git a/gnu/packages/patches/glibc-ldd-powerpc.patch b/gnu/packages/patches/glibc-ldd-powerpc.patch
new file mode 100644
index 0000000000..8e899ee99b
--- /dev/null
+++ b/gnu/packages/patches/glibc-ldd-powerpc.patch
@@ -0,0 +1,10 @@
+diff -r -U3 a/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed b/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed
+--- a/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed	1970-01-01 01:00:00.000000000 +0100
++++ b/sysdeps/unix/sysv/linux/powerpc/ldd-rewrite.sed	2020-02-29 00:15:41.080000000 +0100
+@@ -11,5 +11,5 @@
+ # this works for /lib64/ld64.so.x and /lib/ld.so.x as input
+ s_lib64_lib_
+ s_64\.so_\.so_
+-s_^RTLDLIST=\(.*lib\)\(/[^/]*\)\(\.so\.[0-9.]*\)[[:blank:]]*$_RTLDLIST="\1\2\3 \164\264\3"_
++s_^RTLDLIST=\(.*lib\)\(/[^/]*\)\(\.so\.[0-9.]*\)[[:blank:]]*$_RTLDLIST="\1\2\3 \1\264\3"_
+ 
diff --git a/gnu/packages/patches/gnome-shell-CVE-2020-17489.patch b/gnu/packages/patches/gnome-shell-CVE-2020-17489.patch
new file mode 100644
index 0000000000..4b7748950e
--- /dev/null
+++ b/gnu/packages/patches/gnome-shell-CVE-2020-17489.patch
@@ -0,0 +1,46 @@
+From 05b7aec747282f62212b605249d518280ff80059 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode@redhat.com>
+Date: Mon, 27 Jul 2020 10:58:22 -0400
+Subject: [PATCH] loginDialog: Reset auth prompt on vt switch before fade in
+
+At the moment, if a user switches to the login screen vt,
+the login screen fades in whatever was on screen prior, and
+then does a reset.
+
+It makes more sense to reset first, so we fade in what the
+user is going to interact with instead of what they interacted
+with before.
+
+Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2997
+---
+ js/gdm/loginDialog.js | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
+index c3f90dc58..6b35ebb16 100644
+--- a/js/gdm/loginDialog.js
++++ b/js/gdm/loginDialog.js
+@@ -920,16 +920,15 @@ var LoginDialog = GObject.registerClass({
+         if (this.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
+             return;
+ 
++        if (this._authPrompt.verificationStatus !== AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
++            this._authPrompt.reset();
++
+         this._bindOpacity();
+         this.ease({
+             opacity: 255,
+             duration: _FADE_ANIMATION_TIME,
+             mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+-            onComplete: () => {
+-                if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
+-                    this._authPrompt.reset();
+-                this._unbindOpacity();
+-            }
++            onComplete: () => this._unbindOpacity(),
+         });
+     }
+ 
+-- 
+2.30.1
+
diff --git a/gnu/packages/patches/gnutls-CVE-2021-20231.patch b/gnu/packages/patches/gnutls-CVE-2021-20231.patch
new file mode 100644
index 0000000000..5186522eee
--- /dev/null
+++ b/gnu/packages/patches/gnutls-CVE-2021-20231.patch
@@ -0,0 +1,62 @@
+From 15beb4b193b2714d88107e7dffca781798684e7e Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno@gnu.org>
+Date: Fri, 29 Jan 2021 14:06:05 +0100
+Subject: [PATCH 1/2] key_share: avoid use-after-free around realloc
+
+Signed-off-by: Daiki Ueno <ueno@gnu.org>
+---
+ lib/ext/key_share.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/lib/ext/key_share.c b/lib/ext/key_share.c
+index ab8abf8fe..a8c4bb5cf 100644
+--- a/lib/ext/key_share.c
++++ b/lib/ext/key_share.c
+@@ -664,14 +664,14 @@ key_share_send_params(gnutls_session_t session,
+ {
+ 	unsigned i;
+ 	int ret;
+-	unsigned char *lengthp;
+-	unsigned int cur_length;
+ 	unsigned int generated = 0;
+ 	const gnutls_group_entry_st *group;
+ 	const version_entry_st *ver;
+ 
+ 	/* this extension is only being sent on client side */
+ 	if (session->security_parameters.entity == GNUTLS_CLIENT) {
++		unsigned int length_pos;
++
+ 		ver = _gnutls_version_max(session);
+ 		if (unlikely(ver == NULL || ver->key_shares == 0))
+ 			return 0;
+@@ -679,16 +679,13 @@ key_share_send_params(gnutls_session_t session,
+ 		if (!have_creds_for_tls13(session))
+ 			return 0;
+ 
+-		/* write the total length later */
+-		lengthp = &extdata->data[extdata->length];
++		length_pos = extdata->length;
+ 
+ 		ret =
+ 		    _gnutls_buffer_append_prefix(extdata, 16, 0);
+ 		if (ret < 0)
+ 			return gnutls_assert_val(ret);
+ 
+-		cur_length = extdata->length;
+-
+ 		if (session->internals.hsk_flags & HSK_HRR_RECEIVED) { /* we know the group */
+ 			group = get_group(session);
+ 			if (unlikely(group == NULL))
+@@ -736,7 +733,8 @@ key_share_send_params(gnutls_session_t session,
+ 		}
+ 
+ 		/* copy actual length */
+-		_gnutls_write_uint16(extdata->length - cur_length, lengthp);
++		_gnutls_write_uint16(extdata->length - length_pos - 2,
++				     &extdata->data[length_pos]);
+ 
+ 	} else { /* server */
+ 		ver = get_version(session);
+-- 
+2.30.2
+
diff --git a/gnu/packages/patches/gnutls-CVE-2021-20232.patch b/gnu/packages/patches/gnutls-CVE-2021-20232.patch
new file mode 100644
index 0000000000..dc3a0be690
--- /dev/null
+++ b/gnu/packages/patches/gnutls-CVE-2021-20232.patch
@@ -0,0 +1,60 @@
+From 75a937d97f4fefc6f9b08e3791f151445f551cb3 Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno@gnu.org>
+Date: Fri, 29 Jan 2021 14:06:23 +0100
+Subject: [PATCH 2/2] pre_shared_key: avoid use-after-free around realloc
+
+Signed-off-by: Daiki Ueno <ueno@gnu.org>
+---
+ lib/ext/pre_shared_key.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/lib/ext/pre_shared_key.c b/lib/ext/pre_shared_key.c
+index a042c6488..380bf39ed 100644
+--- a/lib/ext/pre_shared_key.c
++++ b/lib/ext/pre_shared_key.c
+@@ -267,7 +267,7 @@ client_send_params(gnutls_session_t session,
+ 	size_t spos;
+ 	gnutls_datum_t username = {NULL, 0};
+ 	gnutls_datum_t user_key = {NULL, 0}, rkey = {NULL, 0};
+-	gnutls_datum_t client_hello;
++	unsigned client_hello_len;
+ 	unsigned next_idx;
+ 	const mac_entry_st *prf_res = NULL;
+ 	const mac_entry_st *prf_psk = NULL;
+@@ -428,8 +428,7 @@ client_send_params(gnutls_session_t session,
+ 	assert(extdata->length >= sizeof(mbuffer_st));
+ 	assert(ext_offset >= (ssize_t)sizeof(mbuffer_st));
+ 	ext_offset -= sizeof(mbuffer_st);
+-	client_hello.data = extdata->data+sizeof(mbuffer_st);
+-	client_hello.size = extdata->length-sizeof(mbuffer_st);
++	client_hello_len = extdata->length-sizeof(mbuffer_st);
+ 
+ 	next_idx = 0;
+ 
+@@ -440,6 +439,11 @@ client_send_params(gnutls_session_t session,
+ 	}
+ 
+ 	if (prf_res && rkey.size > 0) {
++		gnutls_datum_t client_hello;
++
++		client_hello.data = extdata->data+sizeof(mbuffer_st);
++		client_hello.size = client_hello_len;
++
+ 		ret = compute_psk_binder(session, prf_res,
+ 					 binders_len, binders_pos,
+ 					 ext_offset, &rkey, &client_hello, 1,
+@@ -474,6 +478,11 @@ client_send_params(gnutls_session_t session,
+ 	}
+ 
+ 	if (prf_psk && user_key.size > 0 && info) {
++		gnutls_datum_t client_hello;
++
++		client_hello.data = extdata->data+sizeof(mbuffer_st);
++		client_hello.size = client_hello_len;
++
+ 		ret = compute_psk_binder(session, prf_psk,
+ 					 binders_len, binders_pos,
+ 					 ext_offset, &user_key, &client_hello, 0,
+-- 
+2.30.2
+
diff --git a/gnu/packages/patches/hplip-remove-imageprocessor.patch b/gnu/packages/patches/hplip-remove-imageprocessor.patch
index cde3ecba2d..c9d27a4d1d 100644
--- a/gnu/packages/patches/hplip-remove-imageprocessor.patch
+++ b/gnu/packages/patches/hplip-remove-imageprocessor.patch
@@ -1,4 +1,5 @@
-This patch is based heavily on the Debian patch.
+This patch is based heavily on the Debian patch, but was updated to
+apply to subsequent upstream changes not yet in Debian.
 
 https://salsa.debian.org/printing-team/hplip/raw/debian/3.18.10+dfsg0-1/debian/patches/0025-Remove-all-ImageProcessor-functionality-which-is-clo.patch
 
@@ -175,55 +176,67 @@ index 5b282d8..0bacfaf 100644
  
  #include <signal.h>
  #include <sys/wait.h>
-@@ -637,16 +636,10 @@ int HPCupsFilter::processRasterData(cups_raster_t *cups_raster)
- 
+@@ -651,21 +650,8 @@
  
      sprintf(hpPreProcessedRasterFile, "%s/hp_%s_cups_SwapedPagesXXXXXX",CUPS_TMP_DIR, m_JA.user_name);
--    image_processor_t* imageProcessor = imageProcessorCreate();
- 
+  
+-    image_processor_t* imageProcessor=NULL;
+-    IMAGE_PROCESSOR_ERROR result;
+-    //added if condition to check if pinter language is "ljzjstream"
+-    //If so, then bypass imageprocessing functions while running HPCUPS filter.
+-    if(strncmp(m_JA.printer_platform, "ljzjstream",10) == 0){
+-        imageProcessor = imageProcessorCreate();
+-    }
      while (cupsRasterReadHeader2(cups_raster, &cups_header))
      {
- 
--        IMAGE_PROCESSOR_ERROR result = imageProcessorStartPage(imageProcessor, &cups_header);
+-       if(strncmp(m_JA.printer_platform, "ljzjstream",10) == 0){
+-        result = imageProcessorStartPage(imageProcessor, &cups_header);
 -        if (result != IPE_SUCCESS){
 -            dbglog("DEBUG: imageProcessorStartPage failed result = %d\n", result);
 -        }
--
+-     }
          current_page_number++;
  
          if (current_page_number == 1) {
-@@ -745,12 +738,6 @@ int HPCupsFilter::processRasterData(cups_raster_t *cups_raster)
+@@ -764,14 +750,6 @@
              color_raster = rgbRaster;
              black_raster = kRaster;
  
+-	if(strncmp(m_JA.printer_platform, "ljzjstream",10) == 0)
+-	{
 -            result = imageProcessorProcessLine(imageProcessor, m_pPrinterBuffer, cups_header.cupsBytesPerLine);
 -            if (result != IPE_SUCCESS){
 -                dbglog("DEBUG: imageProcessorProcessLine failed result = %d\n", result);
 -            }
--
+-	}
 -
              if ((y == 0) && !is_ljmono) {
                  //For ljmono, make sure that first line is not a blankRaster line.Otherwise printer
                  //may not skip blank lines before actual data
-@@ -780,12 +767,6 @@ int HPCupsFilter::processRasterData(cups_raster_t *cups_raster)
+@@ -801,14 +779,6 @@
              }
          }  // for() loop end
  
+-	if(strncmp(m_JA.printer_platform, "ljzjstream",10) == 0)
+-	{
 -        result = imageProcessorEndPage(imageProcessor);
 -        if (result != IPE_SUCCESS){
 -                dbglog("DEBUG: imageProcessorEndPage failed result = %d\n", result);
 -        }
--
+-	}
 -
          m_Job.NewPage();
          if (err != NO_ERROR) {
              break;
-@@ -800,8 +781,6 @@ int HPCupsFilter::processRasterData(cups_raster_t *cups_raster)
+@@ -823,11 +793,6 @@
          rgbRaster = NULL;
      }
  
+- 
+-   if(strncmp(m_JA.printer_platform, "ljzjstream",10) == 0)
+-   {
 -    imageProcessorDestroy(imageProcessor);
--
+-   }
      unlink(hpPreProcessedRasterFile);
      return ret_status;
  }
diff --git a/gnu/packages/patches/libcaca-CVE-2021-3410-pt1.patch b/gnu/packages/patches/libcaca-CVE-2021-3410-pt1.patch
new file mode 100644
index 0000000000..b23b01d33a
--- /dev/null
+++ b/gnu/packages/patches/libcaca-CVE-2021-3410-pt1.patch
@@ -0,0 +1,137 @@
+https://github.com/cacalabs/libcaca/commit/46b4ea7cea72d6b3ffe65d33e604b1774dcc2bbd.patch
+
+From 46b4ea7cea72d6b3ffe65d33e604b1774dcc2bbd Mon Sep 17 00:00:00 2001
+From: Sam Hocevar <sam@hocevar.net>
+Date: Fri, 26 Feb 2021 10:55:38 +0100
+Subject: [PATCH] canvas: fix an integer overflow in caca_resize().
+
+Fixes: #52 (CVE-2021-3410)
+---
+ caca/canvas.c       | 13 +++++++++++--
+ caca/codec/import.c |  1 +
+ caca/codec/text.c   | 21 ++++++++++++++-------
+ 3 files changed, 26 insertions(+), 9 deletions(-)
+
+diff --git a/caca/canvas.c b/caca/canvas.c
+index 3fdd37ae..d0715392 100644
+--- a/caca/canvas.c
++++ b/caca/canvas.c
+@@ -45,6 +45,7 @@ static int caca_resize(caca_canvas_t *, int, int);
+  *
+  *  If an error occurs, NULL is returned and \b errno is set accordingly:
+  *  - \c EINVAL Specified width or height is invalid.
++ *  - \c EOVERFLOW Specified width and height overflowed.
+  *  - \c ENOMEM Not enough memory for the requested canvas size.
+  *
+  *  \param width The desired canvas width
+@@ -200,6 +201,7 @@ int caca_unmanage_canvas(caca_canvas_t *cv, int (*callback)(void *), void *p)
+  *
+  *  If an error occurs, -1 is returned and \b errno is set accordingly:
+  *  - \c EINVAL Specified width or height is invalid.
++ *  - \c EOVERFLOW Specified width and height overflowed.
+  *  - \c EBUSY The canvas is in use by a display driver and cannot be resized.
+  *  - \c ENOMEM Not enough memory for the requested canvas size. If this
+  *    happens, the canvas handle becomes invalid and should not be used.
+@@ -363,7 +365,7 @@ int caca_rand(int min, int max)
+ 
+ int caca_resize(caca_canvas_t *cv, int width, int height)
+ {
+-    int x, y, f, old_width, old_height, new_size, old_size;
++    int x, y, f, old_width, old_height, old_size;
+ 
+     old_width = cv->width;
+     old_height = cv->height;
+@@ -375,7 +377,14 @@ int caca_resize(caca_canvas_t *cv, int width, int height)
+      * dirty rectangle handling */
+     cv->width = width;
+     cv->height = height;
+-    new_size = width * height;
++    int new_size = width * height;
++
++    /* Check for overflow */
++    if (new_size / width != height)
++    {
++        seterrno(EOVERFLOW);
++        return -1;
++    }
+ 
+     /* If width or height is smaller (or both), we have the opportunity to
+      * reduce or even remove dirty rectangles */
+diff --git a/caca/codec/import.c b/caca/codec/import.c
+index 8836fd08..2dafe3cf 100644
+--- a/caca/codec/import.c
++++ b/caca/codec/import.c
+@@ -61,6 +61,7 @@ static ssize_t import_caca(caca_canvas_t *, void const *, size_t);
+  *
+  *  If an error occurs, -1 is returned and \b errno is set accordingly:
+  *  - \c ENOMEM Not enough memory to allocate canvas.
++ *  - \c EOVERFLOW Importing data caused a value overflow.
+  *  - \c EINVAL Invalid format requested.
+  *
+  *  \param cv A libcaca canvas in which to import the file.
+diff --git a/caca/codec/text.c b/caca/codec/text.c
+index 358b7224..94a2a4d7 100644
+--- a/caca/codec/text.c
++++ b/caca/codec/text.c
+@@ -46,7 +46,7 @@ ssize_t _import_text(caca_canvas_t *cv, void const *data, size_t size)
+     char const *text = (char const *)data;
+     unsigned int width = 0, height = 0, x = 0, y = 0, i;
+ 
+-    caca_set_canvas_size(cv, width, height);
++    caca_set_canvas_size(cv, 0, 0);
+ 
+     for(i = 0; i < size; i++)
+     {
+@@ -70,15 +70,19 @@ ssize_t _import_text(caca_canvas_t *cv, void const *data, size_t size)
+             if(y >= height)
+                 height = y + 1;
+ 
+-            caca_set_canvas_size(cv, width, height);
++            if (caca_set_canvas_size(cv, width, height) < 0)
++                return -1;
+         }
+ 
+         caca_put_char(cv, x, y, ch);
+         x++;
+     }
+ 
+-    if(y > height)
+-        caca_set_canvas_size(cv, width, height = y);
++    if (y > height)
++    {
++        if (caca_set_canvas_size(cv, width, height = y) < 0)
++            return -1;
++    }
+ 
+     return (ssize_t)size;
+ }
+@@ -431,7 +435,8 @@ ssize_t _import_ansi(caca_canvas_t *cv, void const *data, size_t size, int utf8)
+             {
+                 savedattr = caca_get_attr(cv, -1, -1);
+                 caca_set_attr(cv, im.clearattr);
+-                caca_set_canvas_size(cv, width = x + wch, height);
++                if (caca_set_canvas_size(cv, width = x + wch, height) < 0)
++                    return -1;
+                 caca_set_attr(cv, savedattr);
+             }
+             else
+@@ -448,7 +453,8 @@ ssize_t _import_ansi(caca_canvas_t *cv, void const *data, size_t size, int utf8)
+             caca_set_attr(cv, im.clearattr);
+             if(growy)
+             {
+-                caca_set_canvas_size(cv, width, height = y + 1);
++                if (caca_set_canvas_size(cv, width, height = y + 1) < 0)
++                    return -1;
+             }
+             else
+             {
+@@ -480,7 +486,8 @@ ssize_t _import_ansi(caca_canvas_t *cv, void const *data, size_t size, int utf8)
+     {
+         savedattr = caca_get_attr(cv, -1, -1);
+         caca_set_attr(cv, im.clearattr);
+-        caca_set_canvas_size(cv, width, height = y);
++        if (caca_set_canvas_size(cv, width, height = y))
++            return -1;
+         caca_set_attr(cv, savedattr);
+     }
+ 
diff --git a/gnu/packages/patches/libcaca-CVE-2021-3410-pt2.patch b/gnu/packages/patches/libcaca-CVE-2021-3410-pt2.patch
new file mode 100644
index 0000000000..e6fd506b37
--- /dev/null
+++ b/gnu/packages/patches/libcaca-CVE-2021-3410-pt2.patch
@@ -0,0 +1,96 @@
+https://github.com/cacalabs/libcaca/commit/e4968ba6e93e9fd35429eb16895c785c51072015.patch
+Patch adjusted to remove the lines modifying caca/t/canvas.cpp. This file does not exist in the current release.
+
+From e4968ba6e93e9fd35429eb16895c785c51072015 Mon Sep 17 00:00:00 2001
+From: Sam Hocevar <sam@hocevar.net>
+Date: Fri, 26 Feb 2021 12:40:06 +0100
+Subject: [PATCH] Fix a problem in the caca_resize() overflow detection and add
+ several unit tests.
+
+---
+ caca/canvas.c     | 16 ++++++++--------
+ caca/t/canvas.cpp | 18 +++++++++++++++---
+ tools/makefont.c  | 22 +++++++++++++++++++---
+ 3 files changed, 42 insertions(+), 14 deletions(-)
+
+diff --git a/caca/canvas.c b/caca/canvas.c
+index d0715392..08c628c9 100644
+--- a/caca/canvas.c
++++ b/caca/canvas.c
+@@ -367,6 +367,14 @@ int caca_resize(caca_canvas_t *cv, int width, int height)
+ {
+     int x, y, f, old_width, old_height, old_size;
+ 
++    /* Check for overflow */
++    int new_size = width * height;
++    if (new_size < 0 || (width > 0 && new_size / width != height))
++    {
++        seterrno(EOVERFLOW);
++        return -1;
++    }
++
+     old_width = cv->width;
+     old_height = cv->height;
+     old_size = old_width * old_height;
+@@ -377,14 +385,6 @@ int caca_resize(caca_canvas_t *cv, int width, int height)
+      * dirty rectangle handling */
+     cv->width = width;
+     cv->height = height;
+-    int new_size = width * height;
+-
+-    /* Check for overflow */
+-    if (new_size / width != height)
+-    {
+-        seterrno(EOVERFLOW);
+-        return -1;
+-    }
+ 
+     /* If width or height is smaller (or both), we have the opportunity to
+      * reduce or even remove dirty rectangles */
+diff --git a/tools/makefont.c b/tools/makefont.c
+index 226c8838..66718605 100644
+--- a/tools/makefont.c
++++ b/tools/makefont.c
+@@ -40,7 +40,8 @@
+  * and the UTF-8 glyphs necessary for canvas rotation and mirroring. */
+ static unsigned int const blocklist[] =
+ {
+-    0x0000, 0x0080, /* Basic latin: A, B, C, a, b, c */
++    0x0020, 0x0080, /* Basic latin: A, B, C, a, b, c */
++#if 0
+     0x0080, 0x0100, /* Latin-1 Supplement: Ä, Ç, å, ß */
+     0x0100, 0x0180, /* Latin Extended-A: Ā č Ō œ */
+     0x0180, 0x0250, /* Latin Extended-B: Ǝ Ƹ */
+@@ -63,6 +64,7 @@ static unsigned int const blocklist[] =
+     0x30a0, 0x3100, /* Katakana: ロ ル */
+     0xff00, 0xfff0, /* Halfwidth and Fullwidth Forms: A, B, C, a, b, c */
+     0x10400, 0x10450, /* Deseret: 𐐒 𐐋 */
++#endif
+     0, 0
+ };
+ 
+@@ -317,8 +319,22 @@ int main(int argc, char *argv[])
+             printf_unicode(&gtab[n]);
+ 
+             if(gtab[n].same_as == n)
+-                printf_hex(" */ %s\n",
+-                           glyph_data + gtab[n].data_offset, gtab[n].data_size);
++            {
++                char const *lut = " .:nmW@";
++                printf("\n");
++                for (int y = 0; y < height; ++y)
++                {
++                    for (int x = 0; x < gtab[n].data_width; ++x)
++                    {
++                        int val = glyph_data[gtab[n].data_offset + y * gtab[n].data_width + x];
++                        char ch = lut[val * val * 7 / 256 / 256];
++                        printf("%c%c", ch, ch);
++                    }
++                    printf("\n");
++                }
++                //printf_hex(" */ %s\n",
++                //           glyph_data + gtab[n].data_offset, gtab[n].data_size);
++            }
+             else
+             {
+                 printf(" is ");
diff --git a/gnu/packages/patches/libcroco-CVE-2020-12825.patch b/gnu/packages/patches/libcroco-CVE-2020-12825.patch
new file mode 100644
index 0000000000..35005a6a19
--- /dev/null
+++ b/gnu/packages/patches/libcroco-CVE-2020-12825.patch
@@ -0,0 +1,187 @@
+From 7b64eb285dd937b34df71c95188301be50dd1409 Mon Sep 17 00:00:00 2001
+From: Michael Catanzaro <mcatanzaro@gnome.org>
+Date: Wed, 12 Aug 2020 13:54:15 -0500
+Subject: [PATCH] libcroco: Limit recursion in block and any productions
+ (CVE-2020-12825)
+
+If we don't have any limits, we can recurse forever and overflow the
+stack.
+
+This is per https://gitlab.gnome.org/Archive/libcroco/-/issues/8
+
+https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1404
+---
+ src/st/croco/cr-parser.c | 44 ++++++++++++++++++++++++++--------------
+ 1 file changed, 29 insertions(+), 15 deletions(-)
+
+diff --git a/src/st/croco/cr-parser.c b/src/st/croco/cr-parser.c
+index 07f4ed9e8b..8304b75614 100644
+--- a/src/cr-parser.c
++++ b/src/cr-parser.c
+@@ -136,6 +136,8 @@ struct _CRParserPriv {
+ 
+ #define CHARS_TAB_SIZE 12
+ 
++#define RECURSIVE_CALLERS_LIMIT 100
++
+ /**
+  * IS_NUM:
+  *@a_char: the char to test.
+@@ -343,9 +345,11 @@ static enum CRStatus cr_parser_parse_selector_core (CRParser * a_this);
+ 
+ static enum CRStatus cr_parser_parse_declaration_core (CRParser * a_this);
+ 
+-static enum CRStatus cr_parser_parse_any_core (CRParser * a_this);
++static enum CRStatus cr_parser_parse_any_core (CRParser * a_this,
++                                               guint      n_calls);
+ 
+-static enum CRStatus cr_parser_parse_block_core (CRParser * a_this);
++static enum CRStatus cr_parser_parse_block_core (CRParser * a_this,
++                                                 guint      n_calls);
+ 
+ static enum CRStatus cr_parser_parse_value_core (CRParser * a_this);
+ 
+@@ -783,7 +787,7 @@ cr_parser_parse_atrule_core (CRParser * a_this)
+         cr_parser_try_to_skip_spaces_and_comments (a_this);
+ 
+         do {
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, 0);
+         } while (status == CR_OK);
+ 
+         status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr,
+@@ -794,7 +798,7 @@ cr_parser_parse_atrule_core (CRParser * a_this)
+                 cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, 
+                                       token);
+                 token = NULL;
+-                status = cr_parser_parse_block_core (a_this);
++                status = cr_parser_parse_block_core (a_this, 0);
+                 CHECK_PARSING_STATUS (status,
+                                       FALSE);
+                 goto done;
+@@ -929,11 +933,11 @@ cr_parser_parse_selector_core (CRParser * a_this)
+ 
+         RECORD_INITIAL_POS (a_this, &init_pos);
+ 
+-        status = cr_parser_parse_any_core (a_this);
++        status = cr_parser_parse_any_core (a_this, 0);
+         CHECK_PARSING_STATUS (status, FALSE);
+ 
+         do {
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, 0);
+ 
+         } while (status == CR_OK);
+ 
+@@ -955,10 +959,12 @@ cr_parser_parse_selector_core (CRParser * a_this)
+  *in chapter 4.1 of the css2 spec.
+  *block ::= '{' S* [ any | block | ATKEYWORD S* | ';' ]* '}' S*;
+  *@param a_this the current instance of #CRParser.
++ *@param n_calls used to limit recursion depth
+  *FIXME: code this function.
+  */
+ static enum CRStatus
+-cr_parser_parse_block_core (CRParser * a_this)
++cr_parser_parse_block_core (CRParser * a_this,
++                            guint      n_calls)
+ {
+         CRToken *token = NULL;
+         CRInputPos init_pos;
+@@ -966,6 +972,9 @@ cr_parser_parse_block_core (CRParser * a_this)
+ 
+         g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR);
+ 
++        if (n_calls > RECURSIVE_CALLERS_LIMIT)
++                return CR_ERROR;
++
+         RECORD_INITIAL_POS (a_this, &init_pos);
+ 
+         status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token);
+@@ -995,13 +1004,13 @@ cr_parser_parse_block_core (CRParser * a_this)
+         } else if (token->type == CBO_TK) {
+                 cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token);
+                 token = NULL;
+-                status = cr_parser_parse_block_core (a_this);
++                status = cr_parser_parse_block_core (a_this, n_calls + 1);
+                 CHECK_PARSING_STATUS (status, FALSE);
+                 goto parse_block_content;
+         } else {
+                 cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token);
+                 token = NULL;
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, n_calls + 1);
+                 CHECK_PARSING_STATUS (status, FALSE);
+                 goto parse_block_content;
+         }
+@@ -1108,7 +1117,7 @@ cr_parser_parse_value_core (CRParser * a_this)
+                 status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr,
+                                                token);
+                 token = NULL;
+-                status = cr_parser_parse_block_core (a_this);
++                status = cr_parser_parse_block_core (a_this, 0);
+                 CHECK_PARSING_STATUS (status, FALSE);
+                 ref++;
+                 goto continue_parsing;
+@@ -1122,7 +1131,7 @@ cr_parser_parse_value_core (CRParser * a_this)
+                 status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr,
+                                                token);
+                 token = NULL;
+-                status = cr_parser_parse_any_core (a_this);
++                status = cr_parser_parse_any_core (a_this, 0);
+                 if (status == CR_OK) {
+                         ref++;
+                         goto continue_parsing;
+@@ -1161,10 +1170,12 @@ cr_parser_parse_value_core (CRParser * a_this)
+  *        | FUNCTION | DASHMATCH | '(' any* ')' | '[' any* ']' ] S*;
+  *
+  *@param a_this the current instance of #CRParser.
++ *@param n_calls used to limit recursion depth
+  *@return CR_OK upon successfull completion, an error code otherwise.
+  */
+ static enum CRStatus
+-cr_parser_parse_any_core (CRParser * a_this)
++cr_parser_parse_any_core (CRParser * a_this,
++                          guint      n_calls)
+ {
+         CRToken *token1 = NULL,
+                 *token2 = NULL;
+@@ -1173,6 +1184,9 @@ cr_parser_parse_any_core (CRParser * a_this)
+ 
+         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
+ 
++        if (n_calls > RECURSIVE_CALLERS_LIMIT)
++                return CR_ERROR;
++
+         RECORD_INITIAL_POS (a_this, &init_pos);
+ 
+         status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token1);
+@@ -1211,7 +1225,7 @@ cr_parser_parse_any_core (CRParser * a_this)
+                  *We consider parameter as being an "any*" production.
+                  */
+                 do {
+-                        status = cr_parser_parse_any_core (a_this);
++                        status = cr_parser_parse_any_core (a_this, n_calls + 1);
+                 } while (status == CR_OK);
+ 
+                 ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
+@@ -1236,7 +1250,7 @@ cr_parser_parse_any_core (CRParser * a_this)
+                 }
+ 
+                 do {
+-                        status = cr_parser_parse_any_core (a_this);
++                        status = cr_parser_parse_any_core (a_this, n_calls + 1);
+                 } while (status == CR_OK);
+ 
+                 ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
+@@ -1264,7 +1278,7 @@ cr_parser_parse_any_core (CRParser * a_this)
+                 }
+ 
+                 do {
+-                        status = cr_parser_parse_any_core (a_this);
++                        status = cr_parser_parse_any_core (a_this, n_calls + 1);
+                 } while (status == CR_OK);
+ 
+                 ENSURE_PARSING_COND (status == CR_PARSING_ERROR);
+-- 
+GitLab
+
diff --git a/gnu/packages/patches/mongodb-support-unknown-linux-distributions.patch b/gnu/packages/patches/mongodb-support-unknown-linux-distributions.patch
deleted file mode 100644
index 6057ebeb08..0000000000
--- a/gnu/packages/patches/mongodb-support-unknown-linux-distributions.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From e724bb7018a482640c4f194f88b554af2c59d76e Mon Sep 17 00:00:00 2001
-From: Mark Benvenuto <mark.benvenuto@mongodb.com>
-Date: Wed, 20 Sep 2017 11:50:02 -0400
-Subject: [PATCH] SERVER-30857 Support unknown Linux distributions
-
----
- src/mongo/rpc/metadata/client_metadata.cpp | 6 ------
- src/mongo/util/processinfo_linux.cpp       | 9 ++++++---
- 2 files changed, 6 insertions(+), 9 deletions(-)
-
-diff --git a/src/mongo/rpc/metadata/client_metadata.cpp b/src/mongo/rpc/metadata/client_metadata.cpp
-index 845a315dd74..a959a4e31e9 100644
---- a/src/mongo/rpc/metadata/client_metadata.cpp
-+++ b/src/mongo/rpc/metadata/client_metadata.cpp
-@@ -302,9 +302,6 @@ void ClientMetadata::serializePrivate(StringData driverName,
-                                       StringData osArchitecture,
-                                       StringData osVersion,
-                                       BSONObjBuilder* builder) {
--    invariant(!driverName.empty() && !driverVersion.empty() && !osType.empty() && !osName.empty() &&
--              !osArchitecture.empty() && !osVersion.empty());
--
-     BSONObjBuilder metaObjBuilder(builder->subobjStart(kMetadataDocumentName));
- 
-     {
-@@ -347,9 +344,6 @@ Status ClientMetadata::serializePrivate(StringData driverName,
-                                         StringData osVersion,
-                                         StringData appName,
-                                         BSONObjBuilder* builder) {
--    invariant(!driverName.empty() && !driverVersion.empty() && !osType.empty() && !osName.empty() &&
--              !osArchitecture.empty() && !osVersion.empty());
--
-     if (appName.size() > kMaxApplicationNameByteLength) {
-         return Status(ErrorCodes::ClientMetadataAppNameTooLarge,
-                       str::stream() << "The '" << kApplication << "." << kName
-diff --git a/src/mongo/util/processinfo_linux.cpp b/src/mongo/util/processinfo_linux.cpp
-index c3debf377bd..c2813b026b0 100644
---- a/src/mongo/util/processinfo_linux.cpp
-+++ b/src/mongo/util/processinfo_linux.cpp
-@@ -376,10 +376,13 @@ class LinuxSysHelper {
-             if ((nl = name.find('\n', nl)) != string::npos)
-                 // stop at first newline
-                 name.erase(nl);
--            // no standard format for name and version.  use kernel version
--            version = "Kernel ";
--            version += LinuxSysHelper::readLineFromFile("/proc/sys/kernel/osrelease");
-+        } else {
-+            name = "unknown";
-         }
-+
-+        // There is no standard format for name and version so use the kernel version.
-+        version = "Kernel ";
-+        version += LinuxSysHelper::readLineFromFile("/proc/sys/kernel/osrelease");
-     }
- 
-     /**
diff --git a/gnu/packages/patches/mpg321-CVE-2019-14247.patch b/gnu/packages/patches/mpg321-CVE-2019-14247.patch
new file mode 100644
index 0000000000..03afaccc67
--- /dev/null
+++ b/gnu/packages/patches/mpg321-CVE-2019-14247.patch
@@ -0,0 +1,23 @@
+This patch was downloaded from https://sourceforge.net/p/mpg321/bugs/51/ and
+fixes CVE-2019-14247.
+
+Description: Handle illegal bitrate value
+Author: Chrysostomos Nanakos <cnanakos@debian.org>
+Bug-Debian: https://bugs.debian.org/870406
+Bug-Debian: https://bugs.debian.org/887057
+
+--- mpg321-0.3.2.orig/mad.c
++++ mpg321-0.3.2/mad.c
+@@ -574,6 +574,12 @@ void scan(void const *ptr, ssize_t len,
+ 
+     if (!is_vbr)
+     {
++	if (header.bitrate <= 0)                                                
++        {                                                                       
++            fprintf(stderr, "Illegal bit allocation value\n");                                                                              
++            return;                                                             
++        }    
++
+         double time = (len * 8.0) / (header.bitrate); /* time in seconds */
+         double timefrac = (double)time - ((long)(time));
+         long nsamples = 32 * MAD_NSBSAMPLES(&header); /* samples per frame */
diff --git a/gnu/packages/patches/ppsspp-disable-upgrade-and-gold.patch b/gnu/packages/patches/ppsspp-disable-upgrade-and-gold.patch
index 9503ab6f31..760ab97568 100644
--- a/gnu/packages/patches/ppsspp-disable-upgrade-and-gold.patch
+++ b/gnu/packages/patches/ppsspp-disable-upgrade-and-gold.patch
@@ -1,28 +1,28 @@
-From 951f2269f67d618d376656db831796c119f4f6b3 Mon Sep 17 00:00:00 2001
+From 0c57874ebb5982154da127ae338f9190b1581804 Mon Sep 17 00:00:00 2001
 From: Leo Prikler <leo.prikler@student.tugraz.at>
 Date: Fri, 26 Jun 2020 18:20:04 +0200
 Subject: [PATCH] ppsspp: disable upgrade and gold
 
 ---
- Core/Config.cpp             | 11 -------
+ Core/Config.cpp             | 11 ------
  Core/Config.h               |  2 --
  Qt/QtMain.cpp               |  6 ----
  SDL/SDLMain.cpp             |  6 ----
  UI/DevScreens.cpp           |  3 --
  UI/GameSettingsScreen.cpp   |  1 -
- UI/MainScreen.cpp           | 63 +------------------------------------
- UI/MiscScreens.cpp          | 31 ++----------------
+ UI/MainScreen.cpp           | 70 +------------------------------------
+ UI/MiscScreens.cpp          | 31 ++--------------
  UWP/PPSSPP_UWPMain.cpp      |  6 ----
  Windows/MainWindowMenu.cpp  |  2 +-
  Windows/main.cpp            |  6 ----
  android/jni/app-android.cpp |  6 ----
- 12 files changed, 5 insertions(+), 138 deletions(-)
+ 12 files changed, 5 insertions(+), 145 deletions(-)
 
 diff --git a/Core/Config.cpp b/Core/Config.cpp
-index 214aeb433..04e3b151d 100644
+index 1c53e8e57..2fa74a6b8 100644
 --- a/Core/Config.cpp
 +++ b/Core/Config.cpp
-@@ -428,7 +428,6 @@ static ConfigSetting generalSettings[] = {
+@@ -439,7 +439,6 @@ static ConfigSetting generalSettings[] = {
  	ConfigSetting("IgnoreBadMemAccess", &g_Config.bIgnoreBadMemAccess, true, true),
  	ConfigSetting("CurrentDirectory", &g_Config.currentDirectory, ""),
  	ConfigSetting("ShowDebuggerOnLoad", &g_Config.bShowDebuggerOnLoad, false),
@@ -30,7 +30,7 @@ index 214aeb433..04e3b151d 100644
  	ConfigSetting("Language", &g_Config.sLanguageIni, &DefaultLangRegion),
  	ConfigSetting("ForceLagSync2", &g_Config.bForceLagSync, false, true, true),
  	ConfigSetting("DiscordPresence", &g_Config.bDiscordPresence, true, true, false),  // Or maybe it makes sense to have it per-game? Race conditions abound...
-@@ -1229,16 +1228,6 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
+@@ -1293,16 +1292,6 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
  		upgradeMessage = "";
  	}
  
@@ -48,29 +48,29 @@ index 214aeb433..04e3b151d 100644
  	bSaveSettings = true;
  
 diff --git a/Core/Config.h b/Core/Config.h
-index 084eacc94..e7134cab5 100644
+index 13bce8a36..70d6c8aaf 100644
 --- a/Core/Config.h
 +++ b/Core/Config.h
-@@ -99,7 +99,6 @@ struct Config {
- 	bool bIgnoreBadMemAccess;
+@@ -101,7 +101,6 @@ struct Config {
+ 
  	bool bFastMemory;
  	int iCpuCore;
 -	bool bCheckForNewVersion;
  	bool bForceLagSync;
  	bool bFuncReplacements;
  	bool bHideSlowWarnings;
-@@ -521,4 +520,3 @@ std::string CreateRandMAC();
+@@ -540,4 +539,3 @@ std::string CreateRandMAC();
  // TODO: Find a better place for this.
  extern http::Downloader g_DownloadManager;
  extern Config g_Config;
 -
 diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp
-index 7713b6587..1d92d1175 100644
+index 5be0cefa0..b11cb1c64 100644
 --- a/Qt/QtMain.cpp
 +++ b/Qt/QtMain.cpp
-@@ -194,12 +194,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
- 		return true;
+@@ -218,12 +218,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
  	case SYSPROP_HAS_FILE_BROWSER:
+ 	case SYSPROP_HAS_FOLDER_BROWSER:
  		return true;
 -	case SYSPROP_APP_GOLD:
 -#ifdef GOLD
@@ -82,10 +82,10 @@ index 7713b6587..1d92d1175 100644
  		return false;
  	}
 diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp
-index 52028d087..d8697d210 100644
+index 98b56fe91..6af0fcb1a 100644
 --- a/SDL/SDLMain.cpp
 +++ b/SDL/SDLMain.cpp
-@@ -356,12 +356,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
+@@ -380,12 +380,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
  	switch (prop) {
  	case SYSPROP_HAS_BACK_BUTTON:
  		return true;
@@ -99,10 +99,10 @@ index 52028d087..d8697d210 100644
  		return false;
  	}
 diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp
-index f146d099e..625ee124c 100644
+index 8daac5bc8..c0c09ce79 100644
 --- a/UI/DevScreens.cpp
 +++ b/UI/DevScreens.cpp
-@@ -603,9 +603,6 @@ void SystemInfoScreen::CreateViews() {
+@@ -605,9 +605,6 @@ void SystemInfoScreen::CreateViews() {
  #ifdef _M_SSE
  	buildConfig->Add(new InfoItem("_M_SSE", StringFromFormat("0x%x", _M_SSE)));
  #endif
@@ -113,35 +113,35 @@ index f146d099e..625ee124c 100644
  	ViewGroup *cpuExtensionsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
  	cpuExtensionsScroll->SetTag("DevSystemInfoCPUExt");
 diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp
-index 8202870c7..81112f822 100644
+index 2f1e157ee..38c586b06 100644
 --- a/UI/GameSettingsScreen.cpp
 +++ b/UI/GameSettingsScreen.cpp
-@@ -796,7 +796,6 @@ void GameSettingsScreen::CreateViews() {
+@@ -914,7 +914,6 @@ void GameSettingsScreen::CreateViews() {
+ 		}
  	}
  #endif
- 
 -	systemSettings->Add(new CheckBox(&g_Config.bCheckForNewVersion, sy->T("VersionCheck", "Check for new versions of PPSSPP")));
  	const std::string bgPng = GetSysDirectory(DIRECTORY_SYSTEM) + "background.png";
  	const std::string bgJpg = GetSysDirectory(DIRECTORY_SYSTEM) + "background.jpg";
  	if (File::Exists(bgPng) || File::Exists(bgJpg)) {
 diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp
-index 43535913d..36834020d 100644
+index ca870ab8f..84cde88ac 100644
 --- a/UI/MainScreen.cpp
 +++ b/UI/MainScreen.cpp
-@@ -1054,11 +1054,7 @@ void MainScreen::CreateViews() {
+@@ -1064,11 +1064,7 @@ void MainScreen::CreateViews() {
  	sprintf(versionString, "%s", PPSSPP_GIT_VERSION);
  	rightColumnItems->SetSpacing(0.0f);
- 	LinearLayout *logos = new LinearLayout(ORIENT_HORIZONTAL);
+ 	AnchorLayout *logos = new AnchorLayout(new AnchorLayoutParams(FILL_PARENT, 60.0f, false));
 -	if (System_GetPropertyBool(SYSPROP_APP_GOLD)) {
--		logos->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false)));
+-		logos->Add(new ImageView(ImageID("I_ICONGOLD"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false)));
 -	} else {
--		logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false)));
+-		logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false)));
 -	}
-+	logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 10, 10, NONE, NONE, false)));
- 	logos->Add(new ImageView(ImageID("I_LOGO"), IS_DEFAULT, new LinearLayoutParams(Margins(-12, 0, 0, 0))));
- 	rightColumnItems->Add(logos);
- 	TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0))));
-@@ -1070,11 +1066,6 @@ void MainScreen::CreateViews() {
++	logos->Add(new ImageView(ImageID("I_ICON"), IS_DEFAULT, new AnchorLayoutParams(64, 64, 0, 0, NONE, NONE, false)));
+ 	logos->Add(new ImageView(ImageID("I_LOGO"), IS_DEFAULT, new AnchorLayoutParams(180, 64, 64, -5.0f, NONE, NONE, false)));
+ 
+ #if !defined(MOBILE_DEVICE)
+@@ -1089,11 +1085,6 @@ void MainScreen::CreateViews() {
  	rightColumnItems->Add(new Choice(mm->T("Game Settings", "Settings")))->OnClick.Handle(this, &MainScreen::OnGameSettings);
  	rightColumnItems->Add(new Choice(mm->T("Credits")))->OnClick.Handle(this, &MainScreen::OnCredits);
  	rightColumnItems->Add(new Choice(mm->T("www.ppsspp.org")))->OnClick.Handle(this, &MainScreen::OnPPSSPPOrg);
@@ -153,7 +153,7 @@ index 43535913d..36834020d 100644
  
  #if !PPSSPP_PLATFORM(UWP)
  	// Having an exit button is against UWP guidelines.
-@@ -1099,28 +1090,6 @@ void MainScreen::CreateViews() {
+@@ -1118,32 +1109,6 @@ void MainScreen::CreateViews() {
  	} else if (tabHolder_->GetVisibility() != V_GONE) {
  		root_->SetDefaultFocusView(tabHolder_);
  	}
@@ -169,7 +169,11 @@ index 43535913d..36834020d 100644
 -		UI::Drawable solid(0xFFbd9939);
 -		upgradeBar_->SetBG(solid);
 -		upgradeBar_->Add(new TextView(u->T("New version of PPSSPP available") + std::string(": ") + g_Config.upgradeVersion, new LinearLayoutParams(1.0f, textMargins)));
+-#if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(WINDOWS)
 -		upgradeBar_->Add(new Button(u->T("Download"), new LinearLayoutParams(buttonMargins)))->OnClick.Handle(this, &MainScreen::OnDownloadUpgrade);
+-#else
+-		upgradeBar_->Add(new Button(u->T("Details"), new LinearLayoutParams(buttonMargins)))->OnClick.Handle(this, &MainScreen::OnDownloadUpgrade);
+-#endif
 -		upgradeBar_->Add(new Button(u->T("Dismiss"), new LinearLayoutParams(buttonMargins)))->OnClick.Handle(this, &MainScreen::OnDismissUpgrade);
 -
 -		// Slip in under root_
@@ -182,7 +186,7 @@ index 43535913d..36834020d 100644
  }
  
  UI::EventReturn MainScreen::OnAllowStorage(UI::EventParams &e) {
-@@ -1128,27 +1097,6 @@ UI::EventReturn MainScreen::OnAllowStorage(UI::EventParams &e) {
+@@ -1151,30 +1116,6 @@ UI::EventReturn MainScreen::OnAllowStorage(UI::EventParams &e) {
  	return UI::EVENT_DONE;
  }
  
@@ -194,9 +198,12 @@ index 43535913d..36834020d 100644
 -	} else {
 -		LaunchBrowser("market://details?id=org.ppsspp.ppsspp");
 -	}
+-#elif PPSSPP_PLATFORM(WINDOWS)
+-	LaunchBrowser("https://www.ppsspp.org/downloads.html");
 -#else
 -	// Go directly to ppsspp.org and let the user sort it out
--	LaunchBrowser("https://www.ppsspp.org/downloads.html");
+-	// (for details and in case downloads doesn't have their platform.)
+-	LaunchBrowser("https://www.ppsspp.org/");
 -#endif
 -	return UI::EVENT_DONE;
 -}
@@ -210,7 +217,7 @@ index 43535913d..36834020d 100644
  void MainScreen::sendMessage(const char *message, const char *value) {
  	// Always call the base class method first to handle the most common messages.
  	UIScreenWithBackground::sendMessage(message, value);
-@@ -1319,15 +1267,6 @@ UI::EventReturn MainScreen::OnCredits(UI::EventParams &e) {
+@@ -1390,15 +1331,6 @@ UI::EventReturn MainScreen::OnCredits(UI::EventParams &e) {
  	return UI::EVENT_DONE;
  }
  
@@ -227,10 +234,10 @@ index 43535913d..36834020d 100644
  	LaunchBrowser("https://www.ppsspp.org");
  	return UI::EVENT_DONE;
 diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp
-index a6542c65d..f5f101594 100644
+index a7284654b..2413d6c89 100644
 --- a/UI/MiscScreens.cpp
 +++ b/UI/MiscScreens.cpp
-@@ -498,11 +498,7 @@ void LogoScreen::render() {
+@@ -539,11 +539,7 @@ void LogoScreen::render() {
  	char temp[256];
  	// Manually formatting UTF-8 is fun.  \xXX doesn't work everywhere.
  	snprintf(temp, sizeof(temp), "%s Henrik Rydg%c%crd", cr->T("created", "Created by"), 0xC3, 0xA5);
@@ -243,7 +250,7 @@ index a6542c65d..f5f101594 100644
  	dc.Draw()->DrawImage(ImageID("I_LOGO"), bounds.centerX() + 40, bounds.centerY() - 30, 1.5f, textColor, ALIGN_CENTER);
  	//dc.Draw()->DrawTextShadow(UBUNTU48, "PPSSPP", xres / 2, yres / 2 - 30, textColor, ALIGN_CENTER);
  	dc.SetFontScale(1.0f, 1.0f);
-@@ -538,10 +534,6 @@ void CreditsScreen::CreateViews() {
+@@ -579,10 +575,6 @@ void CreditsScreen::CreateViews() {
  	// Really need to redo this whole layout with some linear layouts...
  
  	int rightYOffset = 0;
@@ -254,7 +261,7 @@ index a6542c65d..f5f101594 100644
  	root_->Add(new Button(cr->T("PPSSPP Forums"), new AnchorLayoutParams(260, 64, 10, NONE, NONE, 158, false)))->OnClick.Handle(this, &CreditsScreen::OnForums);
  	root_->Add(new Button(cr->T("Discord"), new AnchorLayoutParams(260, 64, 10, NONE, NONE, 232, false)))->OnClick.Handle(this, &CreditsScreen::OnDiscord);
  	root_->Add(new Button("www.ppsspp.org", new AnchorLayoutParams(260, 64, 10, NONE, NONE, 10, false)))->OnClick.Handle(this, &CreditsScreen::OnPPSSPPOrg);
-@@ -550,20 +542,7 @@ void CreditsScreen::CreateViews() {
+@@ -591,20 +583,7 @@ void CreditsScreen::CreateViews() {
  #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS)
  	root_->Add(new Button(cr->T("Share PPSSPP"), new AnchorLayoutParams(260, 64, NONE, NONE, 10, rightYOffset + 158, false)))->OnClick.Handle(this, &CreditsScreen::OnShare);
  #endif
@@ -276,7 +283,7 @@ index a6542c65d..f5f101594 100644
  }
  
  UI::EventReturn CreditsScreen::OnTwitter(UI::EventParams &e) {
-@@ -747,11 +726,7 @@ void CreditsScreen::render() {
+@@ -794,11 +773,7 @@ void CreditsScreen::render() {
  
  	// TODO: This is kinda ugly, done on every frame...
  	char temp[256];
@@ -290,10 +297,10 @@ index a6542c65d..f5f101594 100644
  
  	UIContext &dc = *screenManager()->getUIContext();
 diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp
-index 24f3b964d..1d66ba7ee 100644
+index 0ba7fac4b..d1b687c47 100644
 --- a/UWP/PPSSPP_UWPMain.cpp
 +++ b/UWP/PPSSPP_UWPMain.cpp
-@@ -399,12 +399,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
+@@ -433,12 +433,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
  		return false;
  	case SYSPROP_HAS_BACK_BUTTON:
  		return true;
@@ -307,10 +314,10 @@ index 24f3b964d..1d66ba7ee 100644
  		return false;
  	}
 diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp
-index b5e1bb0eb..71b29b48a 100644
+index 979a60ecb..a57927544 100644
 --- a/Windows/MainWindowMenu.cpp
 +++ b/Windows/MainWindowMenu.cpp
-@@ -1377,7 +1377,7 @@ namespace MainWindow {
+@@ -1393,7 +1393,7 @@ namespace MainWindow {
  		{
  			W32Util::CenterWindow(hDlg);
  			HWND versionBox = GetDlgItem(hDlg, IDC_VERSION);
@@ -320,10 +327,10 @@ index b5e1bb0eb..71b29b48a 100644
  			SetWindowText(versionBox, ConvertUTF8ToWString(windowText).c_str());
  		}
 diff --git a/Windows/main.cpp b/Windows/main.cpp
-index 3795597e2..fd98d0453 100644
+index 4d948cfe5..e609cc1e0 100644
 --- a/Windows/main.cpp
 +++ b/Windows/main.cpp
-@@ -268,12 +268,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
+@@ -301,12 +301,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
  		return true;
  	case SYSPROP_HAS_BACK_BUTTON:
  		return true;
@@ -337,13 +344,13 @@ index 3795597e2..fd98d0453 100644
  		return false;
  	}
 diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp
-index 086371085..0a340c0ae 100644
+index 10fdf97e5..736b1fa66 100644
 --- a/android/jni/app-android.cpp
 +++ b/android/jni/app-android.cpp
-@@ -372,12 +372,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
- 		return true;
- 	case SYSPROP_HAS_IMAGE_BROWSER:
- 		return true;
+@@ -437,12 +437,6 @@ bool System_GetPropertyBool(SystemProperty prop) {
+ 	case SYSPROP_HAS_FOLDER_BROWSER:
+ 		// Uses OPEN_DOCUMENT_TREE to let you select a folder.
+ 		return androidVersion >= 21;
 -	case SYSPROP_APP_GOLD:
 -#ifdef GOLD
 -		return true;
@@ -354,5 +361,5 @@ index 086371085..0a340c0ae 100644
  		return false;
  	}
 -- 
-2.26.2
+2.30.1
 
diff --git a/gnu/packages/patches/python-shouldbe-0.1.2-cpy3.8.patch b/gnu/packages/patches/python-shouldbe-0.1.2-cpy3.8.patch
deleted file mode 100644
index f3b56e42d6..0000000000
--- a/gnu/packages/patches/python-shouldbe-0.1.2-cpy3.8.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-Fix compatibility with Python 3.8.
-
-Upstream issue: https://github.com/DirectXMan12/should_be/pull/5
-
-diff -x '*.pyc' -Naur shouldbe-0.1.2/should_be/core.py shouldbe-0.1.2.patched/should_be/core.py
---- shouldbe-0.1.2/should_be/core.py	2019-03-06 07:38:22.000000000 +0100
-+++ shouldbe-0.1.2.patched/should_be/core.py	2020-05-18 08:44:24.214664704 +0200
-@@ -103,7 +103,7 @@
-     return resf
- 
- 
--def buildCode(baseCode, argcount=None, kwonlyargcount=None,
-+def buildCode(baseCode, argcount=None, posonlyargcount=None, kwonlyargcount=None,
-               nlocals=None, stacksize=None, flags=None,
-               code=None, consts=None, names=None,
-               varnames=None, filename=None, name=None,
-@@ -121,6 +121,24 @@
-                         nlocals or baseCode.co_nlocals,
-                         stacksize or baseCode.co_stacksize,
-                         flags or baseCode.co_flags,
-+                        code or baseCode.co_code,
-+                        consts or baseCode.co_consts,
-+                        names or baseCode.co_names,
-+                        varnames or baseCode.co_varnames,
-+                        filename or baseCode.co_filename,
-+                        name or baseCode.co_name,
-+                        firstlineno or baseCode.co_firstlineno,
-+                        lnotab or baseCode.co_lnotab,
-+                        freevars or baseCode.co_freevars,
-+                        cellvars or baseCode.co_cellvars)
-+    elif hasattr(baseCode, 'co_posonlyargcount'):
-+        # Python 3.8
-+        resc = CodeType(argcount or baseCode.co_argcount,
-+                        posonlyargcount or baseCode.co_posonlyargcount,
-+                        kwonlyargcount or baseCode.co_kwonlyargcount,
-+                        nlocals or baseCode.co_nlocals,
-+                        stacksize or baseCode.co_stacksize,
-+                        flags or baseCode.co_flags,
-                         code or baseCode.co_code,
-                         consts or baseCode.co_consts,
-                         names or baseCode.co_names,
-diff -x '*.pyc' -Naur shouldbe-0.1.2/should_be/tests/test_container_mixin.py shouldbe-0.1.2.patched/should_be/tests/test_container_mixin.py
---- shouldbe-0.1.2/should_be/tests/test_container_mixin.py	2019-03-01 06:38:16.000000000 +0100
-+++ shouldbe-0.1.2.patched/should_be/tests/test_container_mixin.py	2020-05-18 09:00:51.372531064 +0200
-@@ -7,31 +7,31 @@
-         self.lst = [1, 2, 3]
- 
-     def test_should_include_iter(self):
--        err_msg = (r'[a-zA-Z0-9.]+ should have included \[.+?\]'
-+        err_msg = (r'[a-zA-Z0-9.()]+ should have included \[.+?\]'
-                    r', but did not have items .+')
--        self.assertRaisesRegexp(AssertionError, err_msg,
-+        self.assertRaisesRegex(AssertionError, err_msg,
-                                 self.lst.should_include, [4])
- 
-         self.lst.should_include([1, 2, 3])
- 
-     def test_should_include_item(self):
--        err_msg = (r'[a-zA-Z0-9.]+ should have included .+?'
-+        err_msg = (r'[a-zA-Z0-9.()]+ should have included .+?'
-                    r', but did not')
--        self.assertRaisesRegexp(AssertionError, err_msg,
-+        self.assertRaisesRegex(AssertionError, err_msg,
-                                 self.lst.should_include, 4)
- 
-         self.lst.should_include(3)
- 
-     def test_shouldnt_include_iter(self):
-         err_msg = 'should not have included'
--        self.assertRaisesRegexp(AssertionError, err_msg,
-+        self.assertRaisesRegex(AssertionError, err_msg,
-                                 self.lst.shouldnt_include, [2, 3])
- 
-         self.lst.shouldnt_include([4, 5])
- 
-     def test_shouldnt_include_item(self):
-         err_msg = 'should not have included'
--        self.assertRaisesRegexp(AssertionError, err_msg,
-+        self.assertRaisesRegex(AssertionError, err_msg,
-                                 self.lst.shouldnt_include, 3)
- 
-         self.lst.shouldnt_include(4)
diff --git a/gnu/packages/patches/qemu-build-info-manual.patch b/gnu/packages/patches/qemu-build-info-manual.patch
index d57b26ea00..c837040d45 100644
--- a/gnu/packages/patches/qemu-build-info-manual.patch
+++ b/gnu/packages/patches/qemu-build-info-manual.patch
@@ -1,90 +1,29 @@
-From 07303a0a4daa83a0555ac4abad7a5d65584307ad Mon Sep 17 00:00:00 2001
+From 2793f47c066ed396b38893c10533202fceb1a05f Mon Sep 17 00:00:00 2001
 From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
 Date: Thu, 17 Sep 2020 13:28:19 -0400
-Subject: [PATCH] build: Build and install the info manual.
+Subject: [PATCH] build: Build and install a Texinfo version of the manual.
 
 Take advantage of the Sphinx texinfo backend to generate a QEMU info
-manual.  The texinfo format allows for more structure and info readers
+manual.  The Texinfo format allows for more structure and info readers
 provide more advanced navigation capabilities compared to manpages
 readers.
 
-* configure (infodir): Add the --infodir option, which allows
+* configure (infodir): Add an --infodir option, which allows
 configuring the directory under which the info manuals are installed.
-* docs/index.rst: Include the top level documents to prevent
-warnings (treated as errors by sphinx-build).
-* Makefile (sphinxdocs-info, $(MANUAL_BUILDDIR)/QEMU.texi)): New targets.
-(info): Depend on sphinxdocs-info.
-(install-doc): Install the info manual.
+* docs/meson.build (texi, info): New targets.
+
+Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
 ---
- Makefile       | 13 +++++++++++--
- configure      |  7 +++++++
- docs/index.rst |  2 ++
- 3 files changed, 20 insertions(+), 2 deletions(-)
+ configure        |  7 ++++++-
+ docs/meson.build | 21 +++++++++++++++++++++
+ meson.build      |  2 ++
+ 3 files changed, 29 insertions(+), 1 deletion(-)
 
-diff --git a/Makefile b/Makefile
-index 13dd708c..da78612d 100644
---- a/Makefile
-+++ b/Makefile
-@@ -864,12 +864,14 @@ endef
- # Note that we deliberately do not install the "devel" manual: it is
- # for QEMU developers, and not interesting to our users.
- .PHONY: install-sphinxdocs
--install-sphinxdocs: sphinxdocs
-+install-sphinxdocs: sphinxdocs sphinxdocs-info
- 	$(call install-manual,interop)
- 	$(call install-manual,specs)
- 	$(call install-manual,system)
- 	$(call install-manual,tools)
- 	$(call install-manual,user)
-+	$(INSTALL_DIR) "$(DESTDIR)$(infodir)"
-+	$(INSTALL_DATA) $(MANUAL_BUILDDIR)/QEMU.info "$(DESTDIR)$(infodir)"
- 
- install-doc: $(DOCS) install-sphinxdocs
- 	$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
-@@ -1067,6 +1069,13 @@ sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html \
-             $(MANUAL_BUILDDIR)/tools/index.html \
-             $(MANUAL_BUILDDIR)/user/index.html
- 
-+# Build the complete info manual.
-+.PHONE: sphinxdocs-info
-+sphinxdocs-info: $(MANUAL_BUILDDIR)/QEMU.info
-+
-+$(MANUAL_BUILDDIR)/QEMU.texi: $(call manual-deps,*) $(wildcard $(SRC_PATH)/docs/*.rst)
-+	$(call build-manual,,texinfo)
-+
- # Canned command to build a single manual
- # Arguments: $1 = manual name, $2 = Sphinx builder ('html' or 'man')
- # Note the use of different doctree for each (manual, builder) tuple;
-@@ -1126,7 +1135,7 @@ docs/interop/qemu-ga-qapi.texi: qga/qapi-generated/qga-qapi-doc.texi
- 	@cp -p $< $@
- 
- html: docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html sphinxdocs
--info: docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info
-+info: docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info sphinxdocs-info
- pdf: docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
- txt: docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
- 
 diff --git a/configure b/configure
-index 2acc4d14..3691bd2e 100755
+index 18c26e0389..d1ab2c19d1 100755
 --- a/configure
 +++ b/configure
-@@ -415,6 +415,7 @@ LDFLAGS_SHARED="-shared"
- modules="no"
- module_upgrades="no"
- prefix="/usr/local"
-+infodir="\${prefix}/share/info"
- mandir="\${prefix}/share/man"
- datadir="\${prefix}/share"
- firmwarepath="\${prefix}/share/qemu-firmware"
-@@ -987,6 +988,7 @@ if test "$mingw32" = "yes" ; then
-     LIBS="-liberty $LIBS"
-   fi
-   prefix="c:/Program Files/QEMU"
-+  infodir="\${prefix}"
-   mandir="\${prefix}"
-   datadir="\${prefix}"
-   qemu_docdir="\${prefix}"
-@@ -1087,6 +1089,8 @@ for opt do
+@@ -948,6 +948,8 @@ for opt do
      static="yes"
      QEMU_PKG_CONFIG_FLAGS="--static $QEMU_PKG_CONFIG_FLAGS"
    ;;
@@ -93,47 +32,89 @@ index 2acc4d14..3691bd2e 100755
    --mandir=*) mandir="$optarg"
    ;;
    --bindir=*) bindir="$optarg"
-@@ -1780,6 +1784,7 @@ Advanced options (experts only):
+@@ -975,7 +977,7 @@ for opt do
+   --host=*|--build=*|\
+   --disable-dependency-tracking|\
+   --sbindir=*|--sharedstatedir=*|\
+-  --oldincludedir=*|--datarootdir=*|--infodir=*|\
++  --oldincludedir=*|--datarootdir=*|\
+   --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
+     # These switches are silently ignored, for compatibility with
+     # autoconf-generated configure scripts. This allows QEMU's
+@@ -1540,6 +1542,7 @@ includedir="${includedir:-$prefix/include}"
+ if test "$mingw32" = "yes" ; then
+     mandir="$prefix"
+     datadir="$prefix"
++    infodir="$prefix"
+     docdir="$prefix"
+     bindir="$prefix"
+     sysconfdir="$prefix"
+@@ -1547,6 +1550,7 @@ if test "$mingw32" = "yes" ; then
+ else
+     mandir="${mandir:-$prefix/share/man}"
+     datadir="${datadir:-$prefix/share}"
++    infodir="${infodir:-$datadir/info}"
+     docdir="${docdir:-$prefix/share/doc}"
+     bindir="${bindir:-$prefix/bin}"
+     sysconfdir="${sysconfdir:-$prefix/etc}"
+@@ -1683,6 +1687,7 @@ Advanced options (experts only):
    --smbd=SMBD              use specified smbd [$smbd]
    --with-git=GIT           use specified git [$git]
    --static                 enable static build [$static]
 +  --infodir=PATH           install info manual in PATH
    --mandir=PATH            install man pages in PATH
-   --datadir=PATH           install firmware in PATH$confsuffix
-   --docdir=PATH            install documentation in PATH$confsuffix
-@@ -6836,6 +6841,7 @@ echo "include directory $(eval echo $includedir)"
- echo "config directory  $(eval echo $sysconfdir)"
- if test "$mingw32" = "no" ; then
- echo "local state directory   $(eval echo $local_statedir)"
-+echo "Info manual directory   $(eval echo $infodir)"
- echo "Manual directory  $(eval echo $mandir)"
- echo "ELF interp prefix $interp_prefix"
- else
-@@ -7059,6 +7065,7 @@ echo "bindir=$bindir" >> $config_host_mak
- echo "libdir=$libdir" >> $config_host_mak
- echo "libexecdir=$libexecdir" >> $config_host_mak
- echo "includedir=$includedir" >> $config_host_mak
-+echo "infodir=$infodir" >> $config_host_mak
- echo "mandir=$mandir" >> $config_host_mak
- echo "sysconfdir=$sysconfdir" >> $config_host_mak
- echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
-diff --git a/docs/index.rst b/docs/index.rst
-index 763e3d04..4f155b51 100644
---- a/docs/index.rst
-+++ b/docs/index.rst
-@@ -9,6 +9,7 @@ Welcome to QEMU's documentation!
- .. toctree::
-    :maxdepth: 2
-    :caption: Contents:
-+   :glob:
+   --datadir=PATH           install firmware in PATH/$qemu_suffix
+   --localedir=PATH         install translation in PATH/$qemu_suffix
+diff --git a/docs/meson.build b/docs/meson.build
+index ebd85d59f9..1243839461 100644
+--- a/docs/meson.build
++++ b/docs/meson.build
+@@ -114,4 +114,25 @@ if build_docs
+   alias_target('sphinxdocs', sphinxdocs)
+   alias_target('html', sphinxdocs)
+   alias_target('man', sphinxmans)
++
++  # Generate a Texinfo version of the QEMU manual.
++  makeinfo = find_program(['texi2any', 'makeinfo'])
++  if makeinfo.found()
++    sphinxtexi = custom_target(
++      'QEMU manual generated texinfo source',
++      output: ['QEMU.texi', 'sphinxtexi.stamp'],
++      depfile: 'sphinxtexi.d',
++      command: [SPHINX_ARGS, '-Ddepfile=@DEPFILE@',
++               '-Ddepfile_stamp=@OUTPUT1@', '-b', 'texinfo',
++               meson.current_source_dir(), meson.current_build_dir()])
++    sphinxinfo = custom_target(
++      'QEMU info manual',
++      input: sphinxtexi,
++      output: 'QEMU.info',
++      install: true,
++      install_dir: get_option('infodir'),
++      command: [makeinfo, '@INPUT0@', '--output=@OUTPUT@'])
++    alias_target('texi', sphinxtexi)
++    alias_target('info', sphinxinfo)
++  endif
+ endif
+diff --git a/meson.build b/meson.build
+index e3386196ba..d64a125ad9 100644
+--- a/meson.build
++++ b/meson.build
+@@ -32,6 +32,7 @@ endif
+ qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
+ qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
+ qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
++qemu_infodir = get_option('infodir') / get_option('qemu_suffix')
+ qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
  
-    system/index
-    user/index
-@@ -16,3 +17,4 @@ Welcome to QEMU's documentation!
-    interop/index
-    specs/index
-    devel/index
-+   *
+ qemu_desktopdir = get_option('datadir') / 'applications'
+@@ -1995,6 +1996,7 @@ else
+   summary_info += {'local state directory': 'queried at runtime'}
+ endif
+ summary_info += {'Doc directory':     get_option('docdir')}
++summary_info += {'Info directory':    get_option('infodir')}
+ summary_info += {'Build directory':   meson.current_build_dir()}
+ summary_info += {'Source path':       meson.current_source_dir()}
+ summary_info += {'GIT binary':        config_host['GIT']}
 -- 
-2.28.0
+2.30.1
 
diff --git a/gnu/packages/patches/sdcc-disable-non-free-code.patch b/gnu/packages/patches/sdcc-disable-non-free-code.patch
index ad9a3e7a9e..1c823c3c18 100644
--- a/gnu/packages/patches/sdcc-disable-non-free-code.patch
+++ b/gnu/packages/patches/sdcc-disable-non-free-code.patch
@@ -15,10 +15,10 @@ remove instructions that encourage the use of SDCC with non-free
 software.
 
 diff --git a/Makefile.common.in b/Makefile.common.in
-index 412fd5a..81bbd61 100644
+index 926b761..0362fd5 100644
 --- a/Makefile.common.in
 +++ b/Makefile.common.in
-@@ -69,7 +69,6 @@ OPT_DISABLE_PACKIHX     = @OPT_DISABLE_PACKIHX@
+@@ -71,7 +71,6 @@ OPT_DISABLE_PACKIHX     = @OPT_DISABLE_PACKIHX@
  OPT_DISABLE_SDBINUTILS  = @OPT_DISABLE_SDBINUTILS@
  OPT_DISABLE_SDCPP       = @OPT_DISABLE_SDCPP@
  OPT_DISABLE_UCSIM       = @OPT_DISABLE_UCSIM@
@@ -27,7 +27,7 @@ index 412fd5a..81bbd61 100644
  SLIB                    = $(top_builddir)/support/util
  
 diff --git a/Makefile.in b/Makefile.in
-index f3b028d..cfdf06d 100644
+index 5485074..3071472 100644
 --- a/Makefile.in
 +++ b/Makefile.in
 @@ -100,9 +100,6 @@ endif
@@ -73,7 +73,7 @@ index f3b028d..cfdf06d 100644
  
  # doc depends on latex and latex2html
 diff --git a/configure b/configure
-index 43ccb6f..d345f54 100755
+index 4c2226b..b8a9251 100755
 --- a/configure
 +++ b/configure
 @@ -632,7 +632,6 @@ LATEX
@@ -84,7 +84,7 @@ index 43ccb6f..d345f54 100755
  OPT_DISABLE_SDBINUTILS
  OPT_DISABLE_SDCDB
  OPT_DISABLE_SDCPP
-@@ -659,10 +658,7 @@ OPT_DISABLE_R2K
+@@ -661,10 +660,7 @@ OPT_DISABLE_R2K
  OPT_DISABLE_Z180
  OPT_DISABLE_Z80
  OPT_DISABLE_MCS51
@@ -95,7 +95,7 @@ index 43ccb6f..d345f54 100755
  include_dir_suffix
  inclib_dir_suffix
  LIB_TYPE
-@@ -780,7 +776,6 @@ enable_packihx
+@@ -785,7 +781,6 @@ enable_packihx
  enable_sdcpp
  enable_sdcdb
  enable_sdbinutils
@@ -103,7 +103,7 @@ index 43ccb6f..d345f54 100755
  enable_doc
  enable_libgc
  '
-@@ -801,10 +796,7 @@ sdccconf_h_dir_separator
+@@ -806,10 +801,7 @@ sdccconf_h_dir_separator
  LIB_TYPE
  inclib_dir_suffix
  include_dir_suffix
@@ -114,7 +114,7 @@ index 43ccb6f..d345f54 100755
  docdir'
  ac_subdirs_all='support/cpp
  support/packihx
-@@ -812,9 +804,7 @@ sim/ucsim
+@@ -817,9 +809,7 @@ sim/ucsim
  debugger/mcs51
  support/sdbinutils
  device/lib/pic14
@@ -125,7 +125,7 @@ index 43ccb6f..d345f54 100755
  
  # Initialize some variables set by options.
  ac_init_help=
-@@ -1455,7 +1445,6 @@ Optional Features:
+@@ -1473,7 +1463,6 @@ Optional Features:
    --disable-sdcpp         Disables building sdcpp
    --disable-sdcdb         Disables building sdcdb
    --disable-sdbinutils    Disables configuring and building of sdbinutils
@@ -133,7 +133,7 @@ index 43ccb6f..d345f54 100755
    --enable-doc            Enables building the documentation
    --enable-libgc          Use the Bohem memory allocator. Lower runtime
                            footprint.
-@@ -1484,16 +1473,8 @@ Some influential environment variables:
+@@ -1502,16 +1491,8 @@ Some influential environment variables:
                appended to datadir to define SDCC's include/lib directory
    include_dir_suffix
                appended to datadir to define SDCC's include directory
@@ -150,7 +150,7 @@ index 43ccb6f..d345f54 100755
    docdir      documentation installation directory
  
  Use these variables to override the choices made by `configure' or to help
-@@ -7134,19 +7115,6 @@ if test "${include_dir_suffix}" = ""; then
+@@ -7156,19 +7137,6 @@ if test "${include_dir_suffix}" = ""; then
      include_dir_suffix="${inclib_dir_suffix}/include"
  fi
  
@@ -170,7 +170,7 @@ index 43ccb6f..d345f54 100755
  # lib_dir_suffix:
  # *nix default: "sdcc/lib"
  
-@@ -7154,13 +7122,6 @@ if test "${lib_dir_suffix}" = ""; then
+@@ -7176,13 +7144,6 @@ if test "${lib_dir_suffix}" = ""; then
      lib_dir_suffix="${inclib_dir_suffix}/lib"
  fi
  
@@ -184,7 +184,7 @@ index 43ccb6f..d345f54 100755
  # docdir:
  # *nix default: "${datadir}/sdcc/doc"
  
-@@ -7327,24 +7288,6 @@ cat >>confdefs.h <<_ACEOF
+@@ -7349,24 +7310,6 @@ cat >>confdefs.h <<_ACEOF
  #define INCLUDE_DIR_SUFFIX DIR_SEPARATOR_STRING "${norm_inc_dir_suffix}"
  _ACEOF
  
@@ -209,7 +209,7 @@ index 43ccb6f..d345f54 100755
  
  norm_lib_dir_suffix=${lib_dir_suffix}
  case ":$norm_lib_dir_suffix:" in
-@@ -7364,24 +7307,6 @@ cat >>confdefs.h <<_ACEOF
+@@ -7386,24 +7329,6 @@ cat >>confdefs.h <<_ACEOF
  #define LIB_DIR_SUFFIX DIR_SEPARATOR_STRING "${norm_lib_dir_suffix}"
  _ACEOF
  
@@ -234,7 +234,7 @@ index 43ccb6f..d345f54 100755
  
  # relative paths
  for _lcl_i in expanded_bindir:expanded_datadir:bin2data_dir; do
-@@ -8439,28 +8364,6 @@ _ACEOF
+@@ -8513,28 +8438,6 @@ _ACEOF
  
  
  
@@ -263,7 +263,7 @@ index 43ccb6f..d345f54 100755
  
    # Check whether --enable-doc was given.
  if test "${enable_doc+set}" = set; then :
-@@ -8855,20 +8758,12 @@ if test $OPT_DISABLE_PIC14 = 0; then
+@@ -8929,20 +8832,12 @@ if test $OPT_DISABLE_PIC14 = 0; then
  
    test $OPT_DISABLE_DEVICE_LIB = 0 && subdirs="$subdirs device/lib/pic14"
  
@@ -283,8 +283,8 @@ index 43ccb6f..d345f54 100755
 -
  fi
  
- if test $OPT_DISABLE_Z80 = 0 || test $OPT_DISABLE_Z180 = 0 || test $OPT_DISABLE_R2K = 0 || test $OPT_DISABLE_R3KA = 0 || test $OPT_DISABLE_GBZ80 = 0 || test $OPT_DISABLE_TLCS90 = 0 || test $OPT_DISABLE_EZ80_Z80 = 0; then
-@@ -8945,15 +8840,9 @@ fi
+ if test $OPT_DISABLE_Z80 = 0 || test $OPT_DISABLE_Z180 = 0 || test $OPT_DISABLE_R2K = 0 || test $OPT_DISABLE_R2KA = 0 || test $OPT_DISABLE_R3KA = 0 || test $OPT_DISABLE_GBZ80 = 0 || test $OPT_DISABLE_TLCS90 = 0 || test $OPT_DISABLE_EZ80_Z80 = 0 || test $OPT_DISABLE_Z80N = 0; then
+@@ -9019,15 +8914,9 @@ fi
  
  test $OPT_DISABLE_DEVICE_LIB = 0 && ac_config_files="$ac_config_files device/lib/Makefile"
  
@@ -300,7 +300,7 @@ index 43ccb6f..d345f54 100755
  cat >confcache <<\_ACEOF
  # This file is a shell script that caches the results of configure
  # tests run on this system so they can be shared between configure
-@@ -9692,7 +9581,6 @@ do
+@@ -9768,7 +9657,6 @@ do
      "device/lib/pdk15-stack-auto/Makefile") CONFIG_FILES="$CONFIG_FILES device/lib/pdk15-stack-auto/Makefile" ;;
      "sdas/aspdk16/Makefile") CONFIG_FILES="$CONFIG_FILES sdas/aspdk16/Makefile" ;;
      "device/lib/Makefile") CONFIG_FILES="$CONFIG_FILES device/lib/Makefile" ;;
@@ -308,7 +308,7 @@ index 43ccb6f..d345f54 100755
      "main.mk") CONFIG_FILES="$CONFIG_FILES main.mk:main_in.mk" ;;
      "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
      "device/include/Makefile") CONFIG_FILES="$CONFIG_FILES device/include/Makefile" ;;
-@@ -9704,7 +9592,6 @@ do
+@@ -9780,7 +9668,6 @@ do
      "support/regression/ports/host/spec.mk") CONFIG_FILES="$CONFIG_FILES support/regression/ports/host/spec.mk:support/regression/ports/host/spec.mk.in" ;;
      "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
      "Makefile.common") CONFIG_FILES="$CONFIG_FILES Makefile.common:Makefile.common.in" ;;
@@ -316,7 +316,7 @@ index 43ccb6f..d345f54 100755
  
    *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
    esac
-@@ -10513,54 +10400,6 @@ esac
+@@ -10589,54 +10476,6 @@ esac
  incPath3=`echo "$incPath3" | sed 's,\\\\\\\\,\\\\,g'`
  
  
@@ -371,7 +371,7 @@ index 43ccb6f..d345f54 100755
  
  libPath1=`echo "/${prefix2data_dir}/${norm_lib_dir_suffix}" | sed 's,/\./,/,g'`
  case ":$libPath1:" in
-@@ -10610,54 +10449,6 @@ esac
+@@ -10686,54 +10525,6 @@ esac
  libPath3=`echo "$libPath3" | sed 's,\\\\\\\\,\\\\,g'`
  
  
@@ -426,7 +426,7 @@ index 43ccb6f..d345f54 100755
  { $as_echo "$as_me:${as_lineno-$LINENO}: result:
  sdcc ${VERSION} is now configured for
  
-@@ -10694,7 +10485,6 @@ sdcc ${VERSION} is now configured for
+@@ -10772,7 +10563,6 @@ sdcc ${VERSION} is now configured for
      pdk15               ${enable_pdk15_port}
      pdk16               ${enable_pdk16_port}
  
@@ -434,7 +434,7 @@ index 43ccb6f..d345f54 100755
    Disable packihx:      ${OPT_DISABLE_PACKIHX}
    Disable ucsim:        ${OPT_DISABLE_UCSIM}
    Disable device lib:   ${OPT_DISABLE_DEVICE_LIB}
-@@ -10709,9 +10499,6 @@ sdcc ${VERSION} is now configured for
+@@ -10787,9 +10577,6 @@ sdcc ${VERSION} is now configured for
      include/library files:  ${datadir}/${inclib_dir_suffix}
      include files:          ${datadir}/${include_dir_suffix}
      library files:          ${datadir}/${lib_dir_suffix}
@@ -444,7 +444,7 @@ index 43ccb6f..d345f54 100755
      documentation:          ${docdir}
  
      prefix:             ${prefix}
-@@ -10723,15 +10510,9 @@ sdcc ${VERSION} is now configured for
+@@ -10801,15 +10588,9 @@ sdcc ${VERSION} is now configured for
      include files:      ${incPath1}
                          path(argv[0])${incPath2}
                          ${incPath3}
@@ -460,7 +460,7 @@ index 43ccb6f..d345f54 100755
  " >&5
  $as_echo "
  sdcc ${VERSION} is now configured for
-@@ -10769,7 +10550,6 @@ sdcc ${VERSION} is now configured for
+@@ -10849,7 +10630,6 @@ sdcc ${VERSION} is now configured for
      pdk15               ${enable_pdk15_port}
      pdk16               ${enable_pdk16_port}
  
@@ -468,7 +468,7 @@ index 43ccb6f..d345f54 100755
    Disable packihx:      ${OPT_DISABLE_PACKIHX}
    Disable ucsim:        ${OPT_DISABLE_UCSIM}
    Disable device lib:   ${OPT_DISABLE_DEVICE_LIB}
-@@ -10784,9 +10564,6 @@ sdcc ${VERSION} is now configured for
+@@ -10864,9 +10644,6 @@ sdcc ${VERSION} is now configured for
      include/library files:  ${datadir}/${inclib_dir_suffix}
      include files:          ${datadir}/${include_dir_suffix}
      library files:          ${datadir}/${lib_dir_suffix}
@@ -478,7 +478,7 @@ index 43ccb6f..d345f54 100755
      documentation:          ${docdir}
  
      prefix:             ${prefix}
-@@ -10798,14 +10575,8 @@ sdcc ${VERSION} is now configured for
+@@ -10878,14 +10655,8 @@ sdcc ${VERSION} is now configured for
      include files:      ${incPath1}
                          path(argv[0])${incPath2}
                          ${incPath3}
@@ -494,10 +494,10 @@ index 43ccb6f..d345f54 100755
  " >&6; }
  # End of configure/configure.in
 diff --git a/configure.ac b/configure.ac
-index 2185793..76ab155 100644
+index 455fee1..48e0a20 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -544,19 +544,6 @@ if test "${include_dir_suffix}" = ""; then
+@@ -548,19 +548,6 @@ if test "${include_dir_suffix}" = ""; then
      include_dir_suffix="${inclib_dir_suffix}/include"
  fi
  
@@ -517,7 +517,7 @@ index 2185793..76ab155 100644
  # lib_dir_suffix:
  # *nix default: "sdcc/lib"
  AC_ARG_VAR([lib_dir_suffix], [appended to datadir to define SDCC's library root directory])
-@@ -564,13 +551,6 @@ if test "${lib_dir_suffix}" = ""; then
+@@ -568,13 +555,6 @@ if test "${lib_dir_suffix}" = ""; then
      lib_dir_suffix="${inclib_dir_suffix}/lib"
  fi
  
@@ -531,7 +531,7 @@ index 2185793..76ab155 100644
  # docdir:
  # *nix default: "${datadir}/sdcc/doc"
  AC_ARG_VAR([docdir], [documentation installation directory])
-@@ -611,19 +591,11 @@ norm_inc_dir_suffix=${include_dir_suffix}
+@@ -615,19 +595,11 @@ norm_inc_dir_suffix=${include_dir_suffix}
  adl_NORMALIZE_PATH([norm_inc_dir_suffix], [$sdccconf_h_dir_separator])
  AC_DEFINE_UNQUOTED(INCLUDE_DIR_SUFFIX,
                     DIR_SEPARATOR_STRING "${norm_inc_dir_suffix}", [XXX])
@@ -551,7 +551,7 @@ index 2185793..76ab155 100644
  
  # relative paths
  adl_COMPUTE_RELATIVE_PATHS([expanded_bindir:expanded_datadir:bin2data_dir])
-@@ -797,7 +769,6 @@ AC_DO_DISABLER(packihx,    PACKIHX,    [Disables building packihx])
+@@ -803,7 +775,6 @@ AC_DO_DISABLER(packihx,    PACKIHX,    [Disables building packihx])
  AC_DO_DISABLER(sdcpp,      SDCPP,      [Disables building sdcpp])
  AC_DO_DISABLER(sdcdb,      SDCDB,      [Disables building sdcdb])
  AC_DO_DISABLER(sdbinutils, SDBINUTILS, [Disables configuring and building of sdbinutils])
@@ -559,7 +559,7 @@ index 2185793..76ab155 100644
  
  AC_DO_ENABLER(doc,   DOC,   [Enables building the documentation])
  AC_CHECK_PROG([LYX],        [lyx],        [lyx],        [:])
-@@ -868,16 +839,10 @@ if test $OPT_DISABLE_PIC14 = 0; then
+@@ -874,16 +845,10 @@ if test $OPT_DISABLE_PIC14 = 0; then
    AC_CONFIG_FILES(src/pic14/Makefile)
    test $OPT_DISABLE_DEVICE_LIB = 0 && AC_CONFIG_SUBDIRS(device/lib/pic14)
  fi
@@ -574,9 +574,9 @@ index 2185793..76ab155 100644
 -  test $OPT_DISABLE_DEVICE_LIB = 0 && AC_CONFIG_SUBDIRS(device/non-free/lib/pic16)
 -fi
  
- if test $OPT_DISABLE_Z80 = 0 || test $OPT_DISABLE_Z180 = 0 || test $OPT_DISABLE_R2K = 0 || test $OPT_DISABLE_R3KA = 0 || test $OPT_DISABLE_GBZ80 = 0 || test $OPT_DISABLE_TLCS90 = 0 || test $OPT_DISABLE_EZ80_Z80 = 0; then
+ if test $OPT_DISABLE_Z80 = 0 || test $OPT_DISABLE_Z180 = 0 || test $OPT_DISABLE_R2K = 0 || test $OPT_DISABLE_R2KA = 0 || test $OPT_DISABLE_R3KA = 0 || test $OPT_DISABLE_GBZ80 = 0 || test $OPT_DISABLE_TLCS90 = 0 || test $OPT_DISABLE_EZ80_Z80 = 0 || test $OPT_DISABLE_Z80N = 0; then
    AC_CONFIG_FILES([src/z80/Makefile])
-@@ -939,7 +904,6 @@ fi
+@@ -947,7 +912,6 @@ fi
  
  
  test $OPT_DISABLE_DEVICE_LIB = 0 && AC_CONFIG_FILES([device/lib/Makefile])
@@ -584,7 +584,7 @@ index 2185793..76ab155 100644
  
  AC_CONFIG_FILES([main.mk:main_in.mk
  src/Makefile
-@@ -953,9 +917,6 @@ support/regression/ports/host/spec.mk:support/regression/ports/host/spec.mk.in
+@@ -961,9 +925,6 @@ support/regression/ports/host/spec.mk:support/regression/ports/host/spec.mk.in
  Makefile
  Makefile.common:Makefile.common.in
  ])
@@ -594,7 +594,7 @@ index 2185793..76ab155 100644
  AC_OUTPUT
  
  # I found no better place
-@@ -973,16 +934,10 @@ adl_NORMALIZE_PATH_MSG(/${prefix2bin_dir},                         [binPath],  [
+@@ -981,16 +942,10 @@ adl_NORMALIZE_PATH_MSG(/${prefix2bin_dir},                         [binPath],  [
  adl_NORMALIZE_PATH_MSG(/${prefix2data_dir}/${norm_inc_dir_suffix}, [incPath1], [$dirch])
  adl_NORMALIZE_PATH_MSG(/${bin2data_dir}/${norm_inc_dir_suffix},    [incPath2], [$dirch])
  adl_NORMALIZE_PATH_MSG(${expanded_datadir}/${norm_inc_dir_suffix}, [incPath3], [$dirch])
@@ -611,7 +611,7 @@ index 2185793..76ab155 100644
  
  AC_MSG_RESULT([
  sdcc ${VERSION} is now configured for
-@@ -1020,7 +975,6 @@ sdcc ${VERSION} is now configured for
+@@ -1030,7 +985,6 @@ sdcc ${VERSION} is now configured for
      pdk15               ${enable_pdk15_port}
      pdk16               ${enable_pdk16_port}
  
@@ -619,7 +619,7 @@ index 2185793..76ab155 100644
    Disable packihx:      ${OPT_DISABLE_PACKIHX}
    Disable ucsim:        ${OPT_DISABLE_UCSIM}
    Disable device lib:   ${OPT_DISABLE_DEVICE_LIB}
-@@ -1035,9 +989,6 @@ sdcc ${VERSION} is now configured for
+@@ -1045,9 +999,6 @@ sdcc ${VERSION} is now configured for
      include/library files:  ${datadir}/${inclib_dir_suffix}
      include files:          ${datadir}/${include_dir_suffix}
      library files:          ${datadir}/${lib_dir_suffix}
@@ -629,7 +629,7 @@ index 2185793..76ab155 100644
      documentation:          ${docdir}
  
      prefix:             ${prefix}
-@@ -1049,14 +1000,8 @@ sdcc ${VERSION} is now configured for
+@@ -1059,14 +1010,8 @@ sdcc ${VERSION} is now configured for
      include files:      ${incPath1}
                          path(argv[[0]])${incPath2}
                          ${incPath3}
@@ -675,7 +675,7 @@ index 019fe0f..da3389d 100644
  ############################################################
  # Common actions
 diff --git a/device/lib/pic14/Makefile.in b/device/lib/pic14/Makefile.in
-index 39b6cb0..ae3e37b 100644
+index 039c0cb..90510fd 100644
 --- a/device/lib/pic14/Makefile.in
 +++ b/device/lib/pic14/Makefile.in
 @@ -335,13 +335,12 @@ GENERIC_SRC_DIR_ABS = $(abspath $(GENERIC_SRC_DIR))
@@ -704,7 +704,7 @@ index 39b6cb0..ae3e37b 100644
  # extensions generated by the build process
  CLEAN_EXTENSIONS = .asm .lst .sym .d .p .g .v .adb
 diff --git a/device/lib/pic14/libc/Makefile.in b/device/lib/pic14/libc/Makefile.in
-index 0efeeb0..d4dd8e6 100644
+index 1283cbb..70e82d0 100644
 --- a/device/lib/pic14/libc/Makefile.in
 +++ b/device/lib/pic14/libc/Makefile.in
 @@ -878,13 +878,12 @@ GENERIC_SRC_DIR_ABS = $(abspath $(GENERIC_SRC_DIR))
@@ -733,7 +733,7 @@ index 0efeeb0..d4dd8e6 100644
  # extensions generated by the build process
  CLEAN_EXTENSIONS = .asm .lst .sym .d .p .g .v .adb
 diff --git a/device/lib/pic14/libm/Makefile.in b/device/lib/pic14/libm/Makefile.in
-index f0dc9ca..98ed2cf 100644
+index 409835d..e9fdef8 100644
 --- a/device/lib/pic14/libm/Makefile.in
 +++ b/device/lib/pic14/libm/Makefile.in
 @@ -511,13 +511,12 @@ GENERIC_SRC_DIR_ABS = $(abspath $(GENERIC_SRC_DIR))
@@ -762,7 +762,7 @@ index f0dc9ca..98ed2cf 100644
  # extensions generated by the build process
  CLEAN_EXTENSIONS = .asm .lst .sym .d .p .g .v .adb
 diff --git a/device/lib/pic14/libsdcc/enhanced-no-xinst/Makefile.in b/device/lib/pic14/libsdcc/enhanced-no-xinst/Makefile.in
-index 098ec94..d1240ba 100644
+index c82f7ba..780fa77 100644
 --- a/device/lib/pic14/libsdcc/enhanced-no-xinst/Makefile.in
 +++ b/device/lib/pic14/libsdcc/enhanced-no-xinst/Makefile.in
 @@ -518,13 +518,12 @@ GENERIC_SRC_DIR_ABS = $(abspath $(GENERIC_SRC_DIR))
@@ -791,7 +791,7 @@ index 098ec94..d1240ba 100644
  # extensions generated by the build process
  CLEAN_EXTENSIONS = .asm .lst .sym .d .p .g .v .adb
 diff --git a/device/lib/pic14/libsdcc/enhanced/Makefile.in b/device/lib/pic14/libsdcc/enhanced/Makefile.in
-index d2dba9c..0857601 100644
+index 33b8299..f4e0398 100644
 --- a/device/lib/pic14/libsdcc/enhanced/Makefile.in
 +++ b/device/lib/pic14/libsdcc/enhanced/Makefile.in
 @@ -518,13 +518,12 @@ GENERIC_SRC_DIR_ABS = $(abspath $(GENERIC_SRC_DIR))
@@ -820,7 +820,7 @@ index d2dba9c..0857601 100644
  # extensions generated by the build process
  CLEAN_EXTENSIONS = .asm .lst .sym .d .p .g .v .adb
 diff --git a/device/lib/pic14/libsdcc/regular/Makefile.in b/device/lib/pic14/libsdcc/regular/Makefile.in
-index 3c9bccd..9430fb5 100644
+index 6586b7d..7010287 100644
 --- a/device/lib/pic14/libsdcc/regular/Makefile.in
 +++ b/device/lib/pic14/libsdcc/regular/Makefile.in
 @@ -511,13 +511,12 @@ GENERIC_SRC_DIR_ABS = $(abspath $(GENERIC_SRC_DIR))
@@ -875,7 +875,7 @@ index 01ad950..62839b9 100644
  
  clean-local:
 diff --git a/device/lib/pic16/Makefile.in b/device/lib/pic16/Makefile.in
-index 15d2e1d..9664ad4 100644
+index e4e3abb..730066b 100644
 --- a/device/lib/pic16/Makefile.in
 +++ b/device/lib/pic16/Makefile.in
 @@ -87,10 +87,7 @@ PRE_UNINSTALL = :
@@ -915,7 +915,7 @@ index 15d2e1d..9664ad4 100644
  all: config.h
  	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 diff --git a/device/lib/pic16/configure b/device/lib/pic16/configure
-index c8f5b98..76f93a8 100755
+index ed8ad06..65baa93 100755
 --- a/device/lib/pic16/configure
 +++ b/device/lib/pic16/configure
 @@ -3657,7 +3657,6 @@ fi
@@ -942,7 +942,7 @@ index 3966c11..cdbffc7 100644
  
  # Checks for header files.
 diff --git a/device/lib/pic16/debug/Makefile.in b/device/lib/pic16/debug/Makefile.in
-index df593e3..8cb5137 100644
+index 8d5eb80..9dd8bb2 100644
 --- a/device/lib/pic16/debug/Makefile.in
 +++ b/device/lib/pic16/debug/Makefile.in
 @@ -88,10 +88,7 @@ PRE_UNINSTALL = :
@@ -982,7 +982,7 @@ index df593e3..8cb5137 100644
  
  .SUFFIXES:
 diff --git a/device/lib/pic16/libc/Makefile.in b/device/lib/pic16/libc/Makefile.in
-index 85bec90..c0ea488 100644
+index 659db72..cbb73bf 100644
 --- a/device/lib/pic16/libc/Makefile.in
 +++ b/device/lib/pic16/libc/Makefile.in
 @@ -88,10 +88,7 @@ PRE_UNINSTALL = :
@@ -1022,7 +1022,7 @@ index 85bec90..c0ea488 100644
  
  .SUFFIXES:
 diff --git a/device/lib/pic16/libio/Makefile.in b/device/lib/pic16/libio/Makefile.in
-index 06fff29..78fe388 100644
+index 128ffcc..b298c7c 100644
 --- a/device/lib/pic16/libio/Makefile.in
 +++ b/device/lib/pic16/libio/Makefile.in
 @@ -481,10 +481,7 @@ POST_UNINSTALL = :
@@ -1107,7 +1107,7 @@ index 211604e..e8896bf 100755
  include \$(top_srcdir)/Makefile.common
  
 diff --git a/device/lib/pic16/libm/Makefile.in b/device/lib/pic16/libm/Makefile.in
-index 6728a39..495459e 100644
+index af29662..05f1c24 100644
 --- a/device/lib/pic16/libm/Makefile.in
 +++ b/device/lib/pic16/libm/Makefile.in
 @@ -88,10 +88,7 @@ PRE_UNINSTALL = :
@@ -1147,7 +1147,7 @@ index 6728a39..495459e 100644
  
  .SUFFIXES:
 diff --git a/device/lib/pic16/libsdcc/Makefile.in b/device/lib/pic16/libsdcc/Makefile.in
-index 331aea0..63565be 100644
+index d384631..01129e3 100644
 --- a/device/lib/pic16/libsdcc/Makefile.in
 +++ b/device/lib/pic16/libsdcc/Makefile.in
 @@ -88,10 +88,7 @@ PRE_UNINSTALL = :
@@ -1187,7 +1187,7 @@ index 331aea0..63565be 100644
  
  .SUFFIXES:
 diff --git a/device/lib/pic16/startup/Makefile.in b/device/lib/pic16/startup/Makefile.in
-index 2e59220..b213866 100644
+index 6169096..0172a25 100644
 --- a/device/lib/pic16/startup/Makefile.in
 +++ b/device/lib/pic16/startup/Makefile.in
 @@ -89,10 +89,7 @@ PRE_UNINSTALL = :
@@ -1227,7 +1227,7 @@ index 2e59220..b213866 100644
  
  .SUFFIXES:
 diff --git a/doc/INSTALL.txt b/doc/INSTALL.txt
-index 76a6f42..0f92463 100644
+index d630b99..8cd747f 100644
 --- a/doc/INSTALL.txt
 +++ b/doc/INSTALL.txt
 @@ -18,9 +18,7 @@ To install:
@@ -1279,7 +1279,7 @@ index 88f8c98..a36db81 100644
  See:
  
 diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx
-index d18a509..b95bf61 100644
+index c8f8e73..e4afb0c 100644
 --- a/doc/sdccman.lyx
 +++ b/doc/sdccman.lyx
 @@ -1092,54 +1092,9 @@ A possible exception are pic device libraries and header files which are
@@ -1340,7 +1340,7 @@ index d18a509..b95bf61 100644
  \end_layout
  
  \begin_layout Itemize
-@@ -2870,18 +2825,6 @@ include_dir_suffix environment variable, see table below
+@@ -2890,18 +2845,6 @@ include_dir_suffix environment variable, see table below
  \end_inset
  
  
@@ -1359,7 +1359,7 @@ index d18a509..b95bf61 100644
  \begin_inset space ~
  \end_inset
  
-@@ -2894,22 +2837,6 @@ lib_dir_suffix environment variable, see table below
+@@ -2914,22 +2857,6 @@ lib_dir_suffix environment variable, see table below
  \end_inset
  
  
@@ -1382,7 +1382,7 @@ index d18a509..b95bf61 100644
  \begin_inset space ~
  \end_inset
  
-@@ -3408,7 +3335,7 @@ These defaults are:
+@@ -3428,7 +3355,7 @@ These defaults are:
  \begin_layout Standard
  \align center
  \begin_inset Tabular
@@ -1391,7 +1391,7 @@ index d18a509..b95bf61 100644
  <features tabularvalignment="middle">
  <column alignment="block" valignment="top" width="0in">
  <column alignment="block" valignment="top" width="0in">
-@@ -3692,68 +3619,6 @@ sdcc/include
+@@ -3712,68 +3639,6 @@ sdcc/include
  include
  \end_layout
  
@@ -1460,7 +1460,7 @@ index d18a509..b95bf61 100644
  \end_inset
  </cell>
  </row>
-@@ -3764,7 +3629,7 @@ lib
+@@ -3784,7 +3649,7 @@ lib
  \begin_layout Plain Layout
  
  \emph on
@@ -1469,7 +1469,7 @@ index d18a509..b95bf61 100644
  \end_layout
  
  \end_inset
-@@ -3773,7 +3638,7 @@ NON_FREE_LIB_DIR_SUFFIX
+@@ -3793,7 +3658,7 @@ NON_FREE_LIB_DIR_SUFFIX
  \begin_inset Text
  
  \begin_layout Plain Layout
@@ -1478,7 +1478,7 @@ index d18a509..b95bf61 100644
  \end_layout
  
  \end_inset
-@@ -3782,7 +3647,7 @@ sdcc/non-free/lib
+@@ -3802,7 +3667,7 @@ sdcc/non-free/lib
  \begin_inset Text
  
  \begin_layout Plain Layout
@@ -1487,7 +1487,7 @@ index d18a509..b95bf61 100644
  \end_layout
  
  \end_inset
-@@ -4181,20 +4046,6 @@ include
+@@ -4201,20 +4066,6 @@ include
  \end_inset
  
   
@@ -1508,7 +1508,7 @@ index d18a509..b95bf61 100644
  \backslash
  
  \begin_inset Newline newline
-@@ -4209,20 +4060,6 @@ lib
+@@ -4229,20 +4080,6 @@ lib
  \end_inset
  
   
@@ -1529,7 +1529,7 @@ index d18a509..b95bf61 100644
  \backslash
  
  \begin_inset Newline newline
-@@ -4403,20 +4240,6 @@ include
+@@ -4423,20 +4260,6 @@ include
  \end_inset
  
   
@@ -1550,7 +1550,7 @@ index d18a509..b95bf61 100644
  \backslash
  
  \begin_inset Newline newline
-@@ -4431,20 +4254,6 @@ lib
+@@ -4451,20 +4274,6 @@ lib
  \end_inset
  
   
@@ -1571,7 +1571,7 @@ index d18a509..b95bf61 100644
  \backslash
  
  \begin_inset Newline newline
-@@ -4541,7 +4350,7 @@ Install paths
+@@ -4561,7 +4370,7 @@ Install paths
  \begin_layout Standard
  \align center
  \begin_inset Tabular
@@ -1580,7 +1580,7 @@ index d18a509..b95bf61 100644
  <features tabularvalignment="middle">
  <column alignment="left" valignment="top">
  <column alignment="left" valignment="top" width="4.5cm">
-@@ -4697,64 +4506,6 @@ include
+@@ -4717,64 +4526,6 @@ include
  <cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none">
  \begin_inset Text
  
@@ -1645,7 +1645,7 @@ index d18a509..b95bf61 100644
  \begin_layout Plain Layout
  Library file**
  \end_layout
-@@ -4804,64 +4555,6 @@ sdcc
+@@ -4824,64 +4575,6 @@ sdcc
  lib
  \end_layout
  
@@ -1710,7 +1710,7 @@ index d18a509..b95bf61 100644
  \end_inset
  </cell>
  </row>
-@@ -5184,7 +4877,7 @@ $PATH
+@@ -5204,7 +4897,7 @@ $PATH
  \begin_layout Standard
  \align center
  \begin_inset Tabular
@@ -1719,7 +1719,7 @@ index d18a509..b95bf61 100644
  <features tabularvalignment="middle">
  <column alignment="block" valignment="top" width="0.5cm">
  <column alignment="block" valignment="top" width="4.8cm">
-@@ -5462,203 +5155,13 @@ include
+@@ -5482,203 +5175,13 @@ include
  </cell>
  </row>
  <row>
@@ -1924,7 +1924,7 @@ index d18a509..b95bf61 100644
  \end_inset
  </cell>
  <cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none">
-@@ -5674,21 +5177,13 @@ $DATADIR/
+@@ -5694,21 +5197,13 @@ $DATADIR/
  \end_inset
  
  
@@ -1947,7 +1947,7 @@ index d18a509..b95bf61 100644
  \begin_inset Text
  
  \begin_layout Plain Layout
-@@ -5696,7 +5191,7 @@ $INCLUDE_DIR_SUFFIX
+@@ -5716,7 +5211,7 @@ $INCLUDE_DIR_SUFFIX
  \begin_inset Newline newline
  \end_inset
  
@@ -1956,7 +1956,7 @@ index d18a509..b95bf61 100644
  \end_layout
  
  \end_inset
-@@ -5794,7 +5289,7 @@ model
+@@ -5814,7 +5309,7 @@ model
  \begin_layout Standard
  \align center
  \begin_inset Tabular
@@ -1965,7 +1965,7 @@ index d18a509..b95bf61 100644
  <features tabularvalignment="middle">
  <column alignment="block" valignment="top" width="0.5cm">
  <column alignment="block" valignment="top" width="4.5cm">
-@@ -6074,7 +5569,7 @@ lib
+@@ -6094,7 +5589,7 @@ lib
  </cell>
  </row>
  <row>
@@ -1974,7 +1974,7 @@ index d18a509..b95bf61 100644
  \begin_inset Text
  
  \begin_layout Plain Layout
-@@ -6083,7 +5578,7 @@ lib
+@@ -6103,7 +5598,7 @@ lib
  
  \end_inset
  </cell>
@@ -1983,7 +1983,7 @@ index d18a509..b95bf61 100644
  \begin_inset Text
  
  \begin_layout Plain Layout
-@@ -6114,7 +5609,7 @@ $LIB_DIR_SUFFIX/
+@@ -6134,7 +5629,7 @@ $LIB_DIR_SUFFIX/
  
  \end_inset
  </cell>
@@ -1992,7 +1992,7 @@ index d18a509..b95bf61 100644
  \begin_inset Text
  
  \begin_layout Plain Layout
-@@ -6129,7 +5624,7 @@ lib/
+@@ -6149,7 +5644,7 @@ lib/
  
  \end_inset
  </cell>
@@ -2001,7 +2001,7 @@ index d18a509..b95bf61 100644
  \begin_inset Text
  
  \begin_layout Plain Layout
-@@ -6152,308 +5647,6 @@ lib
+@@ -6172,308 +5667,6 @@ lib
  <model>
  \end_layout
  
@@ -2310,7 +2310,7 @@ index d18a509..b95bf61 100644
  \end_inset
  </cell>
  </row>
-@@ -8717,14 +7910,6 @@ In <installdir>/share/sdcc/include
+@@ -8737,14 +7930,6 @@ In <installdir>/share/sdcc/include
  the include files
  \end_layout
  
@@ -2325,7 +2325,7 @@ index d18a509..b95bf61 100644
  \begin_layout Standard
  In <installdir>/share/sdcc/lib
  \end_layout
-@@ -8733,14 +7918,6 @@ In <installdir>/share/sdcc/lib
+@@ -8753,14 +7938,6 @@ In <installdir>/share/sdcc/lib
  the src and target subdirectories with the precompiled relocatables.
  \end_layout
  
@@ -2340,7 +2340,7 @@ index d18a509..b95bf61 100644
  \begin_layout Standard
  In <installdir>/share/sdcc/doc
  \end_layout
-@@ -15254,66 +14431,6 @@ splint
+@@ -15274,66 +14451,6 @@ splint
  myprogram.c
  \end_layout
  
@@ -2407,7 +2407,7 @@ index d18a509..b95bf61 100644
  \begin_layout Subsection
  Linker Options
  \begin_inset Index idx
-@@ -44656,66 +43773,9 @@ http://sourceforge.net/projects/gputils
+@@ -44653,66 +43770,9 @@ http://sourceforge.net/projects/gputils
  Pic device specific header and c source files are automatically generated
   from MPLAB include files, which are published by Microchip with a special
   requirement that they are only to be used with authentic Microchip devices.
@@ -2477,7 +2477,7 @@ index d18a509..b95bf61 100644
  \begin_inset Newline newline
  \end_inset
  
-@@ -44769,7 +43829,7 @@ Makefile
+@@ -44766,7 +43826,7 @@ Makefile
  \begin_inset space ~
  \end_inset
  
@@ -2486,7 +2486,7 @@ index d18a509..b95bf61 100644
  \begin_inset Newline newline
  \end_inset
  
-@@ -44863,7 +43923,7 @@ Makefile
+@@ -44860,7 +43920,7 @@ Makefile
  \begin_inset space ~
  \end_inset
  
@@ -2495,7 +2495,7 @@ index d18a509..b95bf61 100644
  \begin_inset Newline newline
  \end_inset
  
-@@ -45145,47 +44205,6 @@ status collapsed
+@@ -45142,47 +44202,6 @@ status collapsed
  \begin_layout Plain Layout
  
  
@@ -2543,7 +2543,7 @@ index d18a509..b95bf61 100644
  \backslash
  /
  \end_layout
-@@ -46058,47 +45077,6 @@ status collapsed
+@@ -46055,47 +45074,6 @@ status collapsed
  -all-callee-saves
  \end_layout
  
@@ -2591,7 +2591,7 @@ index d18a509..b95bf61 100644
  \begin_layout Subsection
  Port Specific Options
  \begin_inset Index idx
-@@ -47375,188 +46353,6 @@ Linker
+@@ -47372,188 +46350,6 @@ Linker
  \end_inset
  
  
@@ -2780,7 +2780,7 @@ index d18a509..b95bf61 100644
  \end_layout
  
  \begin_layout Subsection
-@@ -48252,66 +47048,9 @@ name "subsec:PIC16_Header-Files-and-Libraries"
+@@ -48249,66 +47045,9 @@ name "subsec:PIC16_Header-Files-and-Libraries"
  Pic device specific header and c source files are automatically generated
   from MPLAB include files, which are published by Microchip with a special
   requirement that they are only to be used with authentic Microchip devices.
@@ -2850,7 +2850,7 @@ index d18a509..b95bf61 100644
  \end_layout
  
  \begin_layout Subsection
-@@ -48557,195 +47296,6 @@ vfprintf.c
+@@ -48554,195 +47293,6 @@ vfprintf.c
   should also work, but is untested.
  \end_layout
  
@@ -3046,7 +3046,7 @@ index d18a509..b95bf61 100644
  \begin_layout Subsection
  Memory Models
  \end_layout
-@@ -73531,6 +72081,12 @@ This document was initially written by Sandeep Dutta and updated by SDCC
+@@ -73528,6 +72078,12 @@ This document was initially written by Sandeep Dutta and updated by SDCC
   developers.
  \end_layout
  
@@ -3060,10 +3060,10 @@ index d18a509..b95bf61 100644
  All product names mentioned herein may be trademarks
  \begin_inset Index idx
 diff --git a/sdcc.spec b/sdcc.spec
-index b8baa92..be90a84 100644
+index 3609ffe..4b4a5cb 100644
 --- a/sdcc.spec
 +++ b/sdcc.spec
-@@ -83,15 +83,15 @@ rm -rf $RPM_BUILD_ROOT
+@@ -89,9 +89,7 @@ rm -rf $RPM_BUILD_ROOT
  %files common
  %defattr(-,root,root)
  /usr/share/sdcc/include
@@ -3073,12 +3073,13 @@ index b8baa92..be90a84 100644
  
  %files doc
  %defattr(-,root,root)
- %doc %{_defaultdocdir}
- 
+@@ -100,6 +98,8 @@ rm -rf $RPM_BUILD_ROOT
  %changelog
+ * Sat Feb 20 2021 - pkk AT spth.de
+ - version updated to 4.0.0
 +* Tue Dec 08 2020 - simon AT simonsouth.net
 +- removed non-free include and lib directories
- * Sat Jan 18 2029 - pkk AT spth.de
+ * Sat Jan 18 2020 - pkk AT spth.de
  - version updated to 4.0.0
  * Fri Apr 05 2019 - krauseph AT informatik.uni-freiburg.de
 diff --git a/sdcc_vc.h.in b/sdcc_vc.h.in
@@ -3095,10 +3096,10 @@ index 06d8cca..736c325 100644
  #define BIN2DATA_DIR                "\\.."
  #define PREFIX2BIN_DIR              "\\bin"
 diff --git a/sdccconf_in.h b/sdccconf_in.h
-index aeb2724..9c1df9d 100644
+index eb6f48b..9f5b003 100644
 --- a/sdccconf_in.h
 +++ b/sdccconf_in.h
-@@ -97,12 +97,6 @@
+@@ -100,12 +100,6 @@
  /* XXX */
  #undef LIB_DIR_SUFFIX
  
@@ -3111,7 +3112,7 @@ index aeb2724..9c1df9d 100644
  /* Define to 1 to disable the AVR port */
  #undef OPT_DISABLE_AVR
  
-@@ -127,9 +121,6 @@
+@@ -130,9 +124,6 @@
  /* XXX */
  #undef OPT_DISABLE_MCS51
  
@@ -3122,11 +3123,11 @@ index aeb2724..9c1df9d 100644
  #undef OPT_DISABLE_PACKIHX
  
 diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h
-index b8d156b..db81fd7 100644
+index 9383f68..c2f0b42 100644
 --- a/src/SDCCglobl.h
 +++ b/src/SDCCglobl.h
 @@ -288,7 +288,6 @@ struct options
-     int no_pack_iram;           /* MCS51/DS390 - Deprecated: Tells the linker not to pack variables in internal ram */
+     int stack_size;             /* MCS51/DS390 - Tells the linker to allocate this space for stack */
      int acall_ajmp;             /* MCS51 - Use acall/ajmp instead of lcall/ljmp */
      int no_ret_without_call;    /* MCS51 - Do not use ret independent of acall/lcall */
 -    int use_non_free;           /* Search / include non-free licensed libraries and header files */
@@ -3134,10 +3135,10 @@ index b8d156b..db81fd7 100644
      int xstack_loc;             /* initial location of external stack */
      int stack_loc;              /* initial value of internal stack pointer */
 diff --git a/src/SDCCmain.c b/src/SDCCmain.c
-index d4598a5..cd36f3d 100644
+index 2a7a711..f46370f 100644
 --- a/src/SDCCmain.c
 +++ b/src/SDCCmain.c
-@@ -142,7 +142,6 @@ char buffer[PATH_MAX * 2];
+@@ -151,7 +151,6 @@ char buffer[PATH_MAX * 2];
  #define OPTION_DATA_SEG             "--dataseg"
  #define OPTION_DOLLARS_IN_IDENT     "--fdollars-in-identifiers"
  #define OPTION_SIGNED_CHAR          "--fsigned-char"
@@ -3145,7 +3146,7 @@ index d4598a5..cd36f3d 100644
  #define OPTION_PEEP_RETURN          "--peep-return"
  #define OPTION_NO_PEEP_RETURN       "--no-peep-return"
  #define OPTION_NO_OPTSDCC_IN_ASM    "--no-optsdcc-in-asm"
-@@ -197,7 +196,6 @@ static const OPTION optionsTable[] = {
+@@ -207,7 +206,6 @@ static const OPTION optionsTable[] = {
    {0,   OPTION_STD_SDCC2X, NULL, "Use ISO C2X standard with SDCC extensions"},
    {0,   OPTION_DOLLARS_IN_IDENT, &options.dollars_in_ident, "Permit '$' as an identifier character"},
    {0,   OPTION_SIGNED_CHAR, &options.signed_char, "Make \"char\" signed by default"},
@@ -3153,7 +3154,7 @@ index d4598a5..cd36f3d 100644
  
    {0,   NULL, NULL, "Code generation options"},
    {'m', NULL, NULL, "Set the port to use e.g. -mz80."},
-@@ -2084,10 +2082,6 @@ preProcess (char **envp)
+@@ -2113,10 +2111,6 @@ preProcess (char **envp)
        else
          addSet (&preArgvSet, Safe_strdup ("-D__SDCC_CHAR_UNSIGNED"));
  
@@ -3164,7 +3165,7 @@ index d4598a5..cd36f3d 100644
        /* set the macro for large model  */
        switch (options.model)
          {
-@@ -2301,12 +2295,6 @@ setIncludePath (void)
+@@ -2336,12 +2330,6 @@ setIncludePath (void)
     *  6. - $SDCC_HOME/PREFIX2DATA_DIR/INCLUDE_DIR_SUFFIX
     *  7. - path(argv[0])/BIN2DATA_DIR/INCLUDE_DIR_SUFFIX
     *  8. - DATADIR/INCLUDE_DIR_SUFFIX (only on *nix)
@@ -3177,8 +3178,8 @@ index d4598a5..cd36f3d 100644
     */
  
    if (!options.nostdinc)
-@@ -2319,17 +2307,6 @@ setIncludePath (void)
-       includeDirsSet = processStrSet (includeDirsSet, NULL, port->target, NULL);
+@@ -2357,17 +2345,6 @@ setIncludePath (void)
+         includeDirsSet = processStrSet (includeDirsSet, NULL, port->target, NULL);
        mergeSets (&includeDirsSet, tempSet);
  
 -      if (options.use_non_free)
@@ -3195,7 +3196,7 @@ index d4598a5..cd36f3d 100644
        if ((p = getenv (SDCC_INCLUDE_NAME)) != NULL)
          {
            struct dbuf_s dbuf;
-@@ -2354,9 +2331,6 @@ setLibPath (void)
+@@ -2392,9 +2369,6 @@ setLibPath (void)
     * 3. - $SDCC_HOME/PREFIX2DATA_DIR/LIB_DIR_SUFFIX/<model>
     * 4. - path(argv[0])/BIN2DATA_DIR/LIB_DIR_SUFFIX/<model>
     * 5. - DATADIR/LIB_DIR_SUFFIX/<model> (only on *nix)
@@ -3205,7 +3206,7 @@ index d4598a5..cd36f3d 100644
     */
  
    if (!options.nostdlib)
-@@ -2373,13 +2347,6 @@ setLibPath (void)
+@@ -2411,13 +2385,6 @@ setLibPath (void)
        dbuf_makePath (&dbuf, LIB_DIR_SUFFIX, port->general.get_model ? port->general.get_model () : targetname);
        libDirsSet = processStrSet (dataDirsSet, NULL, dbuf_c_str (&dbuf), NULL);
  
@@ -3273,7 +3274,7 @@ index cdfbba0..5877f09 100644
  
  extern pic16_options_t pic16_options;
 diff --git a/src/pic16/main.c b/src/pic16/main.c
-index 61d9cfb..75d1182 100644
+index d416642..bfe514d 100644
 --- a/src/pic16/main.c
 +++ b/src/pic16/main.c
 @@ -655,7 +655,6 @@ OPTION pic16_optionsTable[]= {
@@ -3495,10 +3496,10 @@ index 6db417a..4b35225 100755
    );
  
 diff --git a/support/scripts/sdcc.nsi b/support/scripts/sdcc.nsi
-index 68e9035..92e5784 100644
+index da63063..dae8d8d 100644
 --- a/support/scripts/sdcc.nsi
 +++ b/support/scripts/sdcc.nsi
-@@ -483,11 +483,6 @@ ${Section} "SDCC include files" SEC05
+@@ -479,11 +479,6 @@ ${Section} "SDCC include files" SEC05
  
    SetOutPath "$INSTDIR\include"
    File "${DEV_ROOT}\include\*.h"
@@ -3510,7 +3511,7 @@ index 68e9035..92e5784 100644
  ${SectionEnd}
  
  ${Section} "SDCC DS390 library" SEC06
-@@ -585,18 +580,12 @@ ${Section} "SDCC PIC16 library" SEC21
+@@ -581,18 +576,12 @@ ${Section} "SDCC PIC16 library" SEC21
    SetOutPath "$INSTDIR\lib\pic16"
    File "${DEV_ROOT}\lib\pic16\*.o"
    File "${DEV_ROOT}\lib\pic16\*.lib"
@@ -3551,7 +3552,7 @@ index 68e9035..92e5784 100644
    SetOutPath "$INSTDIR\lib\src\pic16\libio"
    File "${DEV_ROOT}\lib\src\pic16\libio\*.ignore"
  #  File "${DEV_ROOT}\lib\src\pic16\libio\Makefile"
-@@ -1074,13 +1055,9 @@ ${Section} Uninstall SECUNINSTALL
+@@ -1105,13 +1086,9 @@ ${Section} Uninstall SECUNINSTALL
  
    Delete "$INSTDIR\lib\pic14\*.lib"
  
@@ -3565,7 +3566,7 @@ index 68e9035..92e5784 100644
    Delete "$INSTDIR\lib\hc08\*.lib"
  
    Delete "$INSTDIR\lib\s08\*.lib"
-@@ -1144,9 +1121,7 @@ ${Section} Uninstall SECUNINSTALL
+@@ -1182,9 +1159,7 @@ ${Section} Uninstall SECUNINSTALL
    Delete "$INSTDIR\include\pic14\*.h"
    Delete "$INSTDIR\include\pic14\*.txt"
    Delete "$INSTDIR\include\pic14\*.inc"
@@ -3575,7 +3576,7 @@ index 68e9035..92e5784 100644
    Delete "$INSTDIR\include\pic16\*.txt"
    Delete "$INSTDIR\include\mcs51\*.h"
    Delete "$INSTDIR\include\hc08\*.h"
-@@ -1208,9 +1183,7 @@ ${Section} Uninstall SECUNINSTALL
+@@ -1246,9 +1221,7 @@ ${Section} Uninstall SECUNINSTALL
    Delete "$INSTDIR\uninstall.exe"
  
    RMDir /r "$INSTDIR\lib\src\pic14"
@@ -3585,9 +3586,9 @@ index 68e9035..92e5784 100644
    RMDir "$INSTDIR\lib\src\small"
    RMDir "$INSTDIR\lib\src\medium"
    RMDir "$INSTDIR\lib\src\large"
-@@ -1233,12 +1206,9 @@ ${Section} Uninstall SECUNINSTALL
-   RMDir "$INSTDIR\lib\src\pdk15"
-   RMDir "$INSTDIR\lib\src\pdk15-stack-auto"
+@@ -1274,12 +1247,9 @@ ${Section} Uninstall SECUNINSTALL
+   RMDir "$INSTDIR\lib\src\tlcs90"
+   RMDir "$INSTDIR\lib\src\z80n"
    RMDir "$INSTDIR\lib\src"
 -  RMDir "$INSTDIR\non-free\lib\src"
  
@@ -3598,17 +3599,15 @@ index 68e9035..92e5784 100644
    RMDir "$INSTDIR\lib\z80"
    RMDir "$INSTDIR\lib\z180"
    RMDir "$INSTDIR\lib\r2k"
-@@ -1261,7 +1231,6 @@ ${Section} Uninstall SECUNINSTALL
-   RMDir "$INSTDIR\lib\pdk15"
-   RMDir "$INSTDIR\lib\pdk15-stack-auto"
+@@ -1305,15 +1275,12 @@ ${Section} Uninstall SECUNINSTALL
+   RMDir "$INSTDIR\lib\tlcs90"
+   RMDir "$INSTDIR\lib\z80n"
    RMDir "$INSTDIR\lib"
 -  RMDir "$INSTDIR\non-free\lib"
  
    RMDir "$INSTDIR\include\asm\z80"
-   RMDir "$INSTDIR\include\asm\z180"
-@@ -1269,9 +1238,7 @@ ${Section} Uninstall SECUNINSTALL
+   RMDir "$INSTDIR\include\asm\r2k"
    RMDir "$INSTDIR\include\asm\r3ka"
-   RMDir "$INSTDIR\include\asm\ez80_z80"
    RMDir "$INSTDIR\include\asm\pic16"
 -  RMDir "$INSTDIR\non-free\include\asm\pic16"
    RMDir "$INSTDIR\include\asm\pic14"
@@ -3616,7 +3615,7 @@ index 68e9035..92e5784 100644
    RMDir "$INSTDIR\include\asm\mcs51"
    RMDir "$INSTDIR\include\asm\gbz80"
    RMDir "$INSTDIR\include\asm\ds390"
-@@ -1280,17 +1247,12 @@ ${Section} Uninstall SECUNINSTALL
+@@ -1322,17 +1289,12 @@ ${Section} Uninstall SECUNINSTALL
    RMDir "$INSTDIR\include\asm"
    RMDir "$INSTDIR\include\z180"
    RMDir "$INSTDIR\include\pic14"
diff --git a/gnu/packages/patches/ungoogled-chromium-system-opus.patch b/gnu/packages/patches/ungoogled-chromium-system-opus.patch
new file mode 100644
index 0000000000..6f887a31a4
--- /dev/null
+++ b/gnu/packages/patches/ungoogled-chromium-system-opus.patch
@@ -0,0 +1,27 @@
+Add missing build dependency on Opus so that system headers are found.
+
+Taken from upstream:
+https://chromium-review.googlesource.com/c/chromium/src/+/2644623
+
+diff --git a/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
+--- a/third_party/blink/renderer/modules/webcodecs/BUILD.gn
++++ b/third_party/blink/renderer/modules/webcodecs/BUILD.gn
+@@ -65,6 +65,7 @@ blink_modules_sources("webcodecs") {
+     "//media/mojo/clients",
+     "//media/mojo/mojom",
+     "//third_party/libyuv:libyuv",
++    "//third_party/opus",
+   ]
+   if (media_use_openh264) {
+     deps += [ "//third_party/openh264:encoder" ]
+diff --git a/third_party/blink/renderer/modules/webcodecs/DEPS b/third_party/blink/renderer/modules/webcodecs/DEPS
+--- a/third_party/blink/renderer/modules/webcodecs/DEPS
++++ b/third_party/blink/renderer/modules/webcodecs/DEPS
+@@ -19,6 +19,7 @@ include_rules = [
+ 
+     "+third_party/libyuv",
+     "+third_party/openh264",
++    "+third_party/opus",
+ 
+     "+ui/gfx/color_space.h",
+     "+ui/gfx/geometry/rect.h",
diff --git a/gnu/packages/patches/unzip-32bit-zipbomb-fix.patch b/gnu/packages/patches/unzip-32bit-zipbomb-fix.patch
new file mode 100644
index 0000000000..ad6a157c56
--- /dev/null
+++ b/gnu/packages/patches/unzip-32bit-zipbomb-fix.patch
@@ -0,0 +1,50 @@
+From 13f0260beae851f7d5dd96e9ef757d8d6d7daac1 Mon Sep 17 00:00:00 2001
+From: Mark Adler <madler@alumni.caltech.edu>
+Date: Sun, 9 Feb 2020 07:20:13 -0800
+Subject: [PATCH] Fix false overlapped components detection on 32-bit systems.
+
+32-bit systems with ZIP64_SUPPORT enabled could have different
+size types for zoff_t and zusz_t. That resulted in bad parameter
+passing to the bound tracking functions, itself due to the lack of
+use of C function prototypes in unzip. This commit assures that
+parameters are cast properly for those calls.
+
+This problem occurred only for ill-chosen make options, which give
+a 32-bit zoff_t. A proper build will result in a zoff_t of 64 bits,
+even on 32-bit systems.
+---
+ extract.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/extract.c b/extract.c
+index 1b73cb0..d9866f9 100644
+--- a/extract.c
++++ b/extract.c
+@@ -329,7 +329,7 @@ static ZCONST char Far OverlappedComponents[] =
+ 
+ 
+ /* A growable list of spans. */
+-typedef zoff_t bound_t;
++typedef zusz_t bound_t;
+ typedef struct {
+     bound_t beg;        /* start of the span */
+     bound_t end;        /* one past the end of the span */
+@@ -518,7 +518,8 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+         return PK_MEM;
+     }
+     if ((G.extra_bytes != 0 &&
+-         cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
++         cover_add((cover_t *)G.cover,
++                   (bound_t)0, (bound_t)G.extra_bytes) != 0) ||
+         (G.ecrec.have_ecr64 &&
+          cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
+                    G.ecrec.ec64_end) != 0) ||
+@@ -1216,7 +1217,7 @@ static int extract_or_test_entrylist(__G__ numchunk,
+ 
+         /* seek_zipf(__G__ pInfo->offset);  */
+         request = G.pInfo->offset + G.extra_bytes;
+-        if (cover_within((cover_t *)G.cover, request)) {
++        if (cover_within((cover_t *)G.cover, (bound_t)request)) {
+             Info(slide, 0x401, ((char *)slide,
+               LoadFarString(OverlappedComponents)));
+             return PK_BOMB;
diff --git a/gnu/packages/patches/unzip-COVSCAN-fix-unterminated-string.patch b/gnu/packages/patches/unzip-COVSCAN-fix-unterminated-string.patch
new file mode 100644
index 0000000000..717377119b
--- /dev/null
+++ b/gnu/packages/patches/unzip-COVSCAN-fix-unterminated-string.patch
@@ -0,0 +1,131 @@
+From 06d1b08aef94984256cad3c5a54cedb10295681f Mon Sep 17 00:00:00 2001
+From: Jakub Martisko <jamartis@redhat.com>
+Date: Thu, 8 Nov 2018 09:31:18 +0100
+Subject: [PATCH] Possible unterminated string fix
+
+---
+ unix/unix.c   |  4 +++-
+ unix/unxcfg.h |  2 +-
+ unzip.c       | 12 ++++++++----
+ zipinfo.c     | 12 ++++++++----
+ 4 files changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/unix/unix.c b/unix/unix.c
+index 59b622d..cd57f80 100644
+--- a/unix/unix.c
++++ b/unix/unix.c
+@@ -1945,7 +1945,9 @@ void init_conversion_charsets()
+     	for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
+     		if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
+     			strncpy(OEM_CP, dos_charset_map[i].archive_charset,
+-    					sizeof(OEM_CP));
++    					MAX_CP_NAME - 1);
++
++			OEM_CP[MAX_CP_NAME - 1] = '\0';
+     			break;
+     		}
+     }
+diff --git a/unix/unxcfg.h b/unix/unxcfg.h
+index 8729de2..9ee8cfe 100644
+--- a/unix/unxcfg.h
++++ b/unix/unxcfg.h
+@@ -228,7 +228,7 @@ typedef struct stat z_stat;
+ /*    and notfirstcall are used by do_wild().                          */
+ 
+ 
+-#define MAX_CP_NAME 25 
++#define MAX_CP_NAME 25 + 1 
+    
+ #ifdef SETLOCALE
+ #  undef SETLOCALE
+diff --git a/unzip.c b/unzip.c
+index 2d94a38..a485f2b 100644
+--- a/unzip.c
++++ b/unzip.c
+@@ -1561,7 +1561,8 @@ int uz_opts(__G__ pargc, pargv)
+         		                  "error:  a valid character encoding should follow the -I argument"));
+     	                        return(PK_PARAM); 
+     						}
+-    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
++                ISO_CP[MAX_CP_NAME - 1] = '\0';
+     					} else { /* -I charset */
+     						++argv;
+     						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+@@ -1570,7 +1571,8 @@ int uz_opts(__G__ pargc, pargv)
+     	                        return(PK_PARAM); 
+     						}
+     						s = *argv;
+-    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
++                ISO_CP[MAX_CP_NAME - 1] = '\0';
+     					}
+     					while(*(++s)); /* No params straight after charset name */
+     				}
+@@ -1665,7 +1667,8 @@ int uz_opts(__G__ pargc, pargv)
+         		                  "error:  a valid character encoding should follow the -I argument"));
+     	                        return(PK_PARAM); 
+     						}
+-    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
++                OEM_CP[MAX_CP_NAME - 1] = '\0';
+     					} else { /* -O charset */
+     						++argv;
+     						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+@@ -1674,7 +1677,8 @@ int uz_opts(__G__ pargc, pargv)
+     	                        return(PK_PARAM); 
+     						}
+     						s = *argv;
+-    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
++                OEM_CP[MAX_CP_NAME - 1] = '\0';
+     					}
+     					while(*(++s)); /* No params straight after charset name */
+     				}
+diff --git a/zipinfo.c b/zipinfo.c
+index accca2a..cb7e08d 100644
+--- a/zipinfo.c
++++ b/zipinfo.c
+@@ -519,7 +519,8 @@ int zi_opts(__G__ pargc, pargv)
+         		                  "error:  a valid character encoding should follow the -I argument"));
+     	                        return(PK_PARAM); 
+     						}
+-    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
++                ISO_CP[MAX_CP_NAME - 1] = '\0';
+     					} else { /* -I charset */
+     						++argv;
+     						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+@@ -528,7 +529,8 @@ int zi_opts(__G__ pargc, pargv)
+     	                        return(PK_PARAM); 
+     						}
+     						s = *argv;
+-    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    						strncpy(ISO_CP, s, MAX_CP_NAME - 1);
++                ISO_CP[MAX_CP_NAME - 1] = '\0';
+     					}
+     					while(*(++s)); /* No params straight after charset name */
+     				}
+@@ -568,7 +570,8 @@ int zi_opts(__G__ pargc, pargv)
+         		                  "error:  a valid character encoding should follow the -I argument"));
+     	                        return(PK_PARAM); 
+     						}
+-    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
++                OEM_CP[MAX_CP_NAME - 1] = '\0';
+     					} else { /* -O charset */
+     						++argv;
+     						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
+@@ -577,7 +580,8 @@ int zi_opts(__G__ pargc, pargv)
+     	                        return(PK_PARAM); 
+     						}
+     						s = *argv;
+-    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    						strncpy(OEM_CP, s, MAX_CP_NAME - 1);
++                OEM_CP[MAX_CP_NAME - 1] = '\0';
+     					}
+     					while(*(++s)); /* No params straight after charset name */
+     				}
+-- 
+2.14.5
+
diff --git a/gnu/packages/patches/unzip-CVE-2016-9844.patch b/gnu/packages/patches/unzip-CVE-2016-9844.patch
new file mode 100644
index 0000000000..0e4a173397
--- /dev/null
+++ b/gnu/packages/patches/unzip-CVE-2016-9844.patch
@@ -0,0 +1,39 @@
+From 754137e70cf58a64ad524b704a86b651ba0cde07 Mon Sep 17 00:00:00 2001
+From: Petr Stodulka <pstodulk@redhat.com>
+Date: Wed, 14 Dec 2016 16:30:36 +0100
+Subject: [PATCH] Fix CVE-2016-9844 (rhbz#1404283)
+
+Fixes buffer overflow in zipinfo in similar way like fix for
+CVE-2014-9913 provided by upstream.
+---
+ zipinfo.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/zipinfo.c b/zipinfo.c
+index c03620e..accca2a 100644
+--- a/zipinfo.c
++++ b/zipinfo.c
+@@ -1984,7 +1984,19 @@ static int zi_short(__G)   /* return PK-type error code */
+         ush  dnum=(ush)((G.crec.general_purpose_bit_flag>>1) & 3);
+         methbuf[3] = dtype[dnum];
+     } else if (methnum >= NUM_METHODS) {   /* unknown */
+-        sprintf(&methbuf[1], "%03u", G.crec.compression_method);
++        /* 2016-12-05 SMS.
++         * https://launchpad.net/bugs/1643750
++         * Unexpectedly large compression methods overflow
++         * &methbuf[].  Use the old, three-digit decimal format
++         * for values which fit.  Otherwise, sacrifice the "u",
++         * and use four-digit hexadecimal.
++         */
++        if (G.crec.compression_method <= 999) {
++              sprintf( &methbuf[ 1], "%03u", G.crec.compression_method);
++        } else {
++              sprintf( &methbuf[ 0], "%04X", G.crec.compression_method);
++        }
++
+     }
+ 
+     for (k = 0;  k < 15;  ++k)
+-- 
+2.5.5
+
diff --git a/gnu/packages/patches/unzip-CVE-2018-1000035.patch b/gnu/packages/patches/unzip-CVE-2018-1000035.patch
new file mode 100644
index 0000000000..8ca713865c
--- /dev/null
+++ b/gnu/packages/patches/unzip-CVE-2018-1000035.patch
@@ -0,0 +1,34 @@
+--- a/fileio.c	2014-12-05 05:06:05 -0600
++++ b/fileio.c	2017-11-14 01:06:28 -0600
+@@ -1,5 +1,5 @@
+ /*
+-  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
++  Copyright (c) 1990-2017 Info-ZIP.  All rights reserved.
+ 
+   See the accompanying file LICENSE, version 2009-Jan-02 or later
+   (the contents of which are also included in unzip.h) for terms of use.
+@@ -1582,6 +1582,8 @@
+     int r = IZ_PW_ENTERED;
+     char *m;
+     char *prompt;
++    char *ep;
++    char *zp;
+ 
+ #ifndef REENTRANT
+     /* tell picky compilers to shut up about "unused variable" warnings */
+@@ -1590,9 +1592,12 @@
+ 
+     if (*rcnt == 0) {           /* First call for current entry */
+         *rcnt = 2;
+-        if ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL) {
+-            sprintf(prompt, LoadFarString(PasswPrompt),
+-                    FnFilter1(zfn), FnFilter2(efn));
++        zp = FnFilter1( zfn);
++        ep = FnFilter2( efn);
++        prompt = (char *)malloc(        /* Slightly too long (2* "%s"). */
++         sizeof( PasswPrompt)+ strlen( zp)+ strlen( ep));
++        if (prompt != (char *)NULL) {
++            sprintf(prompt, LoadFarString(PasswPrompt), zp, ep);
+             m = prompt;
+         } else
+             m = (char *)LoadFarString(PasswPrompt2);
diff --git a/gnu/packages/patches/unzip-CVE-2018-18384.patch b/gnu/packages/patches/unzip-CVE-2018-18384.patch
new file mode 100644
index 0000000000..54d4b8cb64
--- /dev/null
+++ b/gnu/packages/patches/unzip-CVE-2018-18384.patch
@@ -0,0 +1,35 @@
+--- unzip60/list.c	
++++ unzip60/list.c	
+@@ -97,7 +97,7 @@ int list_files(__G)    /* return PK-type
+ {
+     int do_this_file=FALSE, cfactor, error, error_in_archive=PK_COOL;
+ #ifndef WINDLL
+-    char sgn, cfactorstr[13];
++    char sgn, cfactorstr[1+10+1+1];	/* <sgn><int>%NUL */
+     int longhdr=(uO.vflag>1);
+ #endif
+     int date_format;
+@@ -389,9 +389,9 @@ int list_files(__G)    /* return PK-type
+             }
+ #else /* !WINDLL */
+             if (cfactor == 100)
+-                sprintf(cfactorstr, LoadFarString(CompFactor100));
++                snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
+             else
+-                sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
++                snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
+             if (longhdr)
+                 Info(slide, 0, ((char *)slide, LoadFarString(LongHdrStats),
+                   FmZofft(G.crec.ucsize, "8", "u"), methbuf,
+@@ -471,9 +471,9 @@ int list_files(__G)    /* return PK-type
+ 
+ #else /* !WINDLL */
+         if (cfactor == 100)
+-            sprintf(cfactorstr, LoadFarString(CompFactor100));
++            snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactor100));
+         else
+-            sprintf(cfactorstr, LoadFarString(CompFactorStr), sgn, cfactor);
++            snprintf(cfactorstr, sizeof(cfactorstr), LoadFarString(CompFactorStr), sgn, cfactor);
+         if (longhdr) {
+             Info(slide, 0, ((char *)slide, LoadFarString(LongFileTrailer),
+               FmZofft(tot_ucsize, "8", "u"), FmZofft(tot_csize, "8", "u"),
diff --git a/gnu/packages/patches/unzip-alt-iconv-utf8-print.patch b/gnu/packages/patches/unzip-alt-iconv-utf8-print.patch
new file mode 100644
index 0000000000..0b0153ba54
--- /dev/null
+++ b/gnu/packages/patches/unzip-alt-iconv-utf8-print.patch
@@ -0,0 +1,381 @@
+From ca0212ba19b64488b9e8459a762c11ecd6e7d0bd Mon Sep 17 00:00:00 2001
+From: Petr Stodulka <pstodulk@redhat.com>
+Date: Tue, 24 Nov 2015 17:56:11 +0100
+Subject: [PATCH] print correctly non-ascii filenames
+
+---
+ extract.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
+ unzpriv.h |   7 ++
+ 2 files changed, 233 insertions(+), 63 deletions(-)
+
+diff --git a/extract.c b/extract.c
+index 0ee4e93..741b7e0 100644
+--- a/extract.c
++++ b/extract.c
+@@ -2648,8 +2648,21 @@ static void set_deferred_symlink(__G__ slnk_entry)
+ } /* end function set_deferred_symlink() */
+ #endif /* SYMLINKS */
+ 
++/*
++ * If Unicode is supported, assume we have what we need to do this
++ * check using wide characters, avoiding MBCS issues.
++ */
+ 
+-
++#ifndef UZ_FNFILTER_REPLACECHAR
++        /* A convenient choice for the replacement of unprintable char codes is
++         * the "single char wildcard", as this character is quite unlikely to
++         * appear in filenames by itself.  The following default definition
++         * sets the replacement char to a question mark as the most common
++         * "single char wildcard"; this setting should be overridden in the
++         * appropiate system-specific configuration header when needed.
++         */
++# define UZ_FNFILTER_REPLACECHAR      '?'
++#endif
+ 
+ /*************************/
+ /*  Function fnfilter()  */        /* here instead of in list.c for SFX */
+@@ -2661,48 +2674,168 @@ char *fnfilter(raw, space, size)   /* convert name to safely printable form */
+     extent size;
+ {
+ #ifndef NATIVE   /* ASCII:  filter ANSI escape codes, etc. */
+-    ZCONST uch *r=(ZCONST uch *)raw;
++    ZCONST uch *r; // =(ZCONST uch *)raw;
+     uch *s=space;
+     uch *slim=NULL;
+     uch *se=NULL;
+     int have_overflow = FALSE;
+ 
+-    if (size > 0) {
+-        slim = space + size
+-#ifdef _MBCS
+-                     - (MB_CUR_MAX - 1)
+-#endif
+-                     - 4;
++# if defined( UNICODE_SUPPORT) && defined( _MBCS)
++/* If Unicode support is enabled, and we have multi-byte characters,
++ * then do the isprint() checks by first converting to wide characters
++ * and checking those.  This avoids our having to parse multi-byte
++ * characters for ourselves.  After the wide-char replacements have been
++ * made, the wide string is converted back to the local character set.
++ */
++    wchar_t *wstring;    /* wchar_t version of raw */
++    size_t wslen;        /* length of wstring */
++    wchar_t *wostring;   /* wchar_t version of output string */
++    size_t woslen;       /* length of wostring */
++    char *newraw;        /* new raw */
++
++    /* 2012-11-06 SMS.
++     * Changed to check the value returned by mbstowcs(), and bypass the
++     * Unicode processing if it fails.  This seems to fix a problem
++     * reported in the SourceForge forum, but it's not clear that we
++     * should be doing any Unicode processing without some evidence that
++     * the name actually is Unicode.  (Check bit 11 in the flags before
++     * coming here?)
++     * http://sourceforge.net/p/infozip/bugs/40/
++     */
++
++    if (MB_CUR_MAX <= 1)
++    {
++        /* There's no point to converting multi-byte chars if there are
++         * no multi-byte chars.
++         */
++        wslen = (size_t)-1;
+     }
+-    while (*r) {
+-        if (size > 0 && s >= slim && se == NULL) {
+-            se = s;
++    else
++    {
++        /* Get Unicode wide character count (for storage allocation). */
++        wslen = mbstowcs( NULL, raw, 0);
++    }
++
++    if (wslen != (size_t)-1)
++    {
++        /* Apparently valid Unicode.  Allocate wide-char storage. */
++        wstring = (wchar_t *)malloc((wslen + 1) * sizeof(wchar_t));
++        if (wstring == NULL) {
++            strcpy( (char *)space, raw);
++            return (char *)space;
+         }
+-#ifdef QDOS
+-        if (qlflag & 2) {
+-            if (*r == '/' || *r == '.') {
++        wostring = (wchar_t *)malloc(2 * (wslen + 1) * sizeof(wchar_t));
++        if (wostring == NULL) {
++            free(wstring);
++            strcpy( (char *)space, raw);
++            return (char *)space;
++        }
++
++        /* Convert the multi-byte Unicode to wide chars. */
++        wslen = mbstowcs(wstring, raw, wslen + 1);
++
++        /* Filter the wide-character string. */
++        fnfilterw( wstring, wostring, (2 * (wslen + 1) * sizeof(wchar_t)));
++
++        /* Convert filtered wide chars back to multi-byte. */
++        woslen = wcstombs( NULL, wostring, 0);
++        if ((newraw = malloc(woslen + 1)) == NULL) {
++            free(wstring);
++            free(wostring);
++            strcpy( (char *)space, raw);
++            return (char *)space;
++        }
++        woslen = wcstombs( newraw, wostring, (woslen * MB_CUR_MAX) + 1);
++
++        if (size > 0) {
++            slim = space + size - 4;
++        }
++        r = (ZCONST uch *)newraw;
++        while (*r) {
++            if (size > 0 && s >= slim && se == NULL) {
++                se = s;
++            }
++#  ifdef QDOS
++            if (qlflag & 2) {
++                if (*r == '/' || *r == '.') {
++                    if (se != NULL && (s > (space + (size-3)))) {
++                        have_overflow = TRUE;
++                        break;
++                    }
++                    ++r;
++                    *s++ = '_';
++                    continue;
++                }
++            } else
++#  endif
++            {
+                 if (se != NULL && (s > (space + (size-3)))) {
+                     have_overflow = TRUE;
+                     break;
+                 }
+-                ++r;
+-                *s++ = '_';
+-                continue;
++                *s++ = *r++;
+             }
+-        } else
++        }
++        if (have_overflow) {
++            strcpy((char *)se, "...");
++        } else {
++            *s = '\0';
++        }
++
++        free(wstring);
++        free(wostring);
++        free(newraw);
++    }
++    else
++# endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
++    {
++        /* No Unicode support, or apparently invalid Unicode. */
++        r = (ZCONST uch *)raw;
++
++        if (size > 0) {
++            slim = space + size
++#ifdef _MBCS
++                         - (MB_CUR_MAX - 1)
++#endif
++                         - 4;
++        }
++        while (*r) {
++            if (size > 0 && s >= slim && se == NULL) {
++                se = s;
++            }
++#ifdef QDOS
++            if (qlflag & 2) {
++                if (*r == '/' || *r == '.') {
++                    if (se != NULL && (s > (space + (size-3)))) {
++                        have_overflow = TRUE;
++                        break;
++                    }
++                    ++r;
++                    *s++ = '_';
++                    continue;
++                }
++            } else
+ #endif
+ #ifdef HAVE_WORKING_ISPRINT
+-# ifndef UZ_FNFILTER_REPLACECHAR
+-    /* A convenient choice for the replacement of unprintable char codes is
+-     * the "single char wildcard", as this character is quite unlikely to
+-     * appear in filenames by itself.  The following default definition
+-     * sets the replacement char to a question mark as the most common
+-     * "single char wildcard"; this setting should be overridden in the
+-     * appropiate system-specific configuration header when needed.
+-     */
+-#   define UZ_FNFILTER_REPLACECHAR      '?'
+-# endif
+-        if (!isprint(*r)) {
++            if (!isprint(*r)) {
++                if (*r < 32) {
++                    /* ASCII control codes are escaped as "^{letter}". */
++                    if (se != NULL && (s > (space + (size-4)))) {
++                        have_overflow = TRUE;
++                        break;
++                    }
++                    *s++ = '^', *s++ = (uch)(64 + *r++);
++                } else {
++                    /* Other unprintable codes are replaced by the
++                     * placeholder character. */
++                    if (se != NULL && (s > (space + (size-3)))) {
++                        have_overflow = TRUE;
++                        break;
++                    }
++                    *s++ = UZ_FNFILTER_REPLACECHAR;
++                    INCSTR(r);
++                }
++#else /* !HAVE_WORKING_ISPRINT */
+             if (*r < 32) {
+                 /* ASCII control codes are escaped as "^{letter}". */
+                 if (se != NULL && (s > (space + (size-4)))) {
+@@ -2710,47 +2843,30 @@ char *fnfilter(raw, space, size)   /* convert name to safely printable form */
+                     break;
+                 }
+                 *s++ = '^', *s++ = (uch)(64 + *r++);
++#endif /* ?HAVE_WORKING_ISPRINT */
+             } else {
+-                /* Other unprintable codes are replaced by the
+-                 * placeholder character. */
++#ifdef _MBCS
++                unsigned i = CLEN(r);
++                if (se != NULL && (s > (space + (size-i-2)))) {
++                    have_overflow = TRUE;
++                    break;
++                }
++                for (; i > 0; i--)
++                    *s++ = *r++;
++#else
+                 if (se != NULL && (s > (space + (size-3)))) {
+                     have_overflow = TRUE;
+                     break;
+                 }
+-                *s++ = UZ_FNFILTER_REPLACECHAR;
+-                INCSTR(r);
+-            }
+-#else /* !HAVE_WORKING_ISPRINT */
+-        if (*r < 32) {
+-            /* ASCII control codes are escaped as "^{letter}". */
+-            if (se != NULL && (s > (space + (size-4)))) {
+-                have_overflow = TRUE;
+-                break;
+-            }
+-            *s++ = '^', *s++ = (uch)(64 + *r++);
+-#endif /* ?HAVE_WORKING_ISPRINT */
+-        } else {
+-#ifdef _MBCS
+-            unsigned i = CLEN(r);
+-            if (se != NULL && (s > (space + (size-i-2)))) {
+-                have_overflow = TRUE;
+-                break;
+-            }
+-            for (; i > 0; i--)
+                 *s++ = *r++;
+-#else
+-            if (se != NULL && (s > (space + (size-3)))) {
+-                have_overflow = TRUE;
+-                break;
+-            }
+-            *s++ = *r++;
+ #endif
+-         }
+-    }
+-    if (have_overflow) {
+-        strcpy((char *)se, "...");
+-    } else {
+-        *s = '\0';
++             }
++        }
++        if (have_overflow) {
++            strcpy((char *)se, "...");
++        } else {
++            *s = '\0';
++        }
+     }
+ 
+ #ifdef WINDLL
+@@ -2772,6 +2888,53 @@ char *fnfilter(raw, space, size)   /* convert name to safely printable form */
+ } /* end function fnfilter() */
+ 
+ 
++#if defined( UNICODE_SUPPORT) && defined( _MBCS)
++
++/****************************/
++/*  Function fnfilter[w]()  */  /* (Here instead of in list.c for SFX.) */
++/****************************/
++
++/* fnfilterw() - Convert wide name to safely printable form. */
++
++/* fnfilterw() - Convert wide-character name to safely printable form. */
++
++wchar_t *fnfilterw( src, dst, siz)
++    ZCONST wchar_t *src;        /* Pointer to source char (string). */
++    wchar_t *dst;               /* Pointer to destination char (string). */
++    extent siz;                 /* Not used (!). */
++{
++    wchar_t *dsx = dst;
++
++    /* Filter the wide chars. */
++    while (*src)
++    {
++        if (iswprint( *src))
++        {
++            /* Printable code.  Copy it. */
++            *dst++ = *src;
++        }
++        else
++        {
++            /* Unprintable code.  Substitute something printable for it. */
++            if (*src < 32)
++            {
++                /* Replace ASCII control code with "^{letter}". */
++                *dst++ = (wchar_t)'^';
++                *dst++ = (wchar_t)(64 + *src);
++            }
++            else
++            {
++                /* Replace other unprintable code with the placeholder. */
++                *dst++ = (wchar_t)UZ_FNFILTER_REPLACECHAR;
++            }
++        }
++        src++;
++    }
++    *dst = (wchar_t)0;  /* NUL-terminate the destination string. */
++    return dsx;
++} /* fnfilterw(). */
++
++#endif /* defined( UNICODE_SUPPORT) && defined( _MBCS) */
+ 
+ 
+ #ifdef SET_DIR_ATTRIB
+diff --git a/unzpriv.h b/unzpriv.h
+index 22d3923..e48a652 100644
+--- a/unzpriv.h
++++ b/unzpriv.h
+@@ -1212,6 +1212,7 @@
+ # ifdef UNICODE_WCHAR
+ #  if !(defined(_WIN32_WCE) || defined(POCKET_UNZIP))
+ #   include <wchar.h>
++#   include <wctype.h>
+ #  endif
+ # endif
+ # ifndef _MBCS  /* no need to include <locale.h> twice, see below */
+@@ -2410,6 +2411,12 @@ int    memflush                  OF((__GPRO__ ZCONST uch *rawbuf, ulg size));
+ char  *fnfilter                  OF((ZCONST char *raw, uch *space,
+                                      extent size));
+ 
++# if defined( UNICODE_SUPPORT) && defined( _MBCS)
++wchar_t *fnfilterw               OF((ZCONST wchar_t *src, wchar_t *dst,
++                                     extent siz));
++#endif
++
++
+ /*---------------------------------------------------------------------------
+     Decompression functions:
+   ---------------------------------------------------------------------------*/
+-- 
+2.4.3
+
diff --git a/gnu/packages/patches/unzip-alt-iconv-utf8.patch b/gnu/packages/patches/unzip-alt-iconv-utf8.patch
new file mode 100644
index 0000000000..b9e37774e2
--- /dev/null
+++ b/gnu/packages/patches/unzip-alt-iconv-utf8.patch
@@ -0,0 +1,398 @@
+From: Giovanni Scafora <giovanni.archlinux.org>
+Subject: unzip files encoded with non-latin, non-unicode file names
+Last-Update: 2015-02-11
+
+Updated 2015-02-11 by Marc Deslauriers <marc.deslauriers@canonical.com>
+to fix buffer overflow in charset_to_intern()
+
+Index: unzip-6.0/unix/unix.c
+===================================================================
+--- unzip-6.0.orig/unix/unix.c	2015-02-11 08:46:43.675324290 -0500
++++ unzip-6.0/unix/unix.c	2015-02-11 09:18:04.902081319 -0500
+@@ -30,6 +30,9 @@
+ #define UNZIP_INTERNAL
+ #include "unzip.h"
+ 
++#include <iconv.h>
++#include <langinfo.h>
++
+ #ifdef SCO_XENIX
+ #  define SYSNDIR
+ #else  /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
+@@ -1874,3 +1877,102 @@
+     }
+ }
+ #endif /* QLZIP */
++
++
++typedef struct {
++    char *local_charset;
++    char *archive_charset;
++} CHARSET_MAP;
++
++/* A mapping of local <-> archive charsets used by default to convert filenames
++ * of DOS/Windows Zip archives. Currently very basic. */
++static CHARSET_MAP dos_charset_map[] = {
++    { "ANSI_X3.4-1968", "CP850" },
++    { "ISO-8859-1", "CP850" },
++    { "CP1252", "CP850" },
++    { "UTF-8", "CP866" },
++    { "KOI8-R", "CP866" },
++    { "KOI8-U", "CP866" },
++    { "ISO-8859-5", "CP866" }
++};
++
++char OEM_CP[MAX_CP_NAME] = "";
++char ISO_CP[MAX_CP_NAME] = "";
++
++/* Try to guess the default value of OEM_CP based on the current locale.
++ * ISO_CP is left alone for now. */
++void init_conversion_charsets()
++{
++    const char *local_charset;
++    int i;
++
++    /* Make a guess only if OEM_CP not already set. */ 
++    if(*OEM_CP == '\0') {
++    	local_charset = nl_langinfo(CODESET);
++    	for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
++    		if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
++    			strncpy(OEM_CP, dos_charset_map[i].archive_charset,
++    					sizeof(OEM_CP));
++    			break;
++    		}
++    }
++}
++
++/* Convert a string from one encoding to the current locale using iconv().
++ * Be as non-intrusive as possible. If error is encountered during covertion
++ * just leave the string intact. */
++static void charset_to_intern(char *string, char *from_charset)
++{
++    iconv_t cd;
++    char *s,*d, *buf;
++    size_t slen, dlen, buflen;
++    const char *local_charset;
++
++    if(*from_charset == '\0')
++    	return;
++
++    buf = NULL;
++    local_charset = nl_langinfo(CODESET);
++
++    if((cd = iconv_open(local_charset, from_charset)) == (iconv_t)-1)
++        return;
++
++    slen = strlen(string);
++    s = string;
++
++    /*  Make sure OUTBUFSIZ + 1 never ends up smaller than FILNAMSIZ
++     *  as this function also gets called with G.outbuf in fileio.c
++     */
++    buflen = FILNAMSIZ;
++    if (OUTBUFSIZ + 1 < FILNAMSIZ)
++    {
++        buflen = OUTBUFSIZ + 1;
++    }
++
++    d = buf = malloc(buflen);
++    if(!d)
++    	goto cleanup;
++
++    bzero(buf,buflen);
++    dlen = buflen - 1;
++
++    if(iconv(cd, &s, &slen, &d, &dlen) == (size_t)-1)
++    	goto cleanup;
++    strncpy(string, buf, buflen);
++
++    cleanup:
++    free(buf);
++    iconv_close(cd);
++}
++
++/* Convert a string from OEM_CP to the current locale charset. */
++inline void oem_intern(char *string)
++{
++    charset_to_intern(string, OEM_CP);
++}
++
++/* Convert a string from ISO_CP to the current locale charset. */
++inline void iso_intern(char *string)
++{
++    charset_to_intern(string, ISO_CP);
++}
+Index: unzip-6.0/unix/unxcfg.h
+===================================================================
+--- unzip-6.0.orig/unix/unxcfg.h	2015-02-11 08:46:43.675324290 -0500
++++ unzip-6.0/unix/unxcfg.h	2015-02-11 08:46:43.671324260 -0500
+@@ -228,4 +228,30 @@
+ /* wild_dir, dirname, wildname, matchname[], dirnamelen, have_dirname, */
+ /*    and notfirstcall are used by do_wild().                          */
+ 
++
++#define MAX_CP_NAME 25 
++   
++#ifdef SETLOCALE
++#  undef SETLOCALE
++#endif
++#define SETLOCALE(category, locale) setlocale(category, locale)
++#include <locale.h>
++   
++#ifdef _ISO_INTERN
++#  undef _ISO_INTERN
++#endif
++#define _ISO_INTERN(str1) iso_intern(str1)
++
++#ifdef _OEM_INTERN
++#  undef _OEM_INTERN
++#endif
++#ifndef IZ_OEM2ISO_ARRAY
++#  define IZ_OEM2ISO_ARRAY
++#endif
++#define _OEM_INTERN(str1) oem_intern(str1)
++
++void iso_intern(char *);
++void oem_intern(char *);
++void init_conversion_charsets(void);
++   
+ #endif /* !__unxcfg_h */
+Index: unzip-6.0/unzip.c
+===================================================================
+--- unzip-6.0.orig/unzip.c	2015-02-11 08:46:43.675324290 -0500
++++ unzip-6.0/unzip.c	2015-02-11 08:46:43.675324290 -0500
+@@ -327,11 +327,21 @@
+   -2  just filenames but allow -h/-t/-z  -l  long Unix \"ls -l\" format\n\
+                                          -v  verbose, multi-page format\n";
+ 
++#ifndef UNIX
+ static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
+   -h  print header line       -t  print totals for listed files or for all\n\
+   -z  print zipfile comment   -T  print file times in sortable decimal format\
+ \n  -C  be case-insensitive   %s\
+   -x  exclude filenames that follow from listing\n";
++#else /* UNIX */
++static ZCONST char Far ZipInfoUsageLine3[] = "miscellaneous options:\n\
++  -h  print header line       -t  print totals for listed files or for all\n\
++  -z  print zipfile comment  %c-T%c print file times in sortable decimal format\
++\n %c-C%c be case-insensitive   %s\
++  -x  exclude filenames that follow from listing\n\
++  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives\n\
++  -I CHARSET  specify a character encoding for UNIX and other archives\n";
++#endif /* !UNIX */
+ #ifdef MORE
+    static ZCONST char Far ZipInfoUsageLine4[] =
+      "  -M  page output through built-in \"more\"\n";
+@@ -664,6 +674,17 @@
+   -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
+   -C  match filenames case-insensitively     -L  make (some) names \
+ lowercase\n %-42s  -V  retain VMS version numbers\n%s";
++#elif (defined UNIX)
++static ZCONST char Far UnzipUsageLine4[] = "\
++modifiers:\n\
++  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)\n\
++  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files\n\
++  -j  junk paths (do not make directories)   -aa treat ALL files as text\n\
++  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields\n\
++  -C  match filenames case-insensitively     -L  make (some) names \
++lowercase\n %-42s  -V  retain VMS version numbers\n%s\
++  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives\n\
++  -I CHARSET  specify a character encoding for UNIX and other archives\n\n";
+ #else /* !VMS */
+ static ZCONST char Far UnzipUsageLine4[] = "\
+ modifiers:\n\
+@@ -802,6 +823,10 @@
+ #endif /* UNICODE_SUPPORT */
+ 
+ 
++#ifdef UNIX
++    init_conversion_charsets();
++#endif
++
+ #if (defined(__IBMC__) && defined(__DEBUG_ALLOC__))
+     extern void DebugMalloc(void);
+ 
+@@ -1335,6 +1360,11 @@
+     argc = *pargc;
+     argv = *pargv;
+ 
++#ifdef UNIX
++    extern char OEM_CP[MAX_CP_NAME];
++    extern char ISO_CP[MAX_CP_NAME];
++#endif
++    
+     while (++argv, (--argc > 0 && *argv != NULL && **argv == '-')) {
+         s = *argv + 1;
+         while ((c = *s++) != 0) {    /* "!= 0":  prevent Turbo C warning */
+@@ -1516,6 +1546,35 @@
+                     }
+                     break;
+ #endif  /* MACOS */
++#ifdef UNIX
++    			case ('I'):
++                    if (negative) {
++                        Info(slide, 0x401, ((char *)slide,
++                          "error:  encodings can't be negated"));
++                        return(PK_PARAM);
++    				} else {
++    					if(*s) { /* Handle the -Icharset case */
++    						/* Assume that charsets can't start with a dash to spot arguments misuse */
++    						if(*s == '-') { 
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -I argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    					} else { /* -I charset */
++    						++argv;
++    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -I argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						s = *argv;
++    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    					}
++    					while(*(++s)); /* No params straight after charset name */
++    				}
++    				break;
++#endif /* ?UNIX */
+                 case ('j'):    /* junk pathnames/directory structure */
+                     if (negative)
+                         uO.jflag = FALSE, negative = 0;
+@@ -1591,6 +1650,35 @@
+                     } else
+                         ++uO.overwrite_all;
+                     break;
++#ifdef UNIX
++    			case ('O'):
++                    if (negative) {
++                        Info(slide, 0x401, ((char *)slide,
++                          "error:  encodings can't be negated"));
++                        return(PK_PARAM);
++    				} else {
++    					if(*s) { /* Handle the -Ocharset case */
++    						/* Assume that charsets can't start with a dash to spot arguments misuse */
++    						if(*s == '-') { 
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -I argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    					} else { /* -O charset */
++    						++argv;
++    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -O argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						s = *argv;
++    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    					}
++    					while(*(++s)); /* No params straight after charset name */
++    				}
++    				break;
++#endif /* ?UNIX */
+                 case ('p'):    /* pipes:  extract to stdout, no messages */
+                     if (negative) {
+                         uO.cflag = FALSE;
+Index: unzip-6.0/unzpriv.h
+===================================================================
+--- unzip-6.0.orig/unzpriv.h	2015-02-11 08:46:43.675324290 -0500
++++ unzip-6.0/unzpriv.h	2015-02-11 08:46:43.675324290 -0500
+@@ -3008,7 +3008,7 @@
+          !(((islochdr) || (isuxatt)) && \
+            ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
+         (hostnum) == FS_HPFS_ || \
+-        ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
++        ((hostnum) == FS_NTFS_ /* && (hostver) == 50 */ )) { \
+         _OEM_INTERN((string)); \
+     } else { \
+         _ISO_INTERN((string)); \
+Index: unzip-6.0/zipinfo.c
+===================================================================
+--- unzip-6.0.orig/zipinfo.c	2015-02-11 08:46:43.675324290 -0500
++++ unzip-6.0/zipinfo.c	2015-02-11 08:46:43.675324290 -0500
+@@ -457,6 +457,10 @@
+     int    tflag_slm=TRUE, tflag_2v=FALSE;
+     int    explicit_h=FALSE, explicit_t=FALSE;
+ 
++#ifdef UNIX
++    extern char OEM_CP[MAX_CP_NAME];
++    extern char ISO_CP[MAX_CP_NAME];
++#endif
+ 
+ #ifdef MACOS
+     uO.lflag = LFLAG;         /* reset default on each call */
+@@ -501,6 +505,35 @@
+                             uO.lflag = 0;
+                     }
+                     break;
++#ifdef UNIX
++    			case ('I'):
++                    if (negative) {
++                        Info(slide, 0x401, ((char *)slide,
++                          "error:  encodings can't be negated"));
++                        return(PK_PARAM);
++    				} else {
++    					if(*s) { /* Handle the -Icharset case */
++    						/* Assume that charsets can't start with a dash to spot arguments misuse */
++    						if(*s == '-') { 
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -I argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    					} else { /* -I charset */
++    						++argv;
++    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -I argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						s = *argv;
++    						strncpy(ISO_CP, s, sizeof(ISO_CP));
++    					}
++    					while(*(++s)); /* No params straight after charset name */
++    				}
++    				break;
++#endif /* ?UNIX */
+                 case 'l':      /* longer form of "ls -l" type listing */
+                     if (negative)
+                         uO.lflag = -2, negative = 0;
+@@ -521,6 +554,35 @@
+                         G.M_flag = TRUE;
+                     break;
+ #endif
++#ifdef UNIX
++    			case ('O'):
++                    if (negative) {
++                        Info(slide, 0x401, ((char *)slide,
++                          "error:  encodings can't be negated"));
++                        return(PK_PARAM);
++    				} else {
++    					if(*s) { /* Handle the -Ocharset case */
++    						/* Assume that charsets can't start with a dash to spot arguments misuse */
++    						if(*s == '-') { 
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -I argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    					} else { /* -O charset */
++    						++argv;
++    						if(!(--argc > 0 && *argv != NULL && **argv != '-')) {
++    	                        Info(slide, 0x401, ((char *)slide,
++        		                  "error:  a valid character encoding should follow the -O argument"));
++    	                        return(PK_PARAM); 
++    						}
++    						s = *argv;
++    						strncpy(OEM_CP, s, sizeof(OEM_CP));
++    					}
++    					while(*(++s)); /* No params straight after charset name */
++    				}
++    				break;
++#endif /* ?UNIX */
+                 case 's':      /* default:  shorter "ls -l" type listing */
+                     if (negative)
+                         uO.lflag = -2, negative = 0;
diff --git a/gnu/packages/patches/unzip-case-insensitive.patch b/gnu/packages/patches/unzip-case-insensitive.patch
new file mode 100644
index 0000000000..3cb68450b9
--- /dev/null
+++ b/gnu/packages/patches/unzip-case-insensitive.patch
@@ -0,0 +1,131 @@
+diff --git a/match.c b/match.c
+index 6cd656f..4e569f5 100644
+--- a/match.c
++++ b/match.c
+@@ -190,10 +190,10 @@ char *___tmp_ptr;
+ 
+ #endif
+ 
+-static int recmatch(p, s, cs)
++static int recmatch(p, s, ci)
+ ZCONST char *p;         /* sh pattern to match */
+ ZCONST char *s;         /* string to match it to */
+-int cs;                 /* flag: force case-sensitive matching */
++int ci;                 /* flag: force case-insensitive matching */
+ /* Recursively compare the sh pattern p with the string s and return 1 if
+    they match, and 0 or 2 if they don't or if there is a syntax error in the
+    pattern.  This routine recurses on itself no deeper than the number of
+@@ -214,7 +214,7 @@ int cs;                 /* flag: force case-sensitive matching */
+   if (CLEN(p) == 2) {
+     if (CLEN(s) == 2) {
+       return (*p == *s && *(p+1) == *(s+1)) ?
+-        recmatch(p + 2, s + 2, cs) : 0;
++        recmatch(p + 2, s + 2, ci) : 0;
+     } else {
+       return 0;
+     }
+@@ -230,9 +230,9 @@ int cs;                 /* flag: force case-sensitive matching */
+   /* '?' (or '%' or '#') matches any character (but not an empty string) */
+   if (c == WILDCHR_SINGLE) {
+     if (wild_stop_at_dir)
+-      return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), cs) : 0;
++      return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), ci) : 0;
+     else
+-      return *s ? recmatch(p, s + CLEN(s), cs) : 0;
++      return *s ? recmatch(p, s + CLEN(s), ci) : 0;
+   }
+ 
+   /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+@@ -253,14 +253,14 @@ int cs;                 /* flag: force case-sensitive matching */
+ # endif /* ?AMIGA */
+         /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+         for (; *s && *s != DIRSEP_CHR; INCSTR(s))
+-          if ((c = recmatch(p, s, cs)) != 0)
++          if ((c = recmatch(p, s, ci)) != 0)
+             return c;
+         /* end of pattern: matched if at end of string, else continue */
+         if (*p == 0)
+           return (*s == 0);
+         /* continue to match if at DIRSEP_CHR in pattern, else give up */
+         return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
+-               ? recmatch(p, s, cs) : 2;
++               ? recmatch(p, s, ci) : 2;
+       }
+       /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+       p++;        /* move p past the second WILDCHR_MULTI */
+@@ -308,17 +308,17 @@ int cs;                 /* flag: force case-sensitive matching */
+          */
+         if (q != srest)
+           return 0;
+-        return ((cs ? strcmp(p, q) : namecmp(p, q)) == 0);
++        return ((!ci ? strcmp(p, q) : namecmp(p, q)) == 0);
+       }
+ #else /* !_MBCS */
+-        return ((cs ? strcmp(p, srest) : namecmp(p, srest)) == 0);
++        return ((!ci ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+ #endif /* ?_MBCS */
+     }
+     else
+     {
+       /* pattern contains more wildcards, continue with recursion... */
+       for (; *s; INCSTR(s))
+-        if ((c = recmatch(p, s, cs)) != 0)
++        if ((c = recmatch(p, s, ci)) != 0)
+           return c;
+       return 2;           /* 2 means give up--shmatch will return false */
+     }
+@@ -353,17 +353,17 @@ int cs;                 /* flag: force case-sensitive matching */
+         c = *(p-1);
+       else
+       {
+-        uch cc = (cs ? (uch)*s : case_map((uch)*s));
++        uch cc = (!ci ? (uch)*s : to_up((uch)*s));
+         uch uc = (uch) c;
+         if (*(p+1) != '-')
+           for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
+             /* compare range */
+-            if ((cs ? uc : case_map(uc)) == cc)
+-              return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs);
++            if ((!ci ? uc : to_up(uc)) == cc)
++              return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), ci);
+         c = e = 0;                      /* clear range, escape flags */
+       }
+     }
+-    return r ? recmatch(q + CLEN(q), s + CLEN(s), cs) : 0;
++    return r ? recmatch(q + CLEN(q), s + CLEN(s), ci) : 0;
+                                         /* bracket match failed */
+   }
+ #endif /* !VMS */
+@@ -382,18 +382,18 @@ int cs;                 /* flag: force case-sensitive matching */
+   {
+     /* Match "...]" with "]".  Continue after "]" in both. */
+     if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+-      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
++      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
+ 
+     /* Else, look for a reduced match in s, until "]" in or end of s. */
+     for (; *s && (*s != ']'); INCSTR(s))
+       if (*s == '.')
+         /* If reduced match, then continue after "..." in p, "." in s. */
+-        if ((c = recmatch( (p+ CLEN( p)), s, cs)) != 0)
++        if ((c = recmatch( (p+ CLEN( p)), s, ci)) != 0)
+           return (int)c;
+ 
+     /* Match "...]" with "]".  Continue after "]" in both. */
+     if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+-      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
++      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), ci);
+ 
+     /* No reduced match.  Quit. */
+     return 2;
+@@ -402,8 +402,8 @@ int cs;                 /* flag: force case-sensitive matching */
+ #endif /* def VMS */
+ 
+   /* Just a character--compare it */
+-  return (cs ? c == *s : case_map((uch)c) == case_map((uch)*s)) ?
+-          recmatch(p, s + CLEN(s), cs) : 0;
++  return (!ci ? c == *s : to_up((uch)c) == to_up((uch)*s)) ?
++          recmatch(p, s + CLEN(s), ci) : 0;
+ }
+ 
+ 
diff --git a/gnu/packages/patches/unzip-close.patch b/gnu/packages/patches/unzip-close.patch
new file mode 100644
index 0000000000..9a238a9006
--- /dev/null
+++ b/gnu/packages/patches/unzip-close.patch
@@ -0,0 +1,176 @@
+diff -up unzip60/extract.c.close unzip60/extract.c
+--- unzip60/extract.c.close	2009-03-14 02:32:52.000000000 +0100
++++ unzip60/extract.c	2009-11-19 08:17:23.481263496 +0100
+@@ -1924,24 +1924,21 @@ static int extract_or_test_member(__G)  
+ 
+ #ifdef VMS                  /* VMS:  required even for stdout! (final flush) */
+     if (!uO.tflag)           /* don't close NULL file */
+-        close_outfile(__G);
++        error = close_outfile(__G);
+ #else
+ #ifdef DLL
+     if (!uO.tflag && (!uO.cflag || G.redirect_data)) {
+         if (G.redirect_data)
+             FINISH_REDIRECT();
+         else
+-            close_outfile(__G);
++            error = close_outfile(__G);
+     }
+ #else
+     if (!uO.tflag && !uO.cflag)   /* don't close NULL file or stdout */
+-        close_outfile(__G);
++        error = close_outfile(__G);
+ #endif
+ #endif /* VMS */
+ 
+-            /* GRR: CONVERT close_outfile() TO NON-VOID:  CHECK FOR ERRORS! */
+-
+-
+     if (G.disk_full) {            /* set by flush() */
+         if (G.disk_full > 1) {
+ #if (defined(DELETE_IF_FULL) && defined(HAVE_UNLINK))
+diff -up unzip60/unix/unix.c.close unzip60/unix/unix.c
+--- unzip60/unix/unix.c.close	2009-01-24 00:31:26.000000000 +0100
++++ unzip60/unix/unix.c	2009-11-19 08:33:25.568389171 +0100
+@@ -1096,10 +1096,41 @@ static int get_extattribs(__G__ pzt, z_u
+ #ifndef MTS
+ 
+ /****************************/
++/* Function CloseError()    */
++/***************************/
++
++int CloseError(__G)
++    __GDEF
++{
++    int errval = PK_OK;
++    
++    if (fclose(G.outfile) < 0) {
++          switch (errno) {
++                case ENOSPC:
++                    /* Do we need this on fileio.c? */
++                    Info(slide, 0x4a1, ((char *)slide, "%s: write error (disk full?).   Continue? (y/n/^C) ",
++                          FnFilter1(G.filename)));
++                    fgets(G.answerbuf, 9, stdin);
++                    if (*G.answerbuf == 'y')     /* stop writing to this file */
++                        G.disk_full = 1;         /* pass to next */
++                    else
++                        G.disk_full = 2;         /* no: exit program */
++          
++                    errval = PK_DISK;
++                    break;
++
++                default:
++                    errval = PK_WARN;
++          }
++     }
++     return errval;
++} /* End of CloseError() */
++
++/****************************/
+ /* Function close_outfile() */
+ /****************************/
+ 
+-void close_outfile(__G)    /* GRR: change to return PK-style warning level */
++int close_outfile(__G) 
+     __GDEF
+ {
+     union {
+@@ -1108,6 +1139,7 @@ void close_outfile(__G)    /* GRR: chang
+     } zt;
+     ulg z_uidgid[2];
+     int have_uidgid_flg;
++    int errval = PK_OK;
+ 
+     have_uidgid_flg = get_extattribs(__G__ &(zt.t3), z_uidgid);
+ 
+@@ -1141,16 +1173,16 @@ void close_outfile(__G)    /* GRR: chang
+             Info(slide, 0x201, ((char *)slide,
+               "warning:  symbolic link (%s) failed: mem alloc overflow\n",
+               FnFilter1(G.filename)));
+-            fclose(G.outfile);
+-            return;
++            errval = CloseError(G.outfile, G.filename);
++            return errval ? errval : PK_WARN;
+         }
+ 
+         if ((slnk_entry = (slinkentry *)malloc(slnk_entrysize)) == NULL) {
+             Info(slide, 0x201, ((char *)slide,
+               "warning:  symbolic link (%s) failed: no mem\n",
+               FnFilter1(G.filename)));
+-            fclose(G.outfile);
+-            return;
++            errval = CloseError(G.outfile, G.filename);
++            return errval ? errval : PK_WARN;
+         }
+         slnk_entry->next = NULL;
+         slnk_entry->targetlen = ucsize;
+@@ -1174,10 +1206,10 @@ void close_outfile(__G)    /* GRR: chang
+               "warning:  symbolic link (%s) failed\n",
+               FnFilter1(G.filename)));
+             free(slnk_entry);
+-            fclose(G.outfile);
+-            return;
++            errval = CloseError(G.outfile, G.filename);
++            return errval ? errval : PK_WARN;
+         }
+-        fclose(G.outfile);                  /* close "link" file for good... */
++        errval = CloseError(G.outfile, G.filename); /* close "link" file for good... */
+         slnk_entry->target[ucsize] = '\0';
+         if (QCOND2)
+             Info(slide, 0, ((char *)slide, "-> %s ",
+@@ -1188,7 +1220,7 @@ void close_outfile(__G)    /* GRR: chang
+         else
+             G.slink_head = slnk_entry;
+         G.slink_last = slnk_entry;
+-        return;
++        return errval;
+     }
+ #endif /* SYMLINKS */
+ 
+@@ -1201,7 +1233,7 @@ void close_outfile(__G)    /* GRR: chang
+ #endif
+ 
+ #if (defined(NO_FCHOWN))
+-    fclose(G.outfile);
++    errval = CloseError(G.outfile, G.filename);
+ #endif
+ 
+     /* if -X option was specified and we have UID/GID info, restore it */
+@@ -1227,7 +1259,7 @@ void close_outfile(__G)    /* GRR: chang
+     }
+ 
+ #if (!defined(NO_FCHOWN) && defined(NO_FCHMOD))
+-    fclose(G.outfile);
++    errval = CloseError(G.outfile, G.filename);
+ #endif
+ 
+ #if (!defined(NO_FCHOWN) && !defined(NO_FCHMOD))
+@@ -1239,7 +1271,7 @@ void close_outfile(__G)    /* GRR: chang
+     if (fchmod(fileno(G.outfile), filtattr(__G__ G.pInfo->file_attr)))
+         perror("fchmod (file attributes) error");
+ 
+-    fclose(G.outfile);
++    errval = CloseError(G.outfile, G.filename);
+ #endif /* !NO_FCHOWN && !NO_FCHMOD */
+ 
+     /* skip restoring time stamps on user's request */
+@@ -1267,6 +1299,7 @@ void close_outfile(__G)    /* GRR: chang
+ #endif
+ #endif /* NO_FCHOWN || NO_FCHMOD */
+ 
++    return errval;
+ } /* end function close_outfile() */
+ 
+ #endif /* !MTS */
+diff -up unzip60/unzpriv.h.close unzip60/unzpriv.h
+--- unzip60/unzpriv.h.close	2009-04-20 01:59:26.000000000 +0200
++++ unzip60/unzpriv.h	2009-11-19 08:19:08.610388618 +0100
+@@ -2604,7 +2604,7 @@ char    *GetLoadPath     OF((__GPRO));  
+    int   SetFileSize     OF((FILE *file, zusz_t filesize));         /* local */
+ #endif
+ #ifndef MTS /* macro in MTS */
+-   void  close_outfile   OF((__GPRO));                              /* local */
++   int  close_outfile   OF((__GPRO));                              /* local */
+ #endif
+ #ifdef SET_SYMLINK_ATTRIBS
+    int  set_symlnk_attribs  OF((__GPRO__ slinkentry *slnk_entry));  /* local */
diff --git a/gnu/packages/patches/unzip-exec-shield.patch b/gnu/packages/patches/unzip-exec-shield.patch
new file mode 100644
index 0000000000..74500aa5d4
--- /dev/null
+++ b/gnu/packages/patches/unzip-exec-shield.patch
@@ -0,0 +1,10 @@
+diff -up unzip60/crc_i386.S.exec-shield unzip60/crc_i386.S
+--- unzip60/crc_i386.S.exec-shield	2007-01-07 06:02:58.000000000 +0100
++++ unzip60/crc_i386.S	2009-11-18 11:16:39.630389312 +0100
+@@ -302,3 +302,6 @@ _crc32:                         /* ulg c
+ #endif /* i386 || _i386 || _I386 || __i386 */
+ 
+ #endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
++
++.section .note.GNU-stack, "", @progbits
++.previous
diff --git a/gnu/packages/patches/unzip-fix-recmatch.patch b/gnu/packages/patches/unzip-fix-recmatch.patch
new file mode 100644
index 0000000000..2a8583c8ca
--- /dev/null
+++ b/gnu/packages/patches/unzip-fix-recmatch.patch
@@ -0,0 +1,477 @@
+diff -up unzip60/match.c.recmatch unzip60/match.c
+--- unzip60/match.c.recmatch	2005-08-14 13:00:36.000000000 -0400
++++ unzip60/match.c	2013-05-28 10:29:57.949077543 -0400
+@@ -27,16 +27,14 @@
+ 
+   ---------------------------------------------------------------------------
+ 
+-  Copyright on recmatch() from Zip's util.c (although recmatch() was almost
+-  certainly written by Mark Adler...ask me how I can tell :-) ):
++  Copyright on recmatch() from Zip's util.c
++	 Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
+ 
+-     Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
+-     Kai Uwe Rommel and Igor Mandrichenko.
++	 See the accompanying file LICENSE, version 2004-May-22 or later
++	 for terms of use.
++	 If, for some reason, both of these files are missing, the Info-ZIP license
++	 also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html  
+ 
+-     Permission is granted to any individual or institution to use, copy,
+-     or redistribute this software so long as all of the original files are
+-     included unmodified, that it is not sold for profit, and that this copy-
+-     right notice is retained.
+ 
+   ---------------------------------------------------------------------------
+ 
+@@ -53,7 +51,7 @@
+ 
+   A set is composed of characters or ranges; a range looks like ``character
+   hyphen character'' (as in 0-9 or A-Z).  [0-9a-zA-Z_] is the minimal set of
+-  characters allowed in the [..] pattern construct.  Other characters are
++  characters ALlowed in the [..] pattern construct.  Other characters are
+   allowed (i.e., 8-bit characters) if your system will support them.
+ 
+   To suppress the special syntactic significance of any of ``[]*?!^-\'', in-
+@@ -101,8 +99,32 @@
+ #  define WILDCHAR   '?'
+ #  define BEG_RANGE  '['
+ #  define END_RANGE  ']'
++#  define WILDCHR_SINGLE '?'
++#  define DIRSEP_CHR '/'
++#  define WILDCHR_MULTI '*'
+ #endif
+ 
++#ifdef WILD_STOP_AT_DIR
++   int wild_stop_at_dir = 1; /* default wildcards do not include / in matches */
++#else
++   int wild_stop_at_dir = 0; /* default wildcards do include / in matches */
++#endif
++
++
++
++/*
++ * case mapping functions. case_map is used to ignore case in comparisons,
++ * to_up is used to force upper case even on Unix (for dosify option).
++ */
++#ifdef USE_CASE_MAP
++#  define case_map(c) upper[(c) & 0xff]
++#  define to_up(c)    upper[(c) & 0xff]
++#else
++#  define case_map(c) (c)
++#  define to_up(c)    ((c) >= 'a' && (c) <= 'z' ? (c)-'a'+'A' : (c))
++#endif /* USE_CASE_MAP */
++
++
+ #if 0                /* GRR:  add this to unzip.h someday... */
+ #if !(defined(MSDOS) && defined(DOSWILD))
+ #ifdef WILD_STOP_AT_DIR
+@@ -114,8 +136,8 @@ int recmatch OF((ZCONST uch *pattern, ZC
+                  int ignore_case __WDLPRO));
+ #endif
+ #endif /* 0 */
+-static int recmatch OF((ZCONST uch *pattern, ZCONST uch *string,
+-                        int ignore_case __WDLPRO));
++static int recmatch OF((ZCONST char *, ZCONST char *, 
++                        int));
+ static char *isshexp OF((ZCONST char *p));
+ static int namecmp OF((ZCONST char *s1, ZCONST char *s2));
+ 
+@@ -154,192 +176,240 @@ int match(string, pattern, ignore_case _
+             }
+             dospattern[j-1] = '\0';                    /* nuke the end "." */
+         }
+-        j = recmatch((uch *)dospattern, (uch *)string, ignore_case __WDL);
++        j = recmatch(dospattern, string, ignore_case);
+         free(dospattern);
+         return j == 1;
+     } else
+ #endif /* MSDOS && DOSWILD */
+-    return recmatch((uch *)pattern, (uch *)string, ignore_case __WDL) == 1;
++    return recmatch(pattern, string, ignore_case) == 1;
+ }
+ 
++#ifdef _MBCS
++
++char *___tmp_ptr;
+ 
++#endif
+ 
+-static int recmatch(p, s, ic __WDL)
+-    ZCONST uch *p;        /* sh pattern to match */
+-    ZCONST uch *s;        /* string to which to match it */
+-    int ic;               /* true for case insensitivity */
+-    __WDLDEF              /* directory sepchar for WildStopAtDir mode, or 0 */
++static int recmatch(p, s, cs)
++ZCONST char *p;         /* sh pattern to match */
++ZCONST char *s;         /* string to match it to */
++int cs;                 /* flag: force case-sensitive matching */
+ /* Recursively compare the sh pattern p with the string s and return 1 if
+- * they match, and 0 or 2 if they don't or if there is a syntax error in the
+- * pattern.  This routine recurses on itself no more deeply than the number
+- * of characters in the pattern. */
++   they match, and 0 or 2 if they don't or if there is a syntax error in the
++   pattern.  This routine recurses on itself no deeper than the number of
++   characters in the pattern. */
+ {
+-    unsigned int c;       /* pattern char or start of range in [-] loop */
++  int c;                /* pattern char or start of range in [-] loop */
++  /* Get first character, the pattern for new recmatch calls follows */
++ /* borrowed from Zip's global.c */
++ int no_wild = 0; 
++ int allow_regex=1;
++  /* This fix provided by akt@m5.dion.ne.jp for Japanese.
++     See 21 July 2006 mail.
++     It only applies when p is pointing to a doublebyte character and
++     things like / and wildcards are not doublebyte.  This probably
++     should not be needed. */
+ 
+-    /* Get first character, the pattern for new recmatch calls follows */
+-    c = *p; INCSTR(p);
++#ifdef _MBCS
++  if (CLEN(p) == 2) {
++    if (CLEN(s) == 2) {
++      return (*p == *s && *(p+1) == *(s+1)) ?
++        recmatch(p + 2, s + 2, cs) : 0;
++    } else {
++      return 0;
++    }
++  }
++#endif /* ?_MBCS */
+ 
+-    /* If that was the end of the pattern, match if string empty too */
+-    if (c == 0)
+-        return *s == 0;
++  c = *POSTINCSTR(p);
+ 
+-    /* '?' (or '%') matches any character (but not an empty string). */
+-    if (c == WILDCHAR)
+-#ifdef WILD_STOP_AT_DIR
+-        /* If uO.W_flag is non-zero, it won't match '/' */
+-        return (*s && (!sepc || *s != (uch)sepc))
+-               ? recmatch(p, s + CLEN(s), ic, sepc) : 0;
+-#else
+-        return *s ? recmatch(p, s + CLEN(s), ic) : 0;
+-#endif
++  /* If that was the end of the pattern, match if string empty too */
++  if (c == 0)
++    return *s == 0;
++
++  /* '?' (or '%' or '#') matches any character (but not an empty string) */
++  if (c == WILDCHR_SINGLE) {
++    if (wild_stop_at_dir)
++      return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), cs) : 0;
++    else
++      return *s ? recmatch(p, s + CLEN(s), cs) : 0;
++  }
+ 
+-    /* '*' matches any number of characters, including zero */
++  /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+ #ifdef AMIGA
+-    if (c == '#' && *p == '?')     /* "#?" is Amiga-ese for "*" */
+-        c = '*', p++;
++  if (!no_wild && c == '#' && *p == '?')            /* "#?" is Amiga-ese for "*" */
++    c = WILDCHR_MULTI, p++;
+ #endif /* AMIGA */
+-    if (c == '*') {
+-#ifdef WILD_STOP_AT_DIR
+-        if (sepc) {
+-          /* check for single "*" or double "**" */
+-#  ifdef AMIGA
+-          if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+-            c = '*', p++;
+-          if (c != '*') {
+-#  else /* !AMIGA */
+-          if (*p != '*') {
+-#  endif /* ?AMIGA */
+-            /* single "*": this doesn't match the dirsep character */
+-            for (; *s && *s != (uch)sepc; INCSTR(s))
+-                if ((c = recmatch(p, s, ic, sepc)) != 0)
+-                    return (int)c;
+-            /* end of pattern: matched if at end of string, else continue */
+-            if (*p == '\0')
+-                return (*s == 0);
+-            /* continue to match if at sepc in pattern, else give up */
+-            return (*p == (uch)sepc || (*p == '\\' && p[1] == (uch)sepc))
+-                   ? recmatch(p, s, ic, sepc) : 2;
+-          }
+-          /* "**": this matches slashes */
+-          ++p;        /* move p behind the second '*' */
+-          /* and continue with the non-W_flag code variant */
+-        }
+-#endif /* WILD_STOP_AT_DIR */
++  if (!no_wild && c == WILDCHR_MULTI)
++  {
++    if (wild_stop_at_dir) {
++      /* Check for an immediately following WILDCHR_MULTI */
++# ifdef AMIGA
++      if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
++        c = WILDCHR_MULTI, p++;
++      if (c != WILDCHR_MULTI) {
++# else /* !AMIGA */
++      if (*p != WILDCHR_MULTI) {
++# endif /* ?AMIGA */
++        /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
++        for (; *s && *s != DIRSEP_CHR; INCSTR(s))
++          if ((c = recmatch(p, s, cs)) != 0)
++            return c;
++        /* end of pattern: matched if at end of string, else continue */
+         if (*p == 0)
+-            return 1;
+-        if (isshexp((ZCONST char *)p) == NULL) {
+-            /* Optimization for rest of pattern being a literal string:
+-             * If there are no other shell expression chars in the rest
+-             * of the pattern behind the multi-char wildcard, then just
+-             * compare the literal string tail.
+-             */
+-            ZCONST uch *srest;
+-
+-            srest = s + (strlen((ZCONST char *)s) - strlen((ZCONST char *)p));
+-            if (srest - s < 0)
+-                /* remaining literal string from pattern is longer than rest
+-                 * of test string, there can't be a match
+-                 */
+-                return 0;
+-            else
+-              /* compare the remaining literal pattern string with the last
+-               * bytes of the test string to check for a match
+-               */
++          return (*s == 0);
++        /* continue to match if at DIRSEP_CHR in pattern, else give up */
++        return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
++               ? recmatch(p, s, cs) : 2;
++      }
++      /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
++      p++;        /* move p past the second WILDCHR_MULTI */
++      /* continue with the normal non-WILD_STOP_AT_DIR code */
++    } /* wild_stop_at_dir */
++
++    /* Not wild_stop_at_dir */
++    if (*p == 0)
++      return 1;
++    if (!isshexp((char *)p))
++    {
++      /* optimization for rest of pattern being a literal string */
++
++      /* optimization to handle patterns like *.txt */
++      /* if the first char in the pattern is '*' and there */
++      /* are no other shell expression chars, i.e. a literal string */
++      /* then just compare the literal string at the end */
++
++      ZCONST char *srest;
++
++      srest = s + (strlen(s) - strlen(p));
++      if (srest - s < 0)
++        /* remaining literal string from pattern is longer than rest of
++           test string, there can't be a match
++         */
++        return 0;
++      else
++        /* compare the remaining literal pattern string with the last bytes
++           of the test string to check for a match */
+ #ifdef _MBCS
+-            {
+-                ZCONST uch *q = s;
++      {
++        ZCONST char *q = s;
+ 
+-                /* MBCS-aware code must not scan backwards into a string from
+-                 * the end.
+-                 * So, we have to move forward by character from our well-known
+-                 * character position s in the test string until we have
+-                 * advanced to the srest position.
+-                 */
+-                while (q < srest)
+-                  INCSTR(q);
+-                /* In case the byte *srest is a trailing byte of a multibyte
+-                 * character in the test string s, we have actually advanced
+-                 * past the position (srest).
+-                 * For this case, the match has failed!
+-                 */
+-                if (q != srest)
+-                    return 0;
+-                return ((ic
+-                         ? namecmp((ZCONST char *)p, (ZCONST char *)q)
+-                         : strcmp((ZCONST char *)p, (ZCONST char *)q)
+-                        ) == 0);
+-            }
++        /* MBCS-aware code must not scan backwards into a string from
++         * the end.
++         * So, we have to move forward by character from our well-known
++         * character position s in the test string until we have advanced
++         * to the srest position.
++         */
++        while (q < srest)
++          INCSTR(q);
++        /* In case the byte *srest is a trailing byte of a multibyte
++         * character, we have actually advanced past the position (srest).
++         * For this case, the match has failed!
++         */
++        if (q != srest)
++          return 0;
++        return ((cs ? strcmp(p, q) : namecmp(p, q)) == 0);
++      }
+ #else /* !_MBCS */
+-                return ((ic
+-                         ? namecmp((ZCONST char *)p, (ZCONST char *)srest)
+-                         : strcmp((ZCONST char *)p, (ZCONST char *)srest)
+-                        ) == 0);
++        return ((cs ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+ #endif /* ?_MBCS */
+-        } else {
+-            /* pattern contains more wildcards, continue with recursion... */
+-            for (; *s; INCSTR(s))
+-                if ((c = recmatch(p, s, ic __WDL)) != 0)
+-                    return (int)c;
+-            return 2;  /* 2 means give up--match will return false */
+-        }
+     }
+-
+-    /* Parse and process the list of characters and ranges in brackets */
+-    if (c == BEG_RANGE) {
+-        int e;          /* flag true if next char to be taken literally */
+-        ZCONST uch *q;  /* pointer to end of [-] group */
+-        int r;          /* flag true to match anything but the range */
+-
+-        if (*s == 0)                            /* need a character to match */
+-            return 0;
+-        p += (r = (*p == '!' || *p == '^'));    /* see if reverse */
+-        for (q = p, e = 0; *q; INCSTR(q))       /* find closing bracket */
+-            if (e)
+-                e = 0;
+-            else
+-                if (*q == '\\')      /* GRR:  change to ^ for MS-DOS, OS/2? */
+-                    e = 1;
+-                else if (*q == END_RANGE)
+-                    break;
+-        if (*q != END_RANGE)         /* nothing matches if bad syntax */
+-            return 0;
+-        for (c = 0, e = (*p == '-'); p < q; INCSTR(p)) {
+-            /* go through the list */
+-            if (!e && *p == '\\')               /* set escape flag if \ */
+-                e = 1;
+-            else if (!e && *p == '-')           /* set start of range if - */
+-                c = *(p-1);
+-            else {
+-                unsigned int cc = Case(*s);
+-
+-                if (*(p+1) != '-')
+-                    for (c = c ? c : *p; c <= *p; c++)  /* compare range */
+-                        if ((unsigned)Case(c) == cc) /* typecast for MSC bug */
+-                            return r ? 0 : recmatch(q + 1, s + 1, ic __WDL);
+-                c = e = 0;   /* clear range, escape flags */
+-            }
+-        }
+-        return r ? recmatch(q + CLEN(q), s + CLEN(s), ic __WDL) : 0;
+-                                        /* bracket match failed */
++    else
++    {
++      /* pattern contains more wildcards, continue with recursion... */
++      for (; *s; INCSTR(s))
++        if ((c = recmatch(p, s, cs)) != 0)
++          return c;
++      return 2;           /* 2 means give up--shmatch will return false */
+     }
++  }
+ 
+-    /* if escape ('\\'), just compare next character */
+-    if (c == '\\' && (c = *p++) == 0)     /* if \ at end, then syntax error */
+-        return 0;
++#ifndef VMS             /* No bracket matching in VMS */
++  /* Parse and process the list of characters and ranges in brackets */
++  if (!no_wild && allow_regex && c == '[')
++  {
++    int e;              /* flag true if next char to be taken literally */
++    ZCONST char *q;     /* pointer to end of [-] group */
++    int r;              /* flag true to match anything but the range */
++
++    if (*s == 0)                        /* need a character to match */
++      return 0;
++    p += (r = (*p == '!' || *p == '^')); /* see if reverse */
++    for (q = p, e = 0; *q; q++)         /* find closing bracket */
++      if (e)
++        e = 0;
++      else
++        if (*q == '\\')
++          e = 1;
++        else if (*q == ']')
++          break;
++    if (*q != ']')                      /* nothing matches if bad syntax */
++      return 0;
++    for (c = 0, e = *p == '-'; p < q; p++)      /* go through the list */
++    {
++      if (e == 0 && *p == '\\')         /* set escape flag if \ */
++        e = 1;
++      else if (e == 0 && *p == '-')     /* set start of range if - */
++        c = *(p-1);
++      else
++      {
++        uch cc = (cs ? (uch)*s : case_map((uch)*s));
++        uch uc = (uch) c;
++        if (*(p+1) != '-')
++          for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
++            /* compare range */
++            if ((cs ? uc : case_map(uc)) == cc)
++              return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs);
++        c = e = 0;                      /* clear range, escape flags */
++      }
++    }
++    return r ? recmatch(q + CLEN(q), s + CLEN(s), cs) : 0;
++                                        /* bracket match failed */
++  }
++#endif /* !VMS */
+ 
+-    /* just a character--compare it */
+-#ifdef QDOS
+-    return QMatch(Case((uch)c), Case(*s)) ?
+-           recmatch(p, s + CLEN(s), ic __WDL) : 0;
+-#else
+-    return Case((uch)c) == Case(*s) ?
+-           recmatch(p, s + CLEN(s), ic __WDL) : 0;
+-#endif
++  /* If escape ('\'), just compare next character */
++  if (!no_wild && c == '\\')
++    if ((c = *p++) == '\0')             /* if \ at end, then syntax error */
++      return 0;
++
++#ifdef VMS
++  /* 2005-11-06 SMS.
++     Handle "..." wildcard in p with "." or "]" in s.
++  */
++  if ((c == '.') && (*p == '.') && (*(p+ CLEN( p)) == '.') &&
++   ((*s == '.') || (*s == ']')))
++  {
++    /* Match "...]" with "]".  Continue after "]" in both. */
++    if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
++      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
++
++    /* Else, look for a reduced match in s, until "]" in or end of s. */
++    for (; *s && (*s != ']'); INCSTR(s))
++      if (*s == '.')
++        /* If reduced match, then continue after "..." in p, "." in s. */
++        if ((c = recmatch( (p+ CLEN( p)), s, cs)) != 0)
++          return (int)c;
++
++    /* Match "...]" with "]".  Continue after "]" in both. */
++    if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
++      return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
++
++    /* No reduced match.  Quit. */
++    return 2;
++  }
++
++#endif /* def VMS */
++
++  /* Just a character--compare it */
++  return (cs ? c == *s : case_map((uch)c) == case_map((uch)*s)) ?
++          recmatch(p, s + CLEN(s), cs) : 0;
++}
+ 
+-} /* end function recmatch() */
+ 
+ 
+ 
++/*************************************************************************************************/
+ static char *isshexp(p)
+ ZCONST char *p;
+ /* If p is a sh expression, a pointer to the first special character is
diff --git a/gnu/packages/patches/unzip-manpage-fix.patch b/gnu/packages/patches/unzip-manpage-fix.patch
new file mode 100644
index 0000000000..ec06516bbb
--- /dev/null
+++ b/gnu/packages/patches/unzip-manpage-fix.patch
@@ -0,0 +1,11 @@
+--- unzip60/man/unzip.1	2011-01-11 11:59:59.000000000 +0000
++++ unzip60/man/unzip_new	2011-02-05 18:45:55.000000000 +0000
+@@ -424,7 +424,7 @@
+ .\" Amiga support possible eventually, but not yet
+ [MS-DOS, OS/2, NT] restore the volume label if the extraction medium is
+ removable (e.g., a diskette).  Doubling the option (\fB\-$$\fP) allows fixed
+-media (hard disks) to be labelled as well.  By default, volume labels are
++media (hard disks) to be labeled as well.  By default, volume labels are
+ ignored.
+ .IP \fB\-/\fP\ \fIextensions\fP
+ [Acorn only] overrides the extension list supplied by Unzip$Ext environment
diff --git a/gnu/packages/patches/unzip-overflow.patch b/gnu/packages/patches/unzip-overflow.patch
new file mode 100644
index 0000000000..228c28377f
--- /dev/null
+++ b/gnu/packages/patches/unzip-overflow.patch
@@ -0,0 +1,25 @@
+diff --git a/extract.c b/extract.c
+index a0a4929..9ef80b3 100644
+--- a/extract.c
++++ b/extract.c
+@@ -2214,6 +2214,7 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
+     ulg eb_ucsize;
+     uch *eb_ucptr;
+     int r;
++    ush method;
+ 
+     if (compr_offset < 4)                /* field is not compressed: */
+         return PK_OK;                    /* do nothing and signal OK */
+@@ -2223,6 +2224,12 @@ static int test_compr_eb(__G__ eb, eb_size, compr_offset, test_uc_ebdata)
+          eb_size <= (compr_offset + EB_CMPRHEADLEN)))
+         return IZ_EF_TRUNC;               /* no compressed data! */
+ 
++    method = makeword(eb + (EB_HEADSIZE + compr_offset));
++    if ((method == STORED) && (eb_size != compr_offset + EB_CMPRHEADLEN + eb_ucsize))
++        return PK_ERR;            /* compressed & uncompressed
++                                   * should match in STORED
++                                   * method */
++
+     if (
+ #ifdef INT_16BIT
+         (((ulg)(extent)eb_ucsize) != eb_ucsize) ||
diff --git a/gnu/packages/patches/unzip-timestamp.patch b/gnu/packages/patches/unzip-timestamp.patch
new file mode 100644
index 0000000000..2aa9424eb8
--- /dev/null
+++ b/gnu/packages/patches/unzip-timestamp.patch
@@ -0,0 +1,41 @@
+From: "Steven M. Schweda" <sms@antinode.info>
+Subject: Do not ignore extra fields containing Unix Timestamps
+Bug-Debian: https://bugs.debian.org/842993
+X-Debian-version: 6.0-21
+
+--- a/process.c
++++ b/process.c
+@@ -2914,10 +2914,13 @@
+             break;
+ 
+           case EF_IZUNIX2:
+-            if (have_new_type_eb == 0) {
+-                flags &= ~0x0ff;        /* ignore any previous IZUNIX field */
++            if (have_new_type_eb == 0) {        /* (< 1) */
+                 have_new_type_eb = 1;
+             }
++            if (have_new_type_eb <= 1) {
++                /* Ignore any prior (EF_IZUNIX/EF_PKUNIX) UID/GID. */
++                flags &= 0x0ff;
++            }
+ #ifdef IZ_HAVE_UXUIDGID
+             if (have_new_type_eb > 1)
+                 break;          /* IZUNIX3 overrides IZUNIX2 e.f. block ! */
+@@ -2933,6 +2936,8 @@
+             /* new 3rd generation Unix ef */
+             have_new_type_eb = 2;
+ 
++            /* Ignore any prior EF_IZUNIX/EF_PKUNIX/EF_IZUNIX2 UID/GID. */
++            flags &= 0x0ff;
+         /*
+           Version       1 byte      version of this extra field, currently 1
+           UIDSize       1 byte      Size of UID field
+@@ -2953,8 +2958,6 @@
+                 uid_size = *((EB_HEADSIZE + 1) + ef_buf);
+                 gid_size = *((EB_HEADSIZE + uid_size + 2) + ef_buf);
+ 
+-                flags &= ~0x0ff;      /* ignore any previous UNIX field */
+-
+                 if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
+                                     uid_size, &z_uidgid[0])
+                     &&
diff --git a/gnu/packages/patches/unzip-valgrind.patch b/gnu/packages/patches/unzip-valgrind.patch
new file mode 100644
index 0000000000..41a752023b
--- /dev/null
+++ b/gnu/packages/patches/unzip-valgrind.patch
@@ -0,0 +1,26 @@
+diff --git a/fileio.c b/fileio.c
+index ba0a1d0..03fc4be 100644
+--- a/fileio.c
++++ b/fileio.c
+@@ -2006,6 +2006,7 @@ int do_string(__G__ length, option)   /* return PK-type error code */
+     unsigned comment_bytes_left;
+     unsigned int block_len;
+     int error=PK_OK;
++    unsigned int length2;
+ #ifdef AMIGA
+     char tmp_fnote[2 * AMIGA_FILENOTELEN];   /* extra room for squozen chars */
+ #endif
+@@ -2292,8 +2293,12 @@ int do_string(__G__ length, option)   /* return PK-type error code */
+             seek_zipf(__G__ G.cur_zipfile_bufstart - G.extra_bytes +
+                       (G.inptr-G.inbuf) + length);
+         } else {
+-            if (readbuf(__G__ (char *)G.extra_field, length) == 0)
++            if ((length2 = readbuf(__G__ (char *)G.extra_field, length)) == 0)
+                 return PK_EOF;
++            if(length2 < length) {
++              memset (__G__ (char *)G.extra_field+length2, 0 , length-length2);
++              length = length2;
++            }
+             /* Looks like here is where extra fields are read */
+             getZip64Data(__G__ G.extra_field, length);
+ #ifdef UNICODE_SUPPORT
diff --git a/gnu/packages/patches/unzip-x-option.patch b/gnu/packages/patches/unzip-x-option.patch
new file mode 100644
index 0000000000..72c77aeb78
--- /dev/null
+++ b/gnu/packages/patches/unzip-x-option.patch
@@ -0,0 +1,28 @@
+--- ./process.c.orig    2009-03-06 02:25:10.000000000 +0100
++++ ./process.c 2013-09-12 10:51:16.000000000 +0200
+@@ -2901,9 +2901,9 @@
+         */
+ 
+ #ifdef IZ_HAVE_UXUIDGID
+-            if (eb_len >= EB_UX3_MINLEN
+-                && z_uidgid != NULL
+-                && (*((EB_HEADSIZE + 0) + ef_buf) == 1)
++            if ((eb_len >= EB_UX3_MINLEN)
++                && (z_uidgid != NULL)
++                && ((*((EB_HEADSIZE + 0) + ef_buf) == 1)))
+                     /* only know about version 1 */
+             {
+                 uch uid_size;
+@@ -2915,10 +2915,10 @@
+                 flags &= ~0x0ff;      /* ignore any previous UNIX field */
+ 
+                 if ( read_ux3_value((EB_HEADSIZE + 2) + ef_buf,
+-                                    uid_size, z_uidgid[0])
++                                    uid_size, &z_uidgid[0])
+                     &&
+                      read_ux3_value((EB_HEADSIZE + uid_size + 3) + ef_buf,
+-                                    gid_size, z_uidgid[1]) )
++                                    gid_size, &z_uidgid[1]) )
+                 {
+                     flags |= EB_UX2_VALID;   /* signal success */
+                 }
diff --git a/gnu/packages/patches/unzip-zipbomb-manpage.patch b/gnu/packages/patches/unzip-zipbomb-manpage.patch
new file mode 100644
index 0000000000..cdeeea5c93
--- /dev/null
+++ b/gnu/packages/patches/unzip-zipbomb-manpage.patch
@@ -0,0 +1,25 @@
+From 6fe72291a5563cdbcd2bdd87e36528537b7cdcfb Mon Sep 17 00:00:00 2001
+From: Jakub Martisko <jamartis@redhat.com>
+Date: Mon, 18 Nov 2019 14:17:46 +0100
+Subject: [PATCH] update the man page
+
+---
+ man/unzip.1 | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/man/unzip.1 b/man/unzip.1
+index 21816d1..4d66073 100644
+--- a/man/unzip.1
++++ b/man/unzip.1
+@@ -850,6 +850,8 @@ the specified zipfiles were not found.
+ invalid options were specified on the command line.
+ .IP 11
+ no matching files were found.
++.IP 12
++invalid zip file with overlapped components (possible zip bomb).
+ .IP 50
+ the disk is (or was) full during extraction.
+ .IP 51
+-- 
+2.23.0
+
diff --git a/gnu/packages/patches/unzip-zipbomb-part1.patch b/gnu/packages/patches/unzip-zipbomb-part1.patch
new file mode 100644
index 0000000000..35cf856522
--- /dev/null
+++ b/gnu/packages/patches/unzip-zipbomb-part1.patch
@@ -0,0 +1,25 @@
+From 41beb477c5744bc396fa1162ee0c14218ec12213 Mon Sep 17 00:00:00 2001
+From: Mark Adler <madler@alumni.caltech.edu>
+Date: Mon, 27 May 2019 08:20:32 -0700
+Subject: [PATCH] Fix bug in undefer_input() that misplaced the input state.
+
+---
+ fileio.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fileio.c b/fileio.c
+index c042987..bc00d74 100644
+--- a/fileio.c
++++ b/fileio.c
+@@ -530,8 +530,10 @@ void undefer_input(__G)
+          * This condition was checked when G.incnt_leftover was set > 0 in
+          * defer_leftover_input(), and it is NOT allowed to touch G.csize
+          * before calling undefer_input() when (G.incnt_leftover > 0)
+-         * (single exception: see read_byte()'s  "G.csize <= 0" handling) !!
++         * (single exception: see readbyte()'s  "G.csize <= 0" handling) !!
+          */
++        if (G.csize < 0L)
++            G.csize = 0L;
+         G.incnt = G.incnt_leftover + (int)G.csize;
+         G.inptr = G.inptr_leftover - (int)G.csize;
+         G.incnt_leftover = 0;
diff --git a/gnu/packages/patches/unzip-zipbomb-part2.patch b/gnu/packages/patches/unzip-zipbomb-part2.patch
new file mode 100644
index 0000000000..903c845763
--- /dev/null
+++ b/gnu/packages/patches/unzip-zipbomb-part2.patch
@@ -0,0 +1,349 @@
+From 47b3ceae397d21bf822bc2ac73052a4b1daf8e1c Mon Sep 17 00:00:00 2001
+From: Mark Adler <madler@alumni.caltech.edu>
+Date: Tue, 11 Jun 2019 22:01:18 -0700
+Subject: [PATCH] Detect and reject a zip bomb using overlapped entries.
+
+This detects an invalid zip file that has at least one entry that
+overlaps with another entry or with the central directory to the
+end of the file. A Fifield zip bomb uses overlapped local entries
+to vastly increase the potential inflation ratio. Such an invalid
+zip file is rejected.
+
+See https://www.bamsoftware.com/hacks/zipbomb/ for David Fifield's
+analysis, construction, and examples of such zip bombs.
+
+The detection maintains a list of covered spans of the zip files
+so far, where the central directory to the end of the file and any
+bytes preceding the first entry at zip file offset zero are
+considered covered initially. Then as each entry is decompressed
+or tested, it is considered covered. When a new entry is about to
+be processed, its initial offset is checked to see if it is
+contained by a covered span. If so, the zip file is rejected as
+invalid.
+
+This commit depends on a preceding commit: "Fix bug in
+undefer_input() that misplaced the input state."
+---
+ extract.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ globals.c |   1 +
+ globals.h |   3 +
+ process.c |  11 ++++
+ unzip.h   |   1 +
+ 5 files changed, 205 insertions(+), 1 deletion(-)
+
+diff --git a/extract.c b/extract.c
+index 1acd769..0973a33 100644
+--- a/extract.c
++++ b/extract.c
+@@ -319,6 +319,125 @@ static ZCONST char Far UnsupportedExtraField[] =
+   "\nerror:  unsupported extra-field compression type (%u)--skipping\n";
+ static ZCONST char Far BadExtraFieldCRC[] =
+   "error [%s]:  bad extra-field CRC %08lx (should be %08lx)\n";
++static ZCONST char Far NotEnoughMemCover[] =
++  "error: not enough memory for bomb detection\n";
++static ZCONST char Far OverlappedComponents[] =
++  "error: invalid zip file with overlapped components (possible zip bomb)\n";
++
++
++
++
++
++/* A growable list of spans. */
++typedef zoff_t bound_t;
++typedef struct {
++    bound_t beg;        /* start of the span */
++    bound_t end;        /* one past the end of the span */
++} span_t;
++typedef struct {
++    span_t *span;       /* allocated, distinct, and sorted list of spans */
++    size_t num;         /* number of spans in the list */
++    size_t max;         /* allocated number of spans (num <= max) */
++} cover_t;
++
++/*
++ * Return the index of the first span in cover whose beg is greater than val.
++ * If there is no such span, then cover->num is returned.
++ */
++static size_t cover_find(cover, val)
++    cover_t *cover;
++    bound_t val;
++{
++    size_t lo = 0, hi = cover->num;
++    while (lo < hi) {
++        size_t mid = (lo + hi) >> 1;
++        if (val < cover->span[mid].beg)
++            hi = mid;
++        else
++            lo = mid + 1;
++    }
++    return hi;
++}
++
++/* Return true if val lies within any one of the spans in cover. */
++static int cover_within(cover, val)
++    cover_t *cover;
++    bound_t val;
++{
++    size_t pos = cover_find(cover, val);
++    return pos > 0 && val < cover->span[pos - 1].end;
++}
++
++/*
++ * Add a new span to the list, but only if the new span does not overlap any
++ * spans already in the list. The new span covers the values beg..end-1. beg
++ * must be less than end.
++ *
++ * Keep the list sorted and merge adjacent spans. Grow the allocated space for
++ * the list as needed. On success, 0 is returned. If the new span overlaps any
++ * existing spans, then 1 is returned and the new span is not added to the
++ * list. If the new span is invalid because beg is greater than or equal to
++ * end, then -1 is returned. If the list needs to be grown but the memory
++ * allocation fails, then -2 is returned.
++ */
++static int cover_add(cover, beg, end)
++    cover_t *cover;
++    bound_t beg;
++    bound_t end;
++{
++    size_t pos;
++    int prec, foll;
++
++    if (beg >= end)
++    /* The new span is invalid. */
++        return -1;
++
++    /* Find where the new span should go, and make sure that it does not
++       overlap with any existing spans. */
++    pos = cover_find(cover, beg);
++    if ((pos > 0 && beg < cover->span[pos - 1].end) ||
++        (pos < cover->num && end > cover->span[pos].beg))
++        return 1;
++
++    /* Check for adjacencies. */
++    prec = pos > 0 && beg == cover->span[pos - 1].end;
++    foll = pos < cover->num && end == cover->span[pos].beg;
++    if (prec && foll) {
++        /* The new span connects the preceding and following spans. Merge the
++           following span into the preceding span, and delete the following
++           span. */
++        cover->span[pos - 1].end = cover->span[pos].end;
++        cover->num--;
++        memmove(cover->span + pos, cover->span + pos + 1,
++                (cover->num - pos) * sizeof(span_t));
++    }
++    else if (prec)
++        /* The new span is adjacent only to the preceding span. Extend the end
++           of the preceding span. */
++        cover->span[pos - 1].end = end;
++    else if (foll)
++        /* The new span is adjacent only to the following span. Extend the
++           beginning of the following span. */
++        cover->span[pos].beg = beg;
++    else {
++        /* The new span has gaps between both the preceding and the following
++           spans. Assure that there is room and insert the span.  */
++        if (cover->num == cover->max) {
++            size_t max = cover->max == 0 ? 16 : cover->max << 1;
++            span_t *span = realloc(cover->span, max * sizeof(span_t));
++            if (span == NULL)
++                return -2;
++            cover->span = span;
++            cover->max = max;
++        }
++        memmove(cover->span + pos + 1, cover->span + pos,
++                (cover->num - pos) * sizeof(span_t));
++        cover->num++;
++        cover->span[pos].beg = beg;
++        cover->span[pos].end = end;
++    }
++    return 0;
++}
+ 
+ 
+ 
+@@ -374,6 +493,29 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+     }
+ #endif /* !SFX || SFX_EXDIR */
+ 
++    /* One more: initialize cover structure for bomb detection. Start with a
++       span that covers the central directory though the end of the file. */
++    if (G.cover == NULL) {
++        G.cover = malloc(sizeof(cover_t));
++        if (G.cover == NULL) {
++            Info(slide, 0x401, ((char *)slide,
++              LoadFarString(NotEnoughMemCover)));
++            return PK_MEM;
++        }
++        ((cover_t *)G.cover)->span = NULL;
++        ((cover_t *)G.cover)->max = 0;
++    }
++    ((cover_t *)G.cover)->num = 0;
++    if ((G.extra_bytes != 0 &&
++         cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
++        cover_add((cover_t *)G.cover,
++                  G.extra_bytes + G.ecrec.offset_start_central_directory,
++                  G.ziplen) != 0) {
++        Info(slide, 0x401, ((char *)slide,
++          LoadFarString(NotEnoughMemCover)));
++        return PK_MEM;
++    }
++
+ /*---------------------------------------------------------------------------
+     The basic idea of this function is as follows.  Since the central di-
+     rectory lies at the end of the zipfile and the member files lie at the
+@@ -591,7 +733,8 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+             if (error > error_in_archive)
+                 error_in_archive = error;
+             /* ...and keep going (unless disk full or user break) */
+-            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC) {
++            if (G.disk_full > 1 || error_in_archive == IZ_CTRLC ||
++                error == PK_BOMB) {
+                 /* clear reached_end to signal premature stop ... */
+                 reached_end = FALSE;
+                 /* ... and cancel scanning the central directory */
+@@ -1060,6 +1203,11 @@ static int extract_or_test_entrylist(__G__ numchunk,
+ 
+         /* seek_zipf(__G__ pInfo->offset);  */
+         request = G.pInfo->offset + G.extra_bytes;
++        if (cover_within((cover_t *)G.cover, request)) {
++            Info(slide, 0x401, ((char *)slide,
++              LoadFarString(OverlappedComponents)));
++            return PK_BOMB;
++        }
+         inbuf_offset = request % INBUFSIZ;
+         bufstart = request - inbuf_offset;
+ 
+@@ -1591,6 +1739,18 @@ static int extract_or_test_entrylist(__G__ numchunk,
+             return IZ_CTRLC;        /* cancel operation by user request */
+         }
+ #endif
++        error = cover_add((cover_t *)G.cover, request,
++                          G.cur_zipfile_bufstart + (G.inptr - G.inbuf));
++        if (error < 0) {
++            Info(slide, 0x401, ((char *)slide,
++              LoadFarString(NotEnoughMemCover)));
++            return PK_MEM;
++        }
++        if (error != 0) {
++            Info(slide, 0x401, ((char *)slide,
++              LoadFarString(OverlappedComponents)));
++            return PK_BOMB;
++        }
+ #ifdef MACOS  /* MacOS is no preemptive OS, thus call event-handling by hand */
+         UserStop();
+ #endif
+@@ -1992,6 +2152,34 @@ static int extract_or_test_member(__G)    /* return PK-type error code */
+     }
+ 
+     undefer_input(__G);
++
++    if ((G.lrec.general_purpose_bit_flag & 8) != 0) {
++        /* skip over data descriptor (harder than it sounds, due to signature
++         * ambiguity)
++         */
++#       define SIG 0x08074b50
++#       define LOW 0xffffffff
++        uch buf[12];
++        unsigned shy = 12 - readbuf((char *)buf, 12);
++        ulg crc = shy ? 0 : makelong(buf);
++        ulg clen = shy ? 0 : makelong(buf + 4);
++        ulg ulen = shy ? 0 : makelong(buf + 8); /* or high clen if ZIP64 */
++        if (crc == SIG &&                       /* if not SIG, no signature */
++            (G.lrec.crc32 != SIG ||             /* if not SIG, have signature */
++             (clen == SIG &&                    /* if not SIG, no signature */
++              ((G.lrec.csize & LOW) != SIG ||   /* if not SIG, have signature */
++               (ulen == SIG &&                  /* if not SIG, no signature */
++                (G.zip64 ? G.lrec.csize >> 32 : G.lrec.ucsize) != SIG
++                                                /* if not SIG, have signature */
++                )))))
++                   /* skip four more bytes to account for signature */
++                   shy += 4 - readbuf((char *)buf, 4);
++        if (G.zip64)
++            shy += 8 - readbuf((char *)buf, 8); /* skip eight more for ZIP64 */
++        if (shy)
++            error = PK_ERR;
++    }
++
+     return error;
+ 
+ } /* end function extract_or_test_member() */
+diff --git a/globals.c b/globals.c
+index fa8cca5..1e0f608 100644
+--- a/globals.c
++++ b/globals.c
+@@ -181,6 +181,7 @@ Uz_Globs *globalsCtor()
+ # if (!defined(NO_TIMESTAMPS))
+     uO.D_flag=1;    /* default to '-D', no restoration of dir timestamps */
+ # endif
++    G.cover = NULL;     /* not allocated yet */
+ #endif
+ 
+     uO.lflag=(-1);
+diff --git a/globals.h b/globals.h
+index 11b7215..2bdcdeb 100644
+--- a/globals.h
++++ b/globals.h
+@@ -260,12 +260,15 @@ typedef struct Globals {
+     ecdir_rec       ecrec;         /* used in unzip.c, extract.c */
+     z_stat   statbuf;              /* used by main, mapname, check_for_newer */
+ 
++    int zip64;                     /* true if Zip64 info in extra field */
++
+     int      mem_mode;
+     uch      *outbufptr;           /* extract.c static */
+     ulg      outsize;              /* extract.c static */
+     int      reported_backslash;   /* extract.c static */
+     int      disk_full;
+     int      newfile;
++    void     **cover;              /* used in extract.c for bomb detection */
+ 
+     int      didCRlast;            /* fileio static */
+     ulg      numlines;             /* fileio static: number of lines printed */
+diff --git a/process.c b/process.c
+index 1e9a1e1..d2e4dc3 100644
+--- a/process.c
++++ b/process.c
+@@ -637,6 +637,13 @@ void free_G_buffers(__G)     /* releases all memory allocated in global vars */
+     }
+ #endif
+ 
++    /* Free the cover span list and the cover structure. */
++    if (G.cover != NULL) {
++        free(*(G.cover));
++        free(G.cover);
++        G.cover = NULL;
++    }
++
+ } /* end function free_G_buffers() */
+ 
+ 
+@@ -1890,6 +1897,8 @@ int getZip64Data(__G__ ef_buf, ef_len)
+ #define Z64FLGS 0xffff
+ #define Z64FLGL 0xffffffff
+ 
++    G.zip64 = FALSE;
++
+     if (ef_len == 0 || ef_buf == NULL)
+         return PK_COOL;
+ 
+@@ -1927,6 +1936,8 @@ int getZip64Data(__G__ ef_buf, ef_len)
+ #if 0
+           break;                /* Expect only one EF_PKSZ64 block. */
+ #endif /* 0 */
++
++          G.zip64 = TRUE;
+         }
+
+         /* Skip this extra field block. */
+diff --git a/unzip.h b/unzip.h
+index 5b2a326..ed24a5b 100644
+--- a/unzip.h
++++ b/unzip.h
+@@ -645,6 +645,7 @@ typedef struct _Uzp_cdir_Rec {
+ #define PK_NOZIP           9   /* zipfile not found */
+ #define PK_PARAM          10   /* bad or illegal parameters specified */
+ #define PK_FIND           11   /* no files found */
++#define PK_BOMB           12   /* likely zip bomb */
+ #define PK_DISK           50   /* disk full */
+ #define PK_EOF            51   /* unexpected EOF */
+ 
diff --git a/gnu/packages/patches/unzip-zipbomb-part3.patch b/gnu/packages/patches/unzip-zipbomb-part3.patch
new file mode 100644
index 0000000000..3b8d67b773
--- /dev/null
+++ b/gnu/packages/patches/unzip-zipbomb-part3.patch
@@ -0,0 +1,112 @@
+From 6d351831be705cc26d897db44f878a978f4138fc Mon Sep 17 00:00:00 2001
+From: Mark Adler <madler@alumni.caltech.edu>
+Date: Thu, 25 Jul 2019 20:43:17 -0700
+Subject: [PATCH] Do not raise a zip bomb alert for a misplaced central
+ directory.
+
+There is a zip-like file in the Firefox distribution, omni.ja,
+which is a zip container with the central directory placed at the
+start of the file instead of after the local entries as required
+by the zip standard. This commit marks the actual location of the
+central directory, as well as the end of central directory records,
+as disallowed locations. This now permits such containers to not
+raise a zip bomb alert, where in fact there are no overlaps.
+---
+ extract.c | 25 +++++++++++++++++++------
+ process.c |  6 ++++++
+ unzpriv.h | 10 ++++++++++
+ 3 files changed, 35 insertions(+), 6 deletions(-)
+
+diff --git a/extract.c b/extract.c
+index 0973a33..1b73cb0 100644
+--- a/extract.c
++++ b/extract.c
+@@ -493,8 +493,11 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+     }
+ #endif /* !SFX || SFX_EXDIR */
+ 
+-    /* One more: initialize cover structure for bomb detection. Start with a
+-       span that covers the central directory though the end of the file. */
++    /* One more: initialize cover structure for bomb detection. Start with
++       spans that cover any extra bytes at the start, the central directory,
++       the end of central directory record (including the Zip64 end of central
++       directory locator, if present), and the Zip64 end of central directory
++       record, if present. */
+     if (G.cover == NULL) {
+         G.cover = malloc(sizeof(cover_t));
+         if (G.cover == NULL) {
+@@ -506,15 +509,25 @@ int extract_or_test_files(__G)    /* return PK-type error code */
+         ((cover_t *)G.cover)->max = 0;
+     }
+     ((cover_t *)G.cover)->num = 0;
+-    if ((G.extra_bytes != 0 &&
+-         cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
+-        cover_add((cover_t *)G.cover,
++    if (cover_add((cover_t *)G.cover,
+                   G.extra_bytes + G.ecrec.offset_start_central_directory,
+-                  G.ziplen) != 0) {
++                  G.extra_bytes + G.ecrec.offset_start_central_directory +
++                  G.ecrec.size_central_directory) != 0) {
+         Info(slide, 0x401, ((char *)slide,
+           LoadFarString(NotEnoughMemCover)));
+         return PK_MEM;
+     }
++    if ((G.extra_bytes != 0 &&
++         cover_add((cover_t *)G.cover, 0, G.extra_bytes) != 0) ||
++        (G.ecrec.have_ecr64 &&
++         cover_add((cover_t *)G.cover, G.ecrec.ec64_start,
++                   G.ecrec.ec64_end) != 0) ||
++        cover_add((cover_t *)G.cover, G.ecrec.ec_start,
++                  G.ecrec.ec_end) != 0) {
++        Info(slide, 0x401, ((char *)slide,
++          LoadFarString(OverlappedComponents)));
++        return PK_BOMB;
++    }
+ 
+ /*---------------------------------------------------------------------------
+     The basic idea of this function is as follows.  Since the central di-
+diff --git a/process.c b/process.c
+index d2e4dc3..d75d405 100644
+--- a/process.c
++++ b/process.c
+@@ -1408,6 +1408,10 @@ static int find_ecrec64(__G__ searchlen)         /* return PK-class error */
+ 
+     /* Now, we are (almost) sure that we have a Zip64 archive. */
+     G.ecrec.have_ecr64 = 1;
++    G.ecrec.ec_start -= ECLOC64_SIZE+4;
++    G.ecrec.ec64_start = ecrec64_start_offset;
++    G.ecrec.ec64_end = ecrec64_start_offset +
++                       12 + makeint64(&byterec[ECREC64_LENGTH]);
+ 
+     /* Update the "end-of-central-dir offset" for later checks. */
+     G.real_ecrec_offset = ecrec64_start_offset;
+@@ -1542,6 +1546,8 @@ static int find_ecrec(__G__ searchlen)          /* return PK-class error */
+       makelong(&byterec[OFFSET_START_CENTRAL_DIRECTORY]);
+     G.ecrec.zipfile_comment_length =
+       makeword(&byterec[ZIPFILE_COMMENT_LENGTH]);
++    G.ecrec.ec_start = G.real_ecrec_offset;
++    G.ecrec.ec_end = G.ecrec.ec_start + 22 + G.ecrec.zipfile_comment_length;
+ 
+     /* Now, we have to read the archive comment, BEFORE the file pointer
+        is moved away backwards to seek for a Zip64 ECLOC64 structure.
+diff --git a/unzpriv.h b/unzpriv.h
+index dc9eff5..297b3c7 100644
+--- a/unzpriv.h
++++ b/unzpriv.h
+@@ -2185,6 +2185,16 @@ typedef struct VMStimbuf {
+        int have_ecr64;                  /* valid Zip64 ecdir-record exists */
+        int is_zip64_archive;            /* Zip64 ecdir-record is mandatory */
+        ush zipfile_comment_length;
++       zusz_t ec_start, ec_end;         /* offsets of start and end of the
++                                           end of central directory record,
++                                           including if present the Zip64
++                                           end of central directory locator,
++                                           which immediately precedes the
++                                           end of central directory record */
++       zusz_t ec64_start, ec64_end;     /* if have_ecr64 is true, then these
++                                           are the offsets of the start and
++                                           end of the Zip64 end of central
++                                           directory record */
+    } ecdir_rec;
+ 
+ 
diff --git a/gnu/packages/patches/vtk-fix-freetypetools-build-failure.patch b/gnu/packages/patches/vtk-fix-freetypetools-build-failure.patch
new file mode 100644
index 0000000000..6988e65872
--- /dev/null
+++ b/gnu/packages/patches/vtk-fix-freetypetools-build-failure.patch
@@ -0,0 +1,36 @@
+This fixes a build failure in VTK when building against recent versions
+of freetype.
+
+  https://gitlab.kitware.com/vtk/vtk/-/merge_requests/7432
+
+Patch by Ben Boeckel <ben.boeckel@kitware.com>
+
+Subject: [PATCH] vtkFreeTypeTools: avoid using an internal macro
+
+This macro has been removed upstream as it was always intended to be
+private.
+---
+ Rendering/FreeType/vtkFreeTypeTools.cxx | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/Rendering/FreeType/vtkFreeTypeTools.cxx b/Rendering/FreeType/vtkFreeTypeTools.cxx
+index c54289dc60..03b899c4da 100644
+--- a/Rendering/FreeType/vtkFreeTypeTools.cxx
++++ b/Rendering/FreeType/vtkFreeTypeTools.cxx
+@@ -387,11 +387,8 @@ FTC_CMapCache* vtkFreeTypeTools::GetCMapCache()
+ }
+ 
+ //----------------------------------------------------------------------------
+-FT_CALLBACK_DEF(FT_Error)
+-vtkFreeTypeToolsFaceRequester(FTC_FaceID face_id,
+-                              FT_Library lib,
+-                              FT_Pointer request_data,
+-                              FT_Face* face)
++static FT_Error vtkFreeTypeToolsFaceRequester(
++  FTC_FaceID face_id, FT_Library lib, FT_Pointer request_data, FT_Face* face)
+ {
+ #if VTK_FTFC_DEBUG_CD
+   printf("vtkFreeTypeToolsFaceRequester()\n");
+-- 
+2.30.1
+
diff --git a/gnu/packages/patches/ytnef-CVE-2021-3403.patch b/gnu/packages/patches/ytnef-CVE-2021-3403.patch
new file mode 100644
index 0000000000..4b1c9d659f
--- /dev/null
+++ b/gnu/packages/patches/ytnef-CVE-2021-3403.patch
@@ -0,0 +1,32 @@
+From f2380a53fb84d370eaf6e6c3473062c54c57fac7 Mon Sep 17 00:00:00 2001
+From: Oliver Giles <ohw.giles@gmail.com>
+Date: Mon, 1 Feb 2021 10:12:16 +1300
+Subject: [PATCH] Prevent potential double-free in TNEFSubjectHandler
+
+If TNEFSubjectHandler is called multiple times, but the last time
+failed due to the PREALLOCCHECK, the subject.data member will be
+a freed, but invalid pointer. To prevent a double-free next time
+TNEFSubjectHandler is entered, set it to zero after freeing.
+
+Resolves: #85
+Reported-by: jasperla
+---
+ lib/ytnef.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/lib/ytnef.c b/lib/ytnef.c
+index b148719..b06c807 100644
+--- a/lib/ytnef.c
++++ b/lib/ytnef.c
+@@ -301,8 +301,10 @@ int TNEFFromHandler STD_ARGLIST {
+ }
+ // -----------------------------------------------------------------------------
+ int TNEFSubjectHandler STD_ARGLIST {
+-  if (TNEF->subject.data)
++  if (TNEF->subject.data) {
+     free(TNEF->subject.data);
++    TNEF->subject.data = NULL;
++  }
+ 
+   PREALLOCCHECK(size, 100);
+   TNEF->subject.data = calloc(size+1, sizeof(BYTE));
diff --git a/gnu/packages/patches/ytnef-CVE-2021-3404.patch b/gnu/packages/patches/ytnef-CVE-2021-3404.patch
new file mode 100644
index 0000000000..e991d6aff1
--- /dev/null
+++ b/gnu/packages/patches/ytnef-CVE-2021-3404.patch
@@ -0,0 +1,30 @@
+From f9ff4a203b8c155d51a208cadadb62f224fba715 Mon Sep 17 00:00:00 2001
+From: Oliver Giles <ohw.giles@gmail.com>
+Date: Mon, 1 Feb 2021 10:18:17 +1300
+Subject: [PATCH] Ensure the size of the version field is 4 bytes
+
+A corrupted version field size can cause TNEFVersion to access outside
+of allocated memory. Check the version is the expected size and raise
+an error if not.
+
+Resolves: #86
+Reported-by: jasperla
+---
+ lib/ytnef.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/lib/ytnef.c b/lib/ytnef.c
+index b148719..ffede44 100644
+--- a/lib/ytnef.c
++++ b/lib/ytnef.c
+@@ -335,6 +335,10 @@ int TNEFRendData STD_ARGLIST {
+ int TNEFVersion STD_ARGLIST {
+   WORD major;
+   WORD minor;
++  if (size != 2 * sizeof(WORD)) {
++    printf("Incorrect size of version field, suspected corruption\n");
++    return -1;
++  }
+   minor = SwapWord((BYTE*)data, size);
+   major = SwapWord((BYTE*)data + 2, size - 2);
+