code:
--- tuxpaint-0.9.22/src/tuxpaint.c
+++ tuxpaint-0.9.22/src/tuxpaint.c
@@ -7474,11 +7474,21 @@
 static void load_stamps(SDL_Surface * screen)
 {
   char *homedirdir = get_fname("stamps", DIR_DATA);
+  char *stamps_path = getenv("TUXPAINT_STAMPS_PATH");

   default_stamp_size = compute_default_scale_factor(1.0);

   load_stamp_dir(screen, homedirdir);
   load_stamp_dir(screen, DATA_PREFIX "stamps");
+  /* Load any stamps in TUXPAINT_STAMPS_PATH */
+  if (stamps_path) {
+    char *token;
+    token = strtok(stamps_path, ":");
+    while (token != NULL) {
+      load_stamp_dir(screen, token);
+      token = strtok(NULL, ":");
+    }
+  }
 #ifdef __APPLE__
   load_stamp_dir(screen, "/Library/Application Support/TuxPaint/stamps");
 #endif


code:
From 46bee14d3cc49d4fb49eaf36a29dbcc7a11a5ab7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Bri=C3=A8re?= <fbriere@fbriere.net>
Date: Sat, 6 Jul 2019 15:40:56 -0400
Subject: [PATCH] Add support for the new bcg729 API, introduced in version
 1.0.2

Starting with version 1.0.2, bcg729 has changed its API to add support
for G.729B, thus requiring us to adjust our function calls depending on
which version is installed.

When dealing with the new API, we merely need to add a few parameters to
disable all G.729B features, namely:

* On the decoder side: When `SIDFrameFlag` is not set, the decoder will
  behave just like before, decoding the payload as a standard G.729A
  voice frame (or concealing an erased frame).  The other parameters,
  `rfc3389PayloadFlag` and `bitStreamLength`, are only of use when
  dealing with a SID frame sent as per RFC 3389, and are ignored if
  `SIDFrameFlag` is not set.

* On the encoder side: When `enableVAD` is disabled, the encoder will
  behave just like before, producing only standard G.729A voice frames.
  The only API difference is the introduction of `*bitStreamLength`, to
  return the length of the encoded frame (0, 2 or 10 bytes).  In our
  case, this will always be 10 bytes just like before; an assert() was
  added to guarantee this.

Closes #104
---
 CMakeLists.txt              |  4 ++++
 cmake/FindG729.cmake        | 36 ++++++++++++++++++++++++++++++++++++
 src/audio/audio_decoder.cpp |  8 ++++++++
 src/audio/audio_encoder.cpp | 10 ++++++++++
 twinkle_config.h.in         |  1 +
 5 files changed, 59 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1dafe55..7e3fde0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -116,6 +116,10 @@ if (WITH_G729)
 	if (G729_FOUND)
 		message(STATUS "bcg729 OK")
 		set(HAVE_BCG729 TRUE)
+
+		if (G729_ANNEX_B)
+			set(HAVE_BCG729_ANNEX_B TRUE)
+		endif (G729_ANNEX_B)

 		include_directories(${G729_INCLUDE_DIR})
 	else (G729_FOUND)
diff --git a/cmake/FindG729.cmake b/cmake/FindG729.cmake
index 4a30ba0..1fbfeeb 100644
--- a/cmake/FindG729.cmake
+++ b/cmake/FindG729.cmake
@@ -1,14 +1,50 @@
+INCLUDE(CMakePushCheckState)
+INCLUDE(CheckCSourceCompiles)
+
 FIND_PATH(G729_INCLUDE_DIR bcg729/decoder.h)
 FIND_LIBRARY(G729_LIBRARY NAMES bcg729)

 IF(G729_INCLUDE_DIR AND G729_LIBRARY)
 	SET(G729_FOUND TRUE)
+
+	# The bcg729 API was changed in 1.0.2 to add support for G.729 Annex B.
+	# This checks whether we are dealing with the old or new API.
+	CMAKE_PUSH_CHECK_STATE()
+	SET(CMAKE_REQUIRED_INCLUDES "${INCLUDE_DIRECTORIES}" "${G729_INCLUDE_DIR}")
+	SET(CMAKE_REQUIRED_LIBRARIES "${G729_LIBRARY}")
+	SET(CMAKE_REQUIRED_QUIET TRUE)
+	# Try to compile something using the old (pre-1.0.2) API.
+	#
+	# We cannot do it the other way around, as initBcg729EncoderChannel()
+	# did not have a prototype before 1.0.2, thus compilation would not fail
+	# when passing it an extra argument.
+	CHECK_C_SOURCE_COMPILES("
+		#include <bcg729/encoder.h>
+
+		int main() {
+			/* This function requires an argument since 1.0.2 */
+			initBcg729EncoderChannel();
+			return 0;
+		}
+	" G729_OLD_API)
+	CMAKE_POP_CHECK_STATE()
+
+	IF (G729_OLD_API)
+		SET(G729_ANNEX_B FALSE)
+	ELSE (G729_OLD_API)
+		SET(G729_ANNEX_B TRUE)
+	ENDIF (G729_OLD_API)
 ENDIF(G729_INCLUDE_DIR AND G729_LIBRARY)

 IF(G729_FOUND)
 	IF (NOT G729_FIND_QUIETLY)
 		MESSAGE(STATUS "Found bcg729 includes:	${G729_INCLUDE_DIR}/bcg729/decoder.h")
 		MESSAGE(STATUS "Found bcg729 library: ${G729_LIBRARY}")
+		IF (G729_ANNEX_B)
+			MESSAGE(STATUS "bcg729 supports Annex B; using the new (1.0.2) API")
+		ELSE (G729_ANNEX_B)
+			MESSAGE(STATUS "bcg729 does not support Annex B; using the old (pre-1.0.2) API")
+		ENDIF (G729_ANNEX_B)
 	ENDIF (NOT G729_FIND_QUIETLY)
 ELSE(G729_FOUND)
 	IF (G729_FIND_REQUIRED)
diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp
index 65935dd..c661910 100644
--- a/src/audio/audio_decoder.cpp
+++ b/src/audio/audio_decoder.cpp
@@ -547,7 +547,11 @@ uint16 t_g729a_audio_decoder::decode(uint8 *payload, uint16 payload_size,

 	for (uint16 done = 0; done < payload_size; done += 10)
 	{
+#ifdef HAVE_BCG729_ANNEX_B
+		bcg729Decoder(_context, &payload[done], 0, false, false, false, &pcm_buf[done * 8]);
+#else
 		bcg729Decoder(_context, &payload[done], false, &pcm_buf[done * 8]);
+#endif
 	}

 	return payload_size * 8;
@@ -562,7 +566,11 @@ uint16 t_g729a_audio_decoder::conceal(int16 *pcm_buf, uint16 pcm_buf_size)
 {
 	assert(pcm_buf_size >= 80);

+#ifdef HAVE_BCG729_ANNEX_B
+	bcg729Decoder(_context, nullptr, 0, true, false, false, pcm_buf);
+#else
 	bcg729Decoder(_context, nullptr, true, pcm_buf);
+#endif
 	return 80;
 }

diff --git a/src/audio/audio_encoder.cpp b/src/audio/audio_encoder.cpp
index d6ff356..952b1ee 100644
--- a/src/audio/audio_encoder.cpp
+++ b/src/audio/audio_encoder.cpp
@@ -433,7 +433,11 @@ uint16 t_g726_audio_encoder::encode(int16 *sample_buf, uint16 nsamples,
 t_g729a_audio_encoder::t_g729a_audio_encoder(uint16 payload_id, uint16 ptime, t_user *user_config)
 	: t_audio_encoder(payload_id, ptime, user_config)
 {
+#ifdef HAVE_BCG729_ANNEX_B
+	_context = initBcg729EncoderChannel(false);
+#else
 	_context = initBcg729EncoderChannel();
+#endif
 }

 t_g729a_audio_encoder::~t_g729a_audio_encoder()
@@ -451,7 +455,13 @@ uint16 t_g729a_audio_encoder::encode(int16 *sample_buf, uint16 nsamples,

 	for (uint16 done = 0; done < nsamples; done += 80)
 	{
+#ifdef HAVE_BCG729_ANNEX_B
+		uint8 frame_size = 10;
+		bcg729Encoder(_context, &sample_buf[done], &payload[done / 8], &frame_size);
+		assert(frame_size == 10);
+#else
 		bcg729Encoder(_context, &sample_buf[done], &payload[done / 8]);
+#endif
 	}

 	return nsamples / 8;
diff --git a/twinkle_config.h.in b/twinkle_config.h.in
index a1aa3b4..53a0426 100644
--- a/twinkle_config.h.in
+++ b/twinkle_config.h.in
@@ -4,6 +4,7 @@
 #cmakedefine HAVE_ILBC_CPP
 #cmakedefine HAVE_ZRTP
 #cmakedefine HAVE_BCG729
+#cmakedefine HAVE_BCG729_ANNEX_B
 #cmakedefine HAVE_GSM

 #cmakedefine HAVE_UNISTD_H

repo_name: maximed/guix

license: mit


code:
From 3fc056f0b9f7c26e58a1e947c8c0184e55919614 Mon Sep 17 00:00:00 2001
From: David Abdurachmanov <david.abdurachmanov@gmail.com>
Date: Wed, 21 Aug 2019 12:07:20 -0700
Subject: [PATCH] qemu-riscv64_smode, sifive-fu540: fix extlinux (define
 preboot)
Forwarded: https://patchwork.ozlabs.org/patch/1151125/

Commit 37304aaf60bf92a5dc3ef222ba520698bd862a44 removed preboot
commands in RISC-V targets and broke extlinux support as reported
by Fu Wei <wefu@redhat.com>.

The patch finishes migration of CONFIG_USE_PREBOOT and CONFIG_REBOOT
to Kconfig.

Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
---
 configs/qemu-riscv64_smode_defconfig | 2 ++
 configs/sifive_fu540_defconfig       | 2 ++
 3 files changed, 4 insertions(+), 4 deletions(-)

Index: u-boot/configs/qemu-riscv64_smode_defconfig
===================================================================
--- u-boot.orig/configs/qemu-riscv64_smode_defconfig
+++ u-boot/configs/qemu-riscv64_smode_defconfig
@@ -14,3 +14,5 @@ CONFIG_CMD_NVEDIT_EFI=y
 CONFIG_OF_PRIOR_STAGE=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_DM_MTD=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="setenv fdt_addr ${fdtcontroladdr}; fdt addr ${fdtcontroladdr};"
Index: u-boot/configs/sifive_fu540_defconfig
===================================================================
--- u-boot.orig/configs/sifive_fu540_defconfig
+++ u-boot/configs/sifive_fu540_defconfig
@@ -27,3 +27,5 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_CLK=y
 CONFIG_DM_MTD=y
 CONFIG_DM_RESET=y
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="setenv fdt_addr ${fdtcontroladdr}; fdt addr ${fdtcontroladdr};"


code:
Downloaded from:
https://patchwork.ozlabs.org/project/uboot/patch/20210406151059.1187379-1-icenowy@aosc.io

From patchwork Tue Apr  6 15:10:59 2021
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Icenowy Zheng <icenowy@aosc.io>
X-Patchwork-Id: 1462876
X-Patchwork-Delegate: ykai007@gmail.com
Return-Path: <u-boot-bounces@lists.denx.de>
X-Original-To: incoming@patchwork.ozlabs.org
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
Authentication-Results: ozlabs.org;
 spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
 (client-ip=85.214.62.61; helo=phobos.denx.de;
 envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)
Authentication-Results: ozlabs.org;
	dkim=fail reason="signature verification failed" (1024-bit key;
 unprotected) header.d=mymailcheap.com header.i=@mymailcheap.com
 header.a=rsa-sha256 header.s=default header.b=unszVtqT;
	dkim=fail reason="signature verification failed" (1024-bit key;
 unprotected) header.d=aosc.io header.i=@aosc.io header.a=rsa-sha256
 header.s=default header.b=mWwYCh9A;
	dkim-atps=neutral
Received: from phobos.denx.de (phobos.denx.de [85.214.62.61])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest
 SHA256)
	(No client certificate requested)
	by ozlabs.org (Postfix) with ESMTPS id 4FF9wc3GdNz9sW1
	for <incoming@patchwork.ozlabs.org>; Wed,  7 Apr 2021 01:11:42 +1000 (AEST)
Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
	by phobos.denx.de (Postfix) with ESMTP id C1F9C8040A;
	Tue,  6 Apr 2021 17:11:32 +0200 (CEST)
Authentication-Results: phobos.denx.de;
 dmarc=none (p=none dis=none) header.from=aosc.io
Authentication-Results: phobos.denx.de;
 spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
Authentication-Results: phobos.denx.de;
	dkim=fail reason="signature verification failed" (1024-bit key;
 unprotected) header.d=mymailcheap.com header.i=@mymailcheap.com
 header.b="unszVtqT";
	dkim=fail reason="signature verification failed" (1024-bit key;
 unprotected) header.d=aosc.io header.i=@aosc.io header.b="mWwYCh9A";
	dkim-atps=neutral
Received: by phobos.denx.de (Postfix, from userid 109)
 id E4F22805B4; Tue,  6 Apr 2021 17:11:30 +0200 (CEST)
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
X-Spam-Level:
X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,
 DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE autolearn=ham
 autolearn_force=no version=3.4.2
Received: from relay3.mymailcheap.com (relay3.mymailcheap.com
 [217.182.66.161])
 (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
 (No client certificate requested)
 by phobos.denx.de (Postfix) with ESMTPS id 2FC4A8039D
 for <u-boot@lists.denx.de>; Tue,  6 Apr 2021 17:11:27 +0200 (CEST)
Authentication-Results: phobos.denx.de;
 dmarc=none (p=none dis=none) header.from=aosc.io
Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=icenowy@aosc.io
Received: from filter2.mymailcheap.com (filter2.mymailcheap.com
 [91.134.140.82])
 by relay3.mymailcheap.com (Postfix) with ESMTPS id A6AC13ECDF;
 Tue,  6 Apr 2021 17:11:26 +0200 (CEST)
Received: from localhost (localhost [127.0.0.1])
 by filter2.mymailcheap.com (Postfix) with ESMTP id 88D512A915;
 Tue,  6 Apr 2021 17:11:26 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mymailcheap.com;
 s=default; t=1617721886;
 bh=qb5gt5o7M9qjdJd67A3WHGZp/76w4s4FS6+u1VuEh/o=;
 h=From:To:Cc:Subject:Date:From;
 b=unszVtqTnO9MGZVbgLH5H0cMo3VfQ+g5377blmOUcrtzMSqNbDD5SM25MUhlTUKiB
 hTFq4L53gszBYfRPfh7Z5XgNVERULL5Zx0+WnVjZ7kUIp/wS3IQqxe81ChoFEsLTr8
 22UB9NN3OSVkuN/jRAzX+lKpugVGBHwOCjZBZukQ=
Received: from filter2.mymailcheap.com ([127.0.0.1])
 by localhost (filter2.mymailcheap.com [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id V9lVOgo6gApH; Tue,  6 Apr 2021 17:11:25 +0200 (CEST)
Received: from mail20.mymailcheap.com (mail20.mymailcheap.com [51.83.111.147])
 (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))
 (No client certificate requested)
 by filter2.mymailcheap.com (Postfix) with ESMTPS;
 Tue,  6 Apr 2021 17:11:25 +0200 (CEST)
Received: from [213.133.102.83] (ml.mymailcheap.com [213.133.102.83])
 by mail20.mymailcheap.com (Postfix) with ESMTP id C9EA3400B6;
 Tue,  6 Apr 2021 15:11:24 +0000 (UTC)
Authentication-Results: mail20.mymailcheap.com; dkim=pass (1024-bit key;
 unprotected) header.d=aosc.io header.i=@aosc.io header.b="mWwYCh9A";
 dkim-atps=neutral
AI-Spam-Status: Not processed
Received: from ice-e5v2.lan (unknown [59.41.163.135])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest
 SHA256) (No client certificate requested)
 by mail20.mymailcheap.com (Postfix) with ESMTPSA id 251F840C16;
 Tue,  6 Apr 2021 15:11:10 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=aosc.io; s=default;
 t=1617721874; bh=qb5gt5o7M9qjdJd67A3WHGZp/76w4s4FS6+u1VuEh/o=;
 h=From:To:Cc:Subject:Date:From;
 b=mWwYCh9AM8eRWm9hiEqirytotj/G/C1p9r2fd0zUxPhS0UQH+kw6L3RWZnsfmXAYq
 HmYFiM3ktIfwevqQw89tOi8c2ktb49iYOyHXkfi8hTZl1dNsJDS94uyzBiHYY+U7x5
 P0aTRRaL5C8ua2c1GedoPx06nrARO/KMEFy39rxI=
From: Icenowy Zheng <icenowy@aosc.io>
To: Simon Glass <sjg@chromium.org>, Kever Yang <kever.yang@rock-chips.com>,
 Frank Wang <frank.wang@rock-chips.com>,
 Jagan Teki <jagan@amarulasolutions.com>
Cc: u-boot@lists.denx.de,
	Icenowy Zheng <icenowy@aosc.io>
Subject: [PATCH] phy: rockchip: inno-usb2: fix hang when multiple controllers
 exit
Date: Tue,  6 Apr 2021 23:10:59 +0800
Message-Id: <20210406151059.1187379-1-icenowy@aosc.io>
X-Mailer: git-send-email 2.30.2
MIME-Version: 1.0
X-Rspamd-Server: mail20.mymailcheap.com
X-Spamd-Result: default: False [4.90 / 20.00]; RCVD_VIA_SMTP_AUTH(0.00)[];
 ARC_NA(0.00)[]; R_DKIM_ALLOW(0.00)[aosc.io:s=default];
 RECEIVED_SPAMHAUS_PBL(0.00)[59.41.163.135:received];
 FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[];
 R_MISSING_CHARSET(2.50)[]; TO_MATCH_ENVRCPT_ALL(0.00)[];
 MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[aosc.io];
 BROKEN_CONTENT_TYPE(1.50)[]; R_SPF_SOFTFAIL(0.00)[~all];
 RCPT_COUNT_FIVE(0.00)[6]; ML_SERVERS(-3.10)[213.133.102.83];
 DKIM_TRACE(0.00)[aosc.io:+]; MID_CONTAINS_FROM(1.00)[];
 RCVD_NO_TLS_LAST(0.10)[]; FROM_EQ_ENVFROM(0.00)[];
 MIME_TRACE(0.00)[0:+];
 ASN(0.00)[asn:24940, ipnet:213.133.96.0/19, country:DE];
 RCVD_COUNT_TWO(0.00)[2];
 HFILTER_HELO_BAREIP(3.00)[213.133.102.83,1]
X-Rspamd-Queue-Id: C9EA3400B6
X-BeenThere: u-boot@lists.denx.de
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: U-Boot discussion <u-boot.lists.denx.de>
List-Unsubscribe: <https://lists.denx.de/options/u-boot>,
 <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>
List-Archive: <https://lists.denx.de/pipermail/u-boot/>
List-Post: <mailto:u-boot@lists.denx.de>
List-Help: <mailto:u-boot-request@lists.denx.de?subject=help>
List-Subscribe: <https://lists.denx.de/listinfo/u-boot>,
 <mailto:u-boot-request@lists.denx.de?subject=subscribe>
Errors-To: u-boot-bounces@lists.denx.de
Sender: "U-Boot" <u-boot-bounces@lists.denx.de>
X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de
X-Virus-Status: Clean

The OHCI and EHCI controllers are both bound to the same PHY. They will
both do init and power_on operations when the controller is brought up
and both do power_off and exit when the controller is stopped. However,
the PHY uclass of U-Boot is not as sane as we thought -- they won't
maintain a status mark for PHYs, and thus the functions of the PHYs
could be called for multiple times. Calling init/power_on for multiple
times have no severe problems, however calling power_off/exit for
multiple times have a problem -- the first exit call will stop the PHY
clock, and power_off/exit calls after it still trying to write to PHY
registers. The write operation to PHY registers will fail because clock
is already stopped.

Adapt the count mechanism from phy-sun4i-usb to both init/exit and
power_on/power_off functions to phy-rockchip-inno-usb2 to fix this
problem. With this stopping USB controllers (manually or before booting
a kernel) will work.

Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Fixes: ac97a9ece14e ("phy: rockchip: Add Rockchip USB2PHY driver")
Tested-by: Peter Robinson <pbrobinson@gmail.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 62b8ba3a4a..be9cc99d90 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -62,6 +62,8 @@ struct rockchip_usb2phy {
 	void *reg_base;
 	struct clk phyclk;
 	const struct rockchip_usb2phy_cfg *phy_cfg;
+	int init_count;
+	int power_on_count;
 };

 static inline int property_enable(void *reg_base,
@@ -92,6 +94,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
 	struct rockchip_usb2phy *priv = dev_get_priv(parent);
 	const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);

+	priv->power_on_count++;
+	if (priv->power_on_count != 1)
+		return 0;
+
 	property_enable(priv->reg_base, &port_cfg->phy_sus, false);

 	/* waiting for the utmi_clk to become stable */
@@ -106,6 +112,10 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
 	struct rockchip_usb2phy *priv = dev_get_priv(parent);
 	const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);

+	priv->power_on_count--;
+	if (priv->power_on_count != 0)
+		return 0;
+
 	property_enable(priv->reg_base, &port_cfg->phy_sus, true);

 	return 0;
@@ -118,6 +128,10 @@ static int rockchip_usb2phy_init(struct phy *phy)
 	const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
 	int ret;

+	priv->init_count++;
+	if (priv->init_count != 1)
+		return 0;
+
 	ret = clk_enable(&priv->phyclk);
 	if (ret) {
 		dev_err(phy->dev, "failed to enable phyclk (ret=%d)\n", ret);
@@ -140,6 +154,10 @@ static int rockchip_usb2phy_exit(struct phy *phy)
 	struct udevice *parent = dev_get_parent(phy->dev);
 	struct rockchip_usb2phy *priv = dev_get_priv(parent);

+	priv->init_count--;
+	if (priv->init_count != 0)
+		return 0;
+
 	clk_disable(&priv->phyclk);

 	return 0;
@@ -212,6 +230,9 @@ static int rockchip_usb2phy_probe(struct udevice *dev)
 		return ret;
 	}

+	priv->power_on_count = 0;
+	priv->init_count = 0;
+
 	return 0;
 }


code:
Since /sys is unavailable in build environments, the list of available
TCP network interfaces cannot be obtained via /sys/class/net.  This patch
provides alternative code that uses the SIOCGIFCONF ioctl to get the
names of the available TCP network interfaces.

diff --git a/src/uct/tcp/tcp_iface.c b/src/uct/tcp/tcp_iface.c
index cad4a2709..7c1d2c9de 100644
--- a/src/uct/tcp/tcp_iface.c
+++ b/src/uct/tcp/tcp_iface.c
@@ -17,6 +17,8 @@
 #include <sys/poll.h>
 #include <netinet/tcp.h>
 #include <dirent.h>
+#include <net/if.h>
+#include <sys/ioctl.h>

 extern ucs_class_t UCS_CLASS_DECL_NAME(uct_tcp_iface_t);
@@ -586,6 +588,68 @@ static UCS_CLASS_DEFINE_NEW_FUNC(uct_tcp_iface_t, uct_iface_t, uct_md_h,
                                  uct_worker_h, const uct_iface_params_t*,
                                  const uct_iface_config_t*);

+/* Fetch information about available network devices through an ioctl.  */
+static ucs_status_t query_devices_ioctl(uct_md_h md,
+					uct_tl_device_resource_t **tl_devices_p,
+					unsigned *num_tl_devices_p)
+{
+    int sock, err, i;
+    uct_tl_device_resource_t *resources, *tmp;
+    unsigned num_resources;
+    ucs_status_t status;
+    struct ifconf conf;
+    struct ifreq reqs[10];
+
+    conf.ifc_len = sizeof reqs;
+    conf.ifc_req = reqs;
+
+    sock = socket(SOCK_STREAM, AF_INET, 0);
+    if (sock < 0) {
+	ucs_error("socket(2) failed: %m");
+	status = UCS_ERR_IO_ERROR;
+	goto out;
+    }
+
+    err = ioctl(sock, SIOCGIFCONF, &conf);
+    if (err < 0) {
+	ucs_error("SIOCGIFCONF ioctl failed: %m");
+	status = UCS_ERR_IO_ERROR;
+	goto out;
+    }
+
+    resources     = NULL;
+    num_resources = 0;
+    for (i = 0; i < conf.ifc_len / sizeof(struct ifreq); i++) {
+	const char *name = reqs[i].ifr_name;
+
+        if (!ucs_netif_is_active(name)) {
+            continue;
+        }
+
+        tmp = ucs_realloc(resources, sizeof(*resources) * (num_resources + 1),
+                          "tcp resources");
+        if (tmp == NULL) {
+            ucs_free(resources);
+            status = UCS_ERR_NO_MEMORY;
+            goto out;
+        }
+        resources = tmp;
+
+        ucs_snprintf_zero(resources[i].name, sizeof(resources[i].name),
+                          "%s", name);
+        resources[i].type = UCT_DEVICE_TYPE_NET;
+        ++num_resources;
+    }
+
+    *num_tl_devices_p = num_resources;
+    *tl_devices_p     = resources;
+    status            = UCS_OK;
+
+out:
+    if (sock >= 0) close(sock);
+    return status;
+}
+
 ucs_status_t uct_tcp_query_devices(uct_md_h md,
                                    uct_tl_device_resource_t **devices_p,
                                    unsigned *num_devices_p)
@@ -599,9 +663,9 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md,

     dir = opendir(netdev_dir);
     if (dir == NULL) {
-        ucs_error("opendir(%s) failed: %m", netdev_dir);
-        status = UCS_ERR_IO_ERROR;
-        goto out;
+	/* When /sys is unavailable, as can be the case in a container,
+	 * resort to a good old 'ioctl'.  */
+	return query_devices_ioctl(md, devices_p, num_devices_p);
     }

     devices     = NULL;
@@ -655,7 +719,6 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md,

 out_closedir:
     closedir(dir);
-out:
     return status;
 }


code:
Remove the support for Unity's appindicator.

diff -Naur udiskie-2.0.4/completions/zsh/_udiskie udiskie-2.0.4-new/completions/zsh/_udiskie
--- udiskie-2.0.4/completions/zsh/_udiskie	2020-01-21 01:12:40.000000000 +0100
+++ udiskie-2.0.4-new/completions/zsh/_udiskie	2020-01-23 10:15:46.956141667 +0100
@@ -18,8 +18,6 @@
     '(-a)'{-A,--no-automount}"[disable automounting]"
     '(-N)'{-n,--notify}"[show popup notifications]"
     '(-n)'{-N,--no-notify}"[disable notifications]"
-    '(--no-appindicator)'--appindicator"[use appindicator for status icon]"
-    '(--appindicator)'--no-appindicator"[don't use appindicator]"
     '(-T -s)'{-t,--tray}"[show tray icon]"
     '(-T -t)'{-s,--smart-tray}"[auto hide tray icon]"
     '(-t -s)'{-T,--no-tray}"[disable tray icon]"
diff -Naur udiskie-2.0.4/doc/udiskie.8.txt udiskie-2.0.4-new/doc/udiskie.8.txt
--- udiskie-2.0.4/doc/udiskie.8.txt	2020-01-21 01:12:40.000000000 +0100
+++ udiskie-2.0.4-new/doc/udiskie.8.txt	2020-01-23 10:16:12.636290647 +0100
@@ -92,12 +92,6 @@
 *--no-terminal*::
 	Disable terminal action.

-*--appindicator*::
-	Use AppIndicator3 for the status icon. Use this on Ubuntu/Unity if no icon is shown.
-
-*--no-appindicator*::
-	Use Gtk.StatusIcon for the status icon (default).
-
 *--password-cache MINUTES*::
 	Cache passwords for LUKS partitions and set the timeout.

diff -Naur udiskie-2.0.4/udiskie/appindicator.py udiskie-2.0.4-new/udiskie/appindicator.py
--- udiskie-2.0.4/udiskie/appindicator.py	2020-01-21 01:12:40.000000000 +0100
+++ udiskie-2.0.4-new/udiskie/appindicator.py	1970-01-01 01:00:00.000000000 +0100
@@ -1,61 +0,0 @@
-"""
-Status icon using AppIndicator3.
-"""
-
-from gi.repository import Gtk
-from gi.repository import AppIndicator3
-
-from .async_ import Future
-
-
-class AppIndicatorIcon:
-
-    """
-    Show status icon using AppIndicator as backend. Replaces
-    `udiskie.tray.StatusIcon` on ubuntu/unity.
-    """
-
-    def __init__(self, menumaker, _icons):
-        self._maker = menumaker
-        self._menu = Gtk.Menu()
-        self._indicator = AppIndicator3.Indicator.new(
-            'udiskie',
-            _icons.get_icon_name('media'),
-            AppIndicator3.IndicatorCategory.HARDWARE)
-        self._indicator.set_status(AppIndicator3.IndicatorStatus.PASSIVE)
-        self._indicator.set_menu(self._menu)
-        # Get notified before menu is shown, see:
-        # https://bugs.launchpad.net/screenlets/+bug/522152/comments/15
-        dbusmenuserver = self._indicator.get_property('dbus-menu-server')
-        self._dbusmenuitem = dbusmenuserver.get_property('root-node')
-        self._conn = self._dbusmenuitem.connect('about-to-show', self._on_show)
-        self.task = Future()
-        menumaker._quit_action = self.destroy
-        # Populate menu initially, so libdbusmenu does not ignore the
-        # 'about-to-show':
-        self._maker(self._menu)
-
-    def destroy(self):
-        self.show(False)
-        self._dbusmenuitem.disconnect(self._conn)
-        self.task.set_result(True)
-
-    @property
-    def visible(self):
-        status = self._indicator.get_status()
-        return status == AppIndicator3.IndicatorStatus.ACTIVE
-
-    def show(self, show=True):
-        if show == self.visible:
-            return
-        status = (AppIndicator3.IndicatorStatus.ACTIVE if show else
-                  AppIndicator3.IndicatorStatus.PASSIVE)
-        self._indicator.set_status(status)
-
-    def _on_show(self, menu):
-        # clear menu:
-        for item in self._menu.get_children():
-            self._menu.remove(item)
-        # repopulate:
-        self._maker(self._menu)
-        self._menu.show_all()
diff -Naur udiskie-2.0.4/udiskie/cli.py udiskie-2.0.4-new/udiskie/cli.py
--- udiskie-2.0.4/udiskie/cli.py	2020-01-21 01:12:40.000000000 +0100
+++ udiskie-2.0.4-new/udiskie/cli.py	2020-01-23 10:17:13.064810617 +0100
@@ -287,9 +287,6 @@
         -T, --no-tray                           Disable tray icon
         -m MENU, --menu MENU                    Tray menu [flat/nested]

-        --appindicator                          Use appindicator for status icon
-        --no-appindicator                       Don't use appindicator
-
         --password-cache MINUTES                Set password cache timeout
         --no-password-cache                     Disable password cache

@@ -312,7 +309,6 @@
         'notify': True,
         'tray': False,
         'menu': 'flat',
-        'appindicator': False,
         'file_manager': 'xdg-open',
         'terminal': '',
         'password_prompt': 'builtin:gui',
@@ -328,7 +324,6 @@
             '--no-tray': False,
             '--smart-tray': 'auto'}),
         'menu': Value('--menu'),
-        'appindicator': Switch('appindicator'),
         'file_manager': OptionalValue('--file-manager'),
         'password_prompt': OptionalValue('--password-prompt'),
         'password_cache': OptionalValue('--password-cache'),
@@ -459,11 +454,7 @@

         menu_maker = udiskie.tray.UdiskieMenu(self, icons, actions, flat,
                                               config.quickmenu_actions)
-        if options['appindicator']:
-            import udiskie.appindicator
-            TrayIcon = udiskie.appindicator.AppIndicatorIcon
-        else:
-            TrayIcon = udiskie.tray.TrayIcon
+        TrayIcon = udiskie.tray.TrayIcon
         trayicon = TrayIcon(menu_maker, icons)
         return udiskie.tray.UdiskieStatusIcon(trayicon, menu_maker, smart)

diff -Naur udiskie-2.0.4/udiskie.egg-info/SOURCES.txt udiskie-2.0.4-new/udiskie.egg-info/SOURCES.txt
--- udiskie-2.0.4/udiskie.egg-info/SOURCES.txt	2020-01-21 01:12:41.000000000 +0100
+++ udiskie-2.0.4-new/udiskie.egg-info/SOURCES.txt	2020-01-23 10:17:50.657205798 +0100
@@ -25,7 +25,6 @@
 test/test_cache.py
 test/test_match.py
 udiskie/__init__.py
-udiskie/appindicator.py
 udiskie/async_.py
 udiskie/automount.py
 udiskie/cache.py
@@ -47,4 +46,4 @@
 udiskie.egg-info/entry_points.txt
 udiskie.egg-info/requires.txt
 udiskie.egg-info/top_level.txt
-udiskie.egg-info/zip-safe
\ Pas de fin de ligne à la fin du fichier
+udiskie.egg-info/zip-safe


code:
Look for extensions in $CHROMIUM_EXTENSION_DIRECTORY instead of
/usr/share/chromium/extensions.

--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -4,6 +4,7 @@

 #include "chrome/common/chrome_paths.h"

+#include "base/environment.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/native_library.h"
@@ -511,7 +512,13 @@
 #endif
 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
     case chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS: {
-      cur = base::FilePath(kFilepathSinglePrefExtensions);
+      std::unique_ptr<base::Environment> environment(base::Environment::Create());
+      std::string extension_dir;
+      if (environment->GetVar("CHROMIUM_EXTENSION_DIRECTORY", &extension_dir)) {
+        cur = base::FilePath(extension_dir);
+      } else {
+        cur = base::FilePath(kFilepathSinglePrefExtensions);
+      }
       break;
     }
 #endif


code:
This patch is taken from the opam repository:
https://github.com/ocaml/opam-repository/blob/master/packages/unison/unison.2.51.2/files/ocaml48.patch

It fixes compatibility with changes introduced in OCaml 4.08.

diff --git a/src/Makefile.OCaml b/src/Makefile.OCaml
index 7cefa2e..378fc8b 100644
--- a/src/Makefile.OCaml
+++ b/src/Makefile.OCaml
@@ -272,7 +272,7 @@ endif

 # Gtk GUI
 ifeq ($(UISTYLE), gtk)
-  CAMLFLAGS+=-I +lablgtk
+  CAMLFLAGS+=-I $(LABLGTKLIB)
   OCAMLOBJS+=pixmaps.cmo uigtk.cmo linkgtk.cmo
   OCAMLLIBS+=lablgtk.cma
 endif
@@ -282,7 +282,7 @@ OCAMLFIND := $(shell command -v ocamlfind 2> /dev/null)

 ifeq ($(UISTYLE), gtk2)
   ifndef OCAMLFIND
-    CAMLFLAGS+=-I +lablgtk2
+    CAMLFLAGS+=-I $(LABLGTK2LIB)
   else
     CAMLFLAGS+=$(shell $(OCAMLFIND) query -i-format lablgtk2 )
   endif
diff --git a/src/files.ml b/src/files.ml
index 5ff1881..1d1fbcc 100644
--- a/src/files.ml
+++ b/src/files.ml
@@ -734,7 +734,7 @@ let get_files_in_directory dir =
   with End_of_file ->
     dirh.System.closedir ()
   end;
-  Sort.list (<) !files
+  List.sort String.compare !files

 let ls dir pattern =
   Util.convertUnixErrorsToTransient
diff --git a/src/recon.ml b/src/recon.ml
index 2c619bb..2412c18 100644
--- a/src/recon.ml
+++ b/src/recon.ml
@@ -661,8 +661,8 @@ let rec reconcile

 (* Sorts the paths so that they will be displayed in order                   *)
 let sortPaths pathUpdatesList =
-  Sort.list
-    (fun (p1, _) (p2, _) -> Path.compare p1 p2 <= 0)
+  List.sort
+    Path.compare
     pathUpdatesList

 let rec enterPath p1 p2 t =
diff --git a/src/system/system_generic.ml b/src/system/system_generic.ml
index 453027d..c2288b8 100755
--- a/src/system/system_generic.ml
+++ b/src/system/system_generic.ml
@@ -47,7 +47,7 @@ let open_out_gen = open_out_gen
 let chmod = Unix.chmod
 let chown = Unix.chown
 let utimes = Unix.utimes
-let link = Unix.link
+let link s d = Unix.link s d
 let openfile = Unix.openfile
 let opendir f =
   let h = Unix.opendir f in
diff --git a/src/uigtk2.ml b/src/uigtk2.ml
index fbc5d8f..4e82cc2 100644
--- a/src/uigtk2.ml
+++ b/src/uigtk2.ml
@@ -94,7 +94,7 @@ let icon =
 let icon =
   let p = GdkPixbuf.create ~width:48 ~height:48 ~has_alpha:true () in
   Gpointer.blit
-    (Gpointer.region_of_string Pixmaps.icon_data) (GdkPixbuf.get_pixels p);
+    (Gpointer.region_of_bytes Pixmaps.icon_data) (GdkPixbuf.get_pixels p);
   p

 let leftPtrWatch =


code:
From: Tobias Geerinckx-Rice <me@tobias.gr>
Date: Wed, 19 Aug 2020 22:58:32 +0200
Subject: [PATCH] gnu: unknown-horizons: Replace ‘dist’ with ‘distro’.

This fixes builds with Python >= 3.8.  Taken verbatim from upstream[0].

[0]: https://github.com/unknown-horizons/unknown-horizons/commit/c40fb866f3f72ac1049d6fa7859b17d8a48fe9e1

From c40fb866f3f72ac1049d6fa7859b17d8a48fe9e1 Mon Sep 17 00:00:00 2001
From: MarkusHackspacher <hackspacher@gmx.de>
Date: Thu, 18 Jul 2019 11:46:39 +0200
Subject: [PATCH] replace deprecated to distro package

---
 requirements.txt | 1 +
 setup.py         | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/requirements.txt b/requirements.txt
index a5edf794fb..b58179bfa8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,7 @@
 coverage==4.4.1
 coveralls==1.1
 crayons==0.1.2
+distro
 future==0.16.0
 greenlet==0.4.15
 isort==4.3.4
diff --git a/setup.py b/setup.py
index 6d63a5ce15..6a237a8749 100755
--- a/setup.py
+++ b/setup.py
@@ -32,6 +32,8 @@
 from distutils.spawn import find_executable
 from shutil import copytree, rmtree

+import distro
+
 import horizons
 from horizons.constants import VERSION
 from horizons.ext import polib
@@ -39,7 +41,7 @@
 # Ensure we are in the correct directory
 os.chdir(os.path.realpath(os.path.dirname(__file__)))

-if platform.dist()[0].lower() in ('debian', 'ubuntu'):
+if distro.linux_distribution(full_distribution_name=False)[0] in ('debian', 'mint', 'ubuntu'):
 	executable_path = 'games'
 else:
 	executable_path = 'bin'


code:
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;


code:
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


code:
From: sms
Subject: Fix CVE-2014-8139: CRC32 verification heap-based overflow
Bug-Debian: http://bugs.debian.org/773722

--- a/extract.c
+++ b/extract.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2014 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.
@@ -298,6 +298,8 @@
 #ifndef SFX
    static ZCONST char Far InconsistEFlength[] = "bad extra-field entry:\n \
      EF block length (%u bytes) exceeds remaining EF data (%u bytes)\n";
+   static ZCONST char Far TooSmallEFlength[] = "bad extra-field entry:\n \
+     EF block length (%u bytes) invalid (< %d)\n";
    static ZCONST char Far InvalidComprDataEAs[] =
      " invalid compressed data for EAs\n";
 #  if (defined(WIN32) && defined(NTSD_EAS))
@@ -2023,7 +2025,8 @@
         ebID = makeword(ef);
         ebLen = (unsigned)makeword(ef+EB_LEN);

-        if (ebLen > (ef_len - EB_HEADSIZE)) {
+        if (ebLen > (ef_len - EB_HEADSIZE))
+        {
            /* Discovered some extra field inconsistency! */
             if (uO.qflag)
                 Info(slide, 1, ((char *)slide, "%-22s ",
@@ -2032,6 +2035,16 @@
               ebLen, (ef_len - EB_HEADSIZE)));
             return PK_ERR;
         }
+        else if (ebLen < EB_HEADSIZE)
+        {
+            /* Extra block length smaller than header length. */
+            if (uO.qflag)
+                Info(slide, 1, ((char *)slide, "%-22s ",
+                  FnFilter1(G.filename)));
+            Info(slide, 1, ((char *)slide, LoadFarString(TooSmallEFlength),
+              ebLen, EB_HEADSIZE));
+            return PK_ERR;
+        }

         switch (ebID) {
             case EF_OS2:


code:
From: sms
Subject: Fix CVE-2014-8140: out-of-bounds write issue in test_compr_eb()
Bug-Debian: http://bugs.debian.org/773722

--- a/extract.c
+++ b/extract.c
@@ -2234,10 +2234,17 @@
     if (compr_offset < 4)                /* field is not compressed: */
         return PK_OK;                    /* do nothing and signal OK */

+    /* Return no/bad-data error status if any problem is found:
+     *    1. eb_size is too small to hold the uncompressed size
+     *       (eb_ucsize).  (Else extract eb_ucsize.)
+     *    2. eb_ucsize is zero (invalid).  2014-12-04 SMS.
+     *    3. eb_ucsize is positive, but eb_size is too small to hold
+     *       the compressed data header.
+     */
     if ((eb_size < (EB_UCSIZE_P + 4)) ||
-        ((eb_ucsize = makelong(eb+(EB_HEADSIZE+EB_UCSIZE_P))) > 0L &&
-         eb_size <= (compr_offset + EB_CMPRHEADLEN)))
-        return IZ_EF_TRUNC;               /* no compressed data! */
+     ((eb_ucsize = makelong( eb+ (EB_HEADSIZE+ EB_UCSIZE_P))) == 0L) ||
+     ((eb_ucsize > 0L) && (eb_size <= (compr_offset + EB_CMPRHEADLEN))))
+        return IZ_EF_TRUNC;             /* no/bad compressed data! */

     if (
 #ifdef INT_16BIT


code:
From: sms
Subject: Fix CVE-2014-8141: out-of-bounds read issues in getZip64Data()
Bug-Debian: http://bugs.debian.org/773722

--- a/fileio.c
+++ b/fileio.c
@@ -176,6 +176,8 @@
 #endif
 static ZCONST char Far ExtraFieldTooLong[] =
   "warning:  extra field too long (%d).  Ignoring...\n";
+static ZCONST char Far ExtraFieldCorrupt[] =
+  "warning:  extra field (type: 0x%04x) corrupt.  Continuing...\n";

 #ifdef WINDLL
    static ZCONST char Far DiskFullQuery[] =
@@ -2295,7 +2297,12 @@
             if (readbuf(__G__ (char *)G.extra_field, length) == 0)
                 return PK_EOF;
             /* Looks like here is where extra fields are read */
-            getZip64Data(__G__ G.extra_field, length);
+            if (getZip64Data(__G__ G.extra_field, length) != PK_COOL)
+            {
+                Info(slide, 0x401, ((char *)slide,
+                 LoadFarString( ExtraFieldCorrupt), EF_PKSZ64));
+                error = PK_WARN;
+            }
 #ifdef UNICODE_SUPPORT
             G.unipath_filename = NULL;
             if (G.UzO.U_flag < 2) {
--- a/process.c
+++ b/process.c
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 1990-2009 Info-ZIP.  All rights reserved.
+  Copyright (c) 1990-2014 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.
@@ -1901,48 +1901,82 @@
     and a 4-byte version of disk start number.
     Sets both local header and central header fields.  Not terribly clever,
     but it means that this procedure is only called in one place.
+
+    2014-12-05 SMS.
+    Added checks to ensure that enough data are available before calling
+    makeint64() or makelong().  Replaced various sizeof() values with
+    simple ("4" or "8") constants.  (The Zip64 structures do not depend
+    on our variable sizes.)  Error handling is crude, but we should now
+    stay within the buffer.
   ---------------------------------------------------------------------------*/

+#define Z64FLGS 0xffff
+#define Z64FLGL 0xffffffff
+
     if (ef_len == 0 || ef_buf == NULL)
         return PK_COOL;

     Trace((stderr,"\ngetZip64Data: scanning extra field of length %u\n",
       ef_len));

-    while (ef_len >= EB_HEADSIZE) {
+    while (ef_len >= EB_HEADSIZE)
+    {
         eb_id = makeword(EB_ID + ef_buf);
         eb_len = makeword(EB_LEN + ef_buf);

-        if (eb_len > (ef_len - EB_HEADSIZE)) {
-            /* discovered some extra field inconsistency! */
+        if (eb_len > (ef_len - EB_HEADSIZE))
+        {
+            /* Extra block length exceeds remaining extra field length. */
             Trace((stderr,
               "getZip64Data: block length %u > rest ef_size %u\n", eb_len,
               ef_len - EB_HEADSIZE));
             break;
         }
-        if (eb_id == EF_PKSZ64) {
-
+        if (eb_id == EF_PKSZ64)
+        {
           int offset = EB_HEADSIZE;

-          if (G.crec.ucsize == 0xffffffff || G.lrec.ucsize == 0xffffffff){
-            G.lrec.ucsize = G.crec.ucsize = makeint64(offset + ef_buf);
-            offset += sizeof(G.crec.ucsize);
+          if ((G.crec.ucsize == Z64FLGL) || (G.lrec.ucsize == Z64FLGL))
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
+            G.crec.ucsize = G.lrec.ucsize = makeint64(offset + ef_buf);
+            offset += 8;
           }
-          if (G.crec.csize == 0xffffffff || G.lrec.csize == 0xffffffff){
-            G.csize = G.lrec.csize = G.crec.csize = makeint64(offset + ef_buf);
-            offset += sizeof(G.crec.csize);
+
+          if ((G.crec.csize == Z64FLGL) || (G.lrec.csize == Z64FLGL))
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
+            G.csize = G.crec.csize = G.lrec.csize = makeint64(offset + ef_buf);
+            offset += 8;
           }
-          if (G.crec.relative_offset_local_header == 0xffffffff){
+
+          if (G.crec.relative_offset_local_header == Z64FLGL)
+          {
+            if (offset+ 8 > ef_len)
+              return PK_ERR;
+
             G.crec.relative_offset_local_header = makeint64(offset + ef_buf);
-            offset += sizeof(G.crec.relative_offset_local_header);
+            offset += 8;
           }
-          if (G.crec.disk_number_start == 0xffff){
+
+          if (G.crec.disk_number_start == Z64FLGS)
+          {
+            if (offset+ 4 > ef_len)
+              return PK_ERR;
+
             G.crec.disk_number_start = (zuvl_t)makelong(offset + ef_buf);
-            offset += sizeof(G.crec.disk_number_start);
+            offset += 4;
           }
+#if 0
+          break;                /* Expect only one EF_PKSZ64 block. */
+#endif /* 0 */
         }

-        /* Skip this extra field block */
+        /* Skip this extra field block. */
         ef_buf += (eb_len + EB_HEADSIZE);
         ef_len -= (eb_len + EB_HEADSIZE);
     }


code:
Copied from Fedora.

http://pkgs.fedoraproject.org/cgit/unzip.git/plain/unzip-6.0-overflow.patch?id=d18f821e

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) ||


code:
Copied from Debian.

From: Petr Stodulka <pstodulk@redhat.com>
Date: Mon, 14 Sep 2015 18:23:17 +0200
Subject: Upstream fix for heap overflow
Bug-Debian: https://bugs.debian.org/802162
Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
Origin: https://bugzilla.redhat.com/attachment.cgi?id=1073002
Forwarded: yes

---
 crypt.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--- a/crypt.c
+++ b/crypt.c
@@ -465,7 +465,17 @@
     GLOBAL(pInfo->encrypted) = FALSE;
     defer_leftover_input(__G);
     for (n = 0; n < RAND_HEAD_LEN; n++) {
-        b = NEXTBYTE;
+        /* 2012-11-23 SMS.  (OUSPG report.)
+         * Quit early if compressed size < HEAD_LEN.  The resulting
+         * error message ("unable to get password") could be improved,
+         * but it's better than trying to read nonexistent data, and
+         * then continuing with a negative G.csize.  (See
+         * fileio.c:readbyte()).
+         */
+        if ((b = NEXTBYTE) == (ush)EOF)
+        {
+            return PK_ERR;
+        }
         h[n] = (uch)b;
         Trace((stdout, " (%02x)", h[n]));
     }


code:
Copied from Debian.

From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 14 Sep 2015 18:24:56 +0200
Subject: fix infinite loop when extracting empty bzip2 data
Bug-Debian: https://bugs.debian.org/802160
Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1260944
Origin: other, https://bugzilla.redhat.com/attachment.cgi?id=1073339

---
 extract.c | 6 ++++++
 1 file changed, 6 insertions(+)

--- a/extract.c
+++ b/extract.c
@@ -2728,6 +2728,12 @@
     int repeated_buf_err;
     bz_stream bstrm;

+    if (G.incnt <= 0 && G.csize <= 0L) {
+        /* avoid an infinite loop */
+        Trace((stderr, "UZbunzip2() got empty input\n"));
+        return 2;
+    }
+
 #if (defined(DLL) && !defined(NO_SLIDE_REDIR))
     if (G.redirect_slide)
         wsize = G.redirect_size, redirSlide = G.redirect_buffer;


code:
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


code:
--- 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);


code:
--- 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"),


code:
Copied from Debian.

From: Santiago Vila <sanvila@debian.org>
Subject: zipinfo.c: Do not crash when hostver byte is >= 100

--- a/zipinfo.c
+++ b/zipinfo.c
@@ -2114,7 +2114,7 @@
             else
                 attribs[9] = (xattr & UNX_ISVTX)? 'T' : '-';  /* T==undefined */

-            sprintf(&attribs[12], "%u.%u", hostver/10, hostver%10);
+            sprintf(&attribs[11], "%2u.%u", hostver/10, hostver%10);
             break;

     } /* end switch (hostnum: external attributes format) */


code:
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


code:
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;


code:
Copied from Fedora.

http://pkgs.fedoraproject.org/cgit/unzip.git/plain/unzip-6.0-attribs-overflow.patch?id=d18f821e

diff -up unzip60/zipinfo.c.attribs-overflow unzip60/zipinfo.c
--- unzip60/zipinfo.c.attribs-overflow	2009-11-30 09:55:39.000000000 +0100
+++ unzip60/zipinfo.c	2009-11-30 09:56:42.844263244 +0100
@@ -1881,7 +1881,7 @@ static int zi_short(__G)   /* return PK-
 #endif
     int         k, error, error_in_archive=PK_COOL;
     unsigned    hostnum, hostver, methid, methnum, xattr;
-    char        *p, workspace[12], attribs[16];
+    char        *p, workspace[12], attribs[17];
     char        methbuf[5];
     static ZCONST char dtype[5]="NXFS"; /* normal, maximum, fast, superfast */
     static ZCONST char Far os[NUM_HOSTS+1][4] = {


code:
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;
 }


code:
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 */