[git] GpgOL - branch, master, updated. gpgol-2.2.0-61-g1e699af

by Andre Heinecke cvs at cvs.gnupg.org
Tue Jul 17 16:57:25 CEST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG extension for MS Outlook".

The branch, master has been updated
       via  1e699afd9531c6d0e4d7bde3efcdf5a323fc02a7 (commit)
       via  1ff79faa4adb181a266531ee39166d8a4af459c1 (commit)
      from  d719c98902827d07af7619c9d19b4f2752bd0862 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 1e699afd9531c6d0e4d7bde3efcdf5a323fc02a7
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Tue Jul 17 16:54:43 2018 +0200

    Rewrite get_tmp_outfile to fix a crash
    
    * src/common.cpp (get_tmp_outfile): Rewrite using c++.
    (getTmpPathUtf8, CreateFileUtf8): New helpers.
    
    --
    This fixes a crash because somehow snwprintf didn't
    always work as I expeted it to. In that case it would
    only concatenate the first chars of the attachment filenames
    this caused the wcsrchr of the backslash to return NULL and
    the following wcschr to find the extension to crash.
    
    This happend on a name conflict in the tmp folder. E.g.
    if two mails were open with the same attachment filenames.

diff --git a/src/common.cpp b/src/common.cpp
index b118dff..689a0b9 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -386,75 +386,127 @@ get_pretty_attachment_name (wchar_t *path, protocol_t protocol,
   return pretty;
 }
 
-/* Open a file in a temporary directory, take name as a
-   suggestion and put the open Handle in outHandle.
-   Returns the actually used file name in case there
-   were other files with that name. */
-wchar_t*
-get_tmp_outfile (wchar_t *name, HANDLE *outHandle)
+static HANDLE
+CreateFileUtf8 (const char *utf8Name)
 {
-  wchar_t tmpPath[MAX_PATH];
-  wchar_t *outName;
-  wchar_t *fileExt = NULL;
-  int tries = 1;
+  if (!utf8Name)
+    {
+      return INVALID_HANDLE_VALUE;
+    }
 
-  if (!name || !wcslen(name))
+  wchar_t *wname = utf8_to_wchar (utf8Name);
+  if (!wname)
     {
-      log_error ("%s:%s: Needs a name.",
-                 SRCNAME, __func__);
-      return NULL;
+      TRACEPOINT;
+      return INVALID_HANDLE_VALUE;
     }
 
+  auto ret = CreateFileW (wname,
+                          GENERIC_WRITE | GENERIC_READ,
+                          FILE_SHARE_READ | FILE_SHARE_DELETE,
+                          NULL,
+                          CREATE_NEW,
+                          FILE_ATTRIBUTE_TEMPORARY,
+                          NULL);
+  xfree (wname);
+  return ret;
+}
+
+static std::string
+getTmpPathUtf8 ()
+{
+  static std::string ret;
+  if (!ret.empty())
+    {
+      return ret;
+    }
+  wchar_t tmpPath[MAX_PATH + 2];
+
   if (!GetTempPathW (MAX_PATH, tmpPath))
     {
       log_error ("%s:%s: Could not get tmp path.",
                  SRCNAME, __func__);
-      return NULL;
+      return ret;
     }
 
-  outName = (wchar_t*) xmalloc ((MAX_PATH + 1) * sizeof(wchar_t));
-  memset (outName, 0, (MAX_PATH + 1) * sizeof (wchar_t));
+  char *utf8Name = wchar_to_utf8 (tmpPath);
 
-  snwprintf (outName, MAX_PATH, L"%s%s", tmpPath, name);
+  if (!utf8Name)
+    {
+      TRACEPOINT;
+      return ret;
+    }
+  ret = utf8Name;
+  xfree (utf8Name);
+  return ret;
+}
 
-  while ((*outHandle = CreateFileW (outName,
-                                    GENERIC_WRITE | GENERIC_READ,
-                                    FILE_SHARE_READ | FILE_SHARE_DELETE,
-                                    NULL,
-                                    CREATE_NEW,
-                                    FILE_ATTRIBUTE_TEMPORARY,
-                                    NULL)) == INVALID_HANDLE_VALUE)
+/* Open a file in a temporary directory, take name as a
+   suggestion and put the open Handle in outHandle.
+   Returns the actually used file name in case there
+   were other files with that name. */
+wchar_t*
+get_tmp_outfile (wchar_t *name, HANDLE *outHandle)
+{
+  const auto utf8Name = wchar_to_utf8_string (name);
+  const auto tmpPath = getTmpPathUtf8 ();
+
+  if (utf8Name.empty() || tmpPath.empty())
+    {
+      TRACEPOINT;
+      return nullptr;
+    }
+
+  auto outName = tmpPath + utf8Name;
+
+  log_mime_parser("%s:%s: Attachment candidate is %s",
+                  SRCNAME, __func__, outName.c_str ());
+
+  int tries = 1;
+  while ((*outHandle = CreateFileUtf8 (outName.c_str ())) == INVALID_HANDLE_VALUE)
     {
-      log_debug_w32 (-1, "%s:%s: Failed to open candidate '%S'",
-                     SRCNAME, __func__, outName);
-      wchar_t fnameBuf[MAX_PATH + 1];
-      wchar_t origName[MAX_PATH + 1];
-      memset (fnameBuf, 0, MAX_PATH + 1);
-      memset (origName, 0, MAX_PATH + 1);
+      log_debug_w32 (-1, "%s:%s: Failed to open candidate '%s'",
+                     SRCNAME, __func__, outName.c_str());
+
+      char *outNameC = strdup (outName.c_str());
+
+      const auto lastBackslash = strrchr (outNameC, '\\');
+      if (!lastBackslash)
+        {
+          /* This is an error because tmp name by definition contains one */
+          log_error ("%s:%s: No backslash in origname '%s'",
+                     SRCNAME, __func__, outNameC);
+          xfree (outNameC);
+          return NULL;
+        }
 
-      snwprintf (origName, MAX_PATH, L"%s%s", tmpPath, name);
-      fileExt = wcschr (wcsrchr(origName, '\\'), '.');
+      auto fileExt = strchr (lastBackslash, '.');
       if (fileExt)
         {
-          wcsncpy (fnameBuf, origName, fileExt - origName);
+          *fileExt = '\0';
+          ++fileExt;
         }
-      else
+      // OutNameC is now without an extension and if
+      // there is a file ext it now points to the extension.
+
+      outName = tmpPath + outNameC + std::to_string(tries++);
+
+      if (fileExt)
         {
-          wcsncpy (fnameBuf, origName, wcslen (origName));
+          outName += fileExt;
         }
-      snwprintf (outName, MAX_PATH, L"%s%i%s", fnameBuf, tries++,
-                 fileExt ? fileExt : L"");
+      xfree (outNameC);
+
       if (tries > 100)
         {
           /* You have to know when to give up,.. */
           log_error ("%s:%s: Could not get a name out of 100 tries",
                      SRCNAME, __func__);
-          xfree (outName);
           return NULL;
         }
     }
 
-  return outName;
+  return utf8_to_wchar (outName.c_str ());
 }
 
 /** Get the Gpg4win Install directory.

commit 1ff79faa4adb181a266531ee39166d8a4af459c1
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Tue Jul 17 16:53:43 2018 +0200

    Add wchar_to_utf8_string function
    
    * src/w32-gettext.cpp, src/w32-gettext.h (wchar_to_utf8_string):
    Wrap the c to c++ conversion in a function.

diff --git a/src/w32-gettext.cpp b/src/w32-gettext.cpp
index 0f67673..b89bc79 100644
--- a/src/w32-gettext.cpp
+++ b/src/w32-gettext.cpp
@@ -1515,6 +1515,26 @@ wchar_to_utf8 (const wchar_t *string)
   return result;
 }
 
+std::string
+wchar_to_utf8_string (const wchar_t *string)
+{
+  std::string ret;
+  if (!string)
+    {
+      return ret;
+    }
+
+  const auto utf8 = wchar_to_utf8 (string);
+  if (!utf8)
+    {
+      return ret;
+    }
+  ret = utf8;
+
+  xfree (utf8);
+  return ret;
+}
+
 
 /* Convert UTF8 to the native codepage.  This function is guaranteed
    to never return NULL.  Caller must xfree the return value. */
diff --git a/src/w32-gettext.h b/src/w32-gettext.h
index cf72888..7010586 100644
--- a/src/w32-gettext.h
+++ b/src/w32-gettext.h
@@ -73,4 +73,6 @@ char *native_to_utf8 (const char *string);
 
 #ifdef __cplusplus
 }
+#include <string>
+std::string wchar_to_utf8_string (const wchar_t *string);
 #endif

-----------------------------------------------------------------------

Summary of changes:
 src/common.cpp      | 132 ++++++++++++++++++++++++++++++++++++----------------
 src/w32-gettext.cpp |  20 ++++++++
 src/w32-gettext.h   |   2 +
 3 files changed, 114 insertions(+), 40 deletions(-)


hooks/post-receive
-- 
GnuPG extension for MS Outlook
http://git.gnupg.org




More information about the Gnupg-commits mailing list