Add fix for gpgtar windows codepage handling
authorAndre Heinecke <aheinecke@intevation.de>
Mon, 17 Nov 2014 13:58:24 +0000 (14:58 +0100)
committerAndre Heinecke <aheinecke@intevation.de>
Mon, 17 Nov 2014 13:58:24 +0000 (14:58 +0100)
    * NEWS: Mention this.
    * patches/gnupg2-2.0.26/
    0005-Fix-gpgtar-8-bit-encoding-handling-on-Win32.patch: New.

--
    See issue1624 for details on this patch.

NEWS
patches/gnupg2-2.0.26/0005-Fix-gpgtar-8-bit-encoding-handling-on-Win32.patch [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index 9ec9263..2c6bfa2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,15 @@ Noteworthy changes in version 2.2.3 (unreleased)
      Dateinamen anzugeben erzeugt nun eine Warnung und wird im
      Batch modus verhindert.
 
+(en) Tar archives can now include files and folders that use
+     special characters (e.g. umlauts) which can be encoded
+     in the native Windows 8-Bit codepage.
+
+(de) Tar Archive können nun Dateien und Ordner beinhalten deren
+     Namen Sonderzeichen (z.B. Umlaute) enthalten welche in der
+     nativen Windows 8-Bit Zeichenkodierung kodiert werden
+     können.
+
 ~~~~~~~~~~~~~~~
 GnuPG:          2.0.26
 Kleopatra:      2.2.0-gitac229d2
diff --git a/patches/gnupg2-2.0.26/0005-Fix-gpgtar-8-bit-encoding-handling-on-Win32.patch b/patches/gnupg2-2.0.26/0005-Fix-gpgtar-8-bit-encoding-handling-on-Win32.patch
new file mode 100755 (executable)
index 0000000..2d4b70c
--- /dev/null
@@ -0,0 +1,187 @@
+#! /bin/sh
+patch -p1 -l -f $* < $0
+exit $?
+
+From 70c387b523fa115f02a7d545fb1f503e9b86f913 Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke@intevation.de>
+Date: Fri, 24 Oct 2014 18:05:29 +0200
+Subject: [PATCH] Fix gpgtar 8 bit encoding handling on Win32
+
+  * tools/gpgtar-create.c (fillup_entry_w32, scan_directory): Convert
+    to and from local encoding.
+  * tools/gpgtar.c (wchar_to_cp, cp_to_wchar): New. Generalized
+    conversion functions.
+    (utf8_to_wchar, wchar_to_utf8): Removed.
+    (wchar_to_native, native_to_wchar): New.
+  * tools/gpgtar.h: Update accordingly.
+
+--
+
+  Gpgtar needs to handle filenames in the local 8 bit encoding on
+  Windows as it uses the 8 bit file io functions.
+
+  GnuPG-bug-id: 1624, 1746
+---
+ tools/gpgtar-create.c | 10 +++++-----
+ tools/gpgtar.c        | 48 ++++++++++++++++++++++++++++++++++--------------
+ tools/gpgtar.h        |  4 ++--
+ 3 files changed, 41 insertions(+), 21 deletions(-)
+
+diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c
+index 09587e4..b586243 100644
+--- a/tools/gpgtar-create.c
++++ b/tools/gpgtar-create.c
+@@ -72,13 +72,13 @@ fillup_entry_w32 (tar_header_t hdr)
+   for (p=hdr->name; *p; p++)
+     if (*p == '/')
+       *p = '\\';
+-  wfname = utf8_to_wchar (hdr->name);
++  wfname = native_to_wchar (hdr->name);
+   for (p=hdr->name; *p; p++)
+     if (*p == '\\')
+       *p = '/';
+   if (!wfname)
+     {
+-      log_error ("error utf8-ing `%s': %s\n", hdr->name, w32_strerror (-1));
++      log_error ("error converting `%s': %s\n", hdr->name, w32_strerror (-1));
+       return gpg_error_from_syserror ();
+     }
+   if (!GetFileAttributesExW (wfname, GetFileExInfoStandard, &fad))
+@@ -299,7 +299,7 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
+     for (p=fname; *p; p++)
+       if (*p == '/')
+         *p = '\\';
+-    wfname = utf8_to_wchar (fname);
++    wfname = native_to_wchar (fname);
+     xfree (fname);
+     if (!wfname)
+       {
+@@ -322,11 +322,11 @@ scan_directory (const char *dname, scanctrl_t scanctrl)
+
+   do
+     {
+-      char *fname = wchar_to_utf8 (fi.cFileName);
++      char *fname = wchar_to_native (fi.cFileName);
+       if (!fname)
+         {
+           err = gpg_error_from_syserror ();
+-          log_error ("error utf8-ing filename: %s\n", w32_strerror (-1));
++          log_error ("error converting filename: %s\n", w32_strerror (-1));
+           break;
+         }
+       for (p=fname; *p; p++)
+diff --git a/tools/gpgtar.c b/tools/gpgtar.c
+index f88964f..644cdd0 100644
+--- a/tools/gpgtar.c
++++ b/tools/gpgtar.c
+@@ -465,18 +465,19 @@ gnupg_mkdir (const char *name, const char *modestr)
+ #endif
+ }
+
++
+ #ifdef HAVE_W32_SYSTEM
+-/* Return a malloced string encoded in UTF-8 from the wide char input
+-   string STRING.  Caller must free this value.  Returns NULL and sets
+-   ERRNO on failure.  Calling this function with STRING set to NULL is
+-   not defined.  */
+-char *
+-wchar_to_utf8 (const wchar_t *string)
++/* Return a malloced string encoded for the codepage CODEPAGE from the wide
++   char input string STRING.  Caller must free this value.  Returns NULL
++   and sets ERRNO on failure.  Calling this function with STRING set to
++   NULL is not defined.  */
++static char *
++wchar_to_cp (const wchar_t *string, unsigned int codepage)
+ {
+   int n;
+   char *result;
+
+-  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
++  n = WideCharToMultiByte (codepage, 0, string, -1, NULL, 0, NULL, NULL);
+   if (n < 0)
+     {
+       errno = EINVAL;
+@@ -487,7 +488,7 @@ wchar_to_utf8 (const wchar_t *string)
+   if (!result)
+     return NULL;
+
+-  n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
++  n = WideCharToMultiByte (codepage, 0, string, -1, result, n, NULL, NULL);
+   if (n < 0)
+     {
+       xfree (result);
+@@ -497,19 +498,18 @@ wchar_to_utf8 (const wchar_t *string)
+   return result;
+ }
+
+-
+-/* Return a malloced wide char string from an UTF-8 encoded input
++/* Return a malloced wide char string from an CODEPAGE encoded input
+    string STRING.  Caller must free this value.  Returns NULL and sets
+    ERRNO on failure.  Calling this function with STRING set to NULL is
+    not defined.  */
+-wchar_t *
+-utf8_to_wchar (const char *string)
++static wchar_t*
++cp_to_wchar (const char *string, unsigned int codepage)
+ {
+   int n;
+   size_t nbytes;
+   wchar_t *result;
+
+-  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
++  n = MultiByteToWideChar (codepage, 0, string, -1, NULL, 0);
+   if (n < 0)
+     {
+       errno = EINVAL;
+@@ -526,7 +526,7 @@ utf8_to_wchar (const char *string)
+   if (!result)
+     return NULL;
+
+-  n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
++  n = MultiByteToWideChar (codepage, 0, string, -1, result, n);
+   if (n < 0)
+     {
+       free (result);
+@@ -535,4 +535,24 @@ utf8_to_wchar (const char *string)
+     }
+   return result;
+ }
++
++/* Return a malloced string encoded in the active code page from the
++   wide char input string STRING.  Caller must free this value.
++   Returns NULL and sets ERRNO on failure.
++   Calling this function with STRING set to NULL is not defined.  */
++char *
++wchar_to_native (const wchar_t *string)
++{
++  return wchar_to_cp (string, CP_ACP);
++}
++
++/* Return a malloced wide char string from an UTF-8 encoded input
++   string STRING.  Caller must free this value.  Returns NULL and sets
++   ERRNO on failure.  Calling this function with STRING set to NULL is
++   not defined.  */
++wchar_t *
++native_to_wchar (const char *string)
++{
++  return cp_to_wchar(string, CP_ACP);
++}
+ #endif /*HAVE_W32_SYSTEM*/
+diff --git a/tools/gpgtar.h b/tools/gpgtar.h
+index 5790894..8c0de85 100644
+--- a/tools/gpgtar.h
++++ b/tools/gpgtar.h
+@@ -113,8 +113,8 @@ gpg_error_t write_record (estream_t stream, const void *record);
+
+ int gnupg_mkdir (const char *name, const char *modestr);
+ #ifdef HAVE_W32_SYSTEM
+-char *wchar_to_utf8 (const wchar_t *string);
+-wchar_t *utf8_to_wchar (const char *string);
++char *wchar_to_native (const wchar_t *string);
++wchar_t *native_to_wchar (const char *string);
+ #endif
+
+ /*-- gpgtar-create.c --*/
+--
+1.9.1