[git] GpgOL - branch, master, updated. gpgol-2.0.3-21-g4967d4e

by Andre Heinecke cvs at cvs.gnupg.org
Sat Dec 2 15:11:47 CET 2017


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  4967d4eeea83817739591d391087710433e4ec65 (commit)
       via  3f9f98dbcbf037b02e3a2f4ef54baead845835f7 (commit)
      from  6f7b068a4aaa7aa92c710c0d0b4e3393ad5299c4 (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 4967d4eeea83817739591d391087710433e4ec65
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Sat Dec 2 15:08:38 2017 +0100

    Read Headers as stream
    
    * src/mapihelp.cpp (mapi_get_header): New helper.
    (mapi_get_message_content_type): Use it.
    
    --
    
    This fixes accessing very large headers where
    MAPI might not return it as a property but
    instead error out with MAPI_E_NOT_ENOUGH_MEMORY.
    
    GnuPG-Bug-Id: 3542

diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp
index 7238ac9..952ddd6 100644
--- a/src/mapihelp.cpp
+++ b/src/mapihelp.cpp
@@ -34,6 +34,8 @@
 #include "gpgolstr.h"
 #include "oomhelp.h"
 
+#include <string>
+
 #ifndef CRYPT_E_STREAM_INSUFFICIENT_DATA
 #define CRYPT_E_STREAM_INSUFFICIENT_DATA 0x80091011
 #endif
@@ -445,6 +447,42 @@ mapi_set_header (LPMESSAGE msg, const char *name, const char *val)
 }
 
 
+/* Return the headers as ASCII string. Returns empty
+   string on failure. */
+std::string
+mapi_get_header (LPMESSAGE message)
+{
+  HRESULT hr;
+  LPSTREAM stream;
+  ULONG bRead;
+  std::string ret;
+
+  if (!message)
+    return ret;
+
+  hr = message->OpenProperty (PR_TRANSPORT_MESSAGE_HEADERS_A, &IID_IStream, 0, 0,
+                              (LPUNKNOWN*)&stream);
+  if (hr)
+    {
+      log_debug ("%s:%s: OpenProperty failed: hr=%#lx", SRCNAME, __func__, hr);
+      return ret;
+    }
+
+  char buf[8192];
+  while ((hr = stream->Read (buf, 8192, &bRead)) == S_OK ||
+         hr == S_FALSE)
+    {
+      if (!bRead)
+        {
+          // EOF
+          break;
+        }
+      ret += std::string (buf, bRead);
+    }
+  gpgol_release (stream);
+  return ret;
+}
+
 
 /* Return the body as a new IStream object.  Returns NULL on failure.
    The stream returns the body as an ASCII stream (Use mapi_get_body
@@ -2944,47 +2982,36 @@ char *
 mapi_get_message_content_type (LPMESSAGE message,
                                char **r_protocol, char **r_smtype)
 {
-  HRESULT hr;
-  LPSPropValue propval = NULL;
   rfc822parse_t msg;
   const char *header_lines, *s;
   rfc822parse_field_t ctx;
   size_t length;
   char *retstr = NULL;
-  
+
   if (r_protocol)
     *r_protocol = NULL;
   if (r_smtype)
     *r_smtype = NULL;
 
-  hr = HrGetOneProp ((LPMAPIPROP)message,
-                     PR_TRANSPORT_MESSAGE_HEADERS_A, &propval);
-  if (FAILED (hr))
-    {
-      log_error ("%s:%s: error getting the headers lines: hr=%#lx",
-                 SRCNAME, __func__, hr);
-      return NULL; 
-    }
-  if (PROP_TYPE (propval->ulPropTag) != PT_STRING8)
+  /* Read the headers into an rfc822 object. */
+  msg = rfc822parse_open (get_message_content_type_cb, NULL);
+  if (!msg)
     {
-      /* As per rfc822, header lines must be plain ascii, so no need
-         to cope with unicode etc. */
-      log_error ("%s:%s: proptag=%#lx not supported\n",
-                 SRCNAME, __func__, propval->ulPropTag);
-      MAPIFreeBuffer (propval);
+      log_error ("%s:%s: rfc822parse_open failed",
+                 SRCNAME, __func__);
       return NULL;
     }
-  header_lines = propval->Value.lpszA;
 
-  /* Read the headers into an rfc822 object. */
-  msg = rfc822parse_open (get_message_content_type_cb, NULL);
-  if (!msg)
+  const std::string hdrStr = mapi_get_header (message);
+  if (hdrStr.empty())
     {
-      log_error ("%s:%s: rfc822parse_open failed\n", SRCNAME, __func__);
-      MAPIFreeBuffer (propval);
+
+      log_error ("%s:%s: failed to get headers",
+                 SRCNAME, __func__);
       return NULL;
     }
-  
+
+  header_lines = hdrStr.c_str();
   while ((s = strchr (header_lines, '\n')))
     {
       length = (s - header_lines);
@@ -2993,7 +3020,7 @@ mapi_get_message_content_type (LPMESSAGE message,
       rfc822parse_insert (msg, (const unsigned char*)header_lines, length);
       header_lines = s+1;
     }
-  
+
   /* Parse the content-type field. */
   ctx = rfc822parse_parse_field (msg, "Content-Type", -1);
   if (ctx)
@@ -3022,7 +3049,6 @@ mapi_get_message_content_type (LPMESSAGE message,
     }
 
   rfc822parse_close (msg);
-  MAPIFreeBuffer (propval);
   return retstr;
 }
 

commit 3f9f98dbcbf037b02e3a2f4ef54baead845835f7
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Sat Dec 2 15:04:35 2017 +0100

    Improve performance of beforeRead handling
    
    * src/mapihelp.cpp (string_to_type): New Helper.
    (mapi_get_message_type, mapi_change_message_class): Use it.
    (mapi_change_message_class): Take optional type retval.
    * src/inspectors.cpp, src/session-events.cpp,
    src/user-events.cpp, src/message.cpp: Udpate calls.
    
    --
    Looking at an improvement for T3542 i measured the
    time spent in beforeRead for "non crypto" mails.
    With this change, which fixes a TODO the time is
    halved because way fewer MAPI calls are required.

diff --git a/src/inspectors.cpp b/src/inspectors.cpp
index 1536e94..da6765c 100644
--- a/src/inspectors.cpp
+++ b/src/inspectors.cpp
@@ -1091,7 +1091,7 @@ proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid)
       if (message)
         {
           /* We sync here. */
-          mapi_change_message_class (message, 1);
+          mapi_change_message_class (message, 1, NULL);
           gpgol_release (message);
         }
     }
diff --git a/src/mail.cpp b/src/mail.cpp
index 7621494..78acd9c 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -259,10 +259,13 @@ Mail::pre_process_message ()
      to the same value again that it already has) causes
      Outlook to reconsider what it "knows" about a message
      and reread data from the underlying base message. */
-  mapi_change_message_class (message, 1);
-  /* TODO: Unify this so mapi_change_message_class returns
-     a useful value already. */
-  m_type = mapi_get_message_type (message);
+  mapi_change_message_class (message, 1, &m_type);
+
+  if (m_type == MSGTYPE_UNKNOWN)
+    {
+      gpgol_release (message);
+      return 0;
+    }
 
   /* Create moss attachments here so that they are properly
      hidden when the item is read into the model. */
diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp
index f2c00f7..7238ac9 100644
--- a/src/mapihelp.cpp
+++ b/src/mapihelp.cpp
@@ -1221,6 +1221,39 @@ change_message_class_ipm_note_secure_cex (LPMESSAGE message, int is_cexenc)
   return newvalue;
 }
 
+static msgtype_t
+string_to_type (const char *s)
+{
+  if (!s || strlen (s) < 14)
+    {
+      return MSGTYPE_UNKNOWN;
+    }
+  if (!strncmp (s, "IPM.Note.GpgOL", 14) && (!s[14] || s[14] =='.'))
+    {
+      s += 14;
+      if (!*s)
+        return MSGTYPE_GPGOL;
+      else if (!strcmp (s, ".MultipartSigned"))
+        return MSGTYPE_GPGOL_MULTIPART_SIGNED;
+      else if (!strcmp (s, ".MultipartEncrypted"))
+        return MSGTYPE_GPGOL_MULTIPART_ENCRYPTED;
+      else if (!strcmp (s, ".OpaqueSigned"))
+        return MSGTYPE_GPGOL_OPAQUE_SIGNED;
+      else if (!strcmp (s, ".OpaqueEncrypted"))
+        return MSGTYPE_GPGOL_OPAQUE_ENCRYPTED;
+      else if (!strcmp (s, ".ClearSigned"))
+        return MSGTYPE_GPGOL_CLEAR_SIGNED;
+      else if (!strcmp (s, ".PGPMessage"))
+        return MSGTYPE_GPGOL_PGP_MESSAGE;
+      else
+        log_debug ("%s:%s: message class `%s' not supported",
+                   SRCNAME, __func__, s-14);
+    }
+  else if (!strncmp (s, "IPM.Note.SMIME", 14) && (!s[14] || s[14] =='.'))
+    return MSGTYPE_SMIME;
+  return MSGTYPE_UNKNOWN;
+}
+
 
 /* This function checks whether MESSAGE requires processing by us and
    adjusts the message class to our own.  By passing true for
@@ -1228,7 +1261,8 @@ change_message_class_ipm_note_secure_cex (LPMESSAGE message, int is_cexenc)
    own message class overide.  Return true if the message was
    changed. */
 int
-mapi_change_message_class (LPMESSAGE message, int sync_override)
+mapi_change_message_class (LPMESSAGE message, int sync_override,
+                           msgtype_t *r_type)
 {
   HRESULT hr;
   ULONG tag;
@@ -1318,6 +1352,10 @@ mapi_change_message_class (LPMESSAGE message, int sync_override)
           newvalue = change_message_class_ipm_note_secure_cex
             (message, cexenc);
         }
+      else if (r_type)
+        {
+          *r_type = string_to_type (s);
+        }
     }
 
   if (!newvalue)
@@ -1332,6 +1370,10 @@ mapi_change_message_class (LPMESSAGE message, int sync_override)
     }
   else
     {
+      if (r_type && newvalue)
+        {
+          *r_type = string_to_type (newvalue);
+        }
       /* Save old message class if not yet done.  (The second
          condition is just a failsafe check). */
       if (!get_gpgololdmsgclass_tag (message, &tag)
@@ -1377,6 +1419,7 @@ mapi_change_message_class (LPMESSAGE message, int sync_override)
         }
       need_save = 1;
     }
+
   MAPIFreeBuffer (propval);
 
   if (need_save)
@@ -1757,34 +1800,10 @@ mapi_get_message_type (LPMESSAGE message)
     }
   else
     log_debug ("%s:%s: have override message class\n", SRCNAME, __func__);
-    
+
   if ( PROP_TYPE (propval->ulPropTag) == PT_STRING8 )
     {
-      const char *s = propval->Value.lpszA;
-
-      if (!strncmp (s, "IPM.Note.GpgOL", 14) && (!s[14] || s[14] =='.'))
-        {
-          s += 14;
-          if (!*s)
-            msgtype = MSGTYPE_GPGOL;
-          else if (!strcmp (s, ".MultipartSigned"))
-            msgtype = MSGTYPE_GPGOL_MULTIPART_SIGNED;
-          else if (!strcmp (s, ".MultipartEncrypted"))
-            msgtype = MSGTYPE_GPGOL_MULTIPART_ENCRYPTED;
-          else if (!strcmp (s, ".OpaqueSigned"))
-            msgtype = MSGTYPE_GPGOL_OPAQUE_SIGNED;
-          else if (!strcmp (s, ".OpaqueEncrypted"))
-            msgtype = MSGTYPE_GPGOL_OPAQUE_ENCRYPTED;
-          else if (!strcmp (s, ".ClearSigned"))
-            msgtype = MSGTYPE_GPGOL_CLEAR_SIGNED;
-          else if (!strcmp (s, ".PGPMessage"))
-            msgtype = MSGTYPE_GPGOL_PGP_MESSAGE;
-          else
-            log_debug ("%s:%s: message class `%s' not supported",
-                       SRCNAME, __func__, s-14);
-        }
-      else if (!strncmp (s, "IPM.Note.SMIME", 14) && (!s[14] || s[14] =='.'))
-        msgtype = MSGTYPE_SMIME;
+      msgtype = string_to_type (propval->Value.lpszA);
     }
   MAPIFreeBuffer (propval);
   return msgtype;
diff --git a/src/mapihelp.h b/src/mapihelp.h
index 93cd63c..0355618 100644
--- a/src/mapihelp.h
+++ b/src/mapihelp.h
@@ -60,7 +60,8 @@ int mapi_do_save_changes (LPMESSAGE message, ULONG flags, int only_del_body,
 
 int mapi_set_header (LPMESSAGE msg, const char *name, const char *val);
 
-int mapi_change_message_class (LPMESSAGE message, int sync_override);
+int mapi_change_message_class (LPMESSAGE message, int sync_override,
+                               msgtype_t *r_type);
 char *mapi_get_message_class (LPMESSAGE message);
 char *mapi_get_old_message_class (LPMESSAGE message);
 char *mapi_get_sender (LPMESSAGE message);
diff --git a/src/message.cpp b/src/message.cpp
index e794a44..08a38de 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -82,7 +82,7 @@ message_incoming_handler (LPMESSAGE message, HWND hwnd, bool force)
         {
           log_debug ("%s:%s: message class not yet checked - doing now\n",
                      SRCNAME, __func__);
-          if (mapi_change_message_class (message, 0))
+          if (mapi_change_message_class (message, 0, NULL))
             goto retry;
         }
       break;
@@ -91,7 +91,7 @@ message_incoming_handler (LPMESSAGE message, HWND hwnd, bool force)
         {
           log_debug ("%s:%s: message class not checked with smime enabled "
                      "- doing now\n", SRCNAME, __func__);
-          if (mapi_change_message_class (message, 0))
+          if (mapi_change_message_class (message, 0, NULL))
             goto retry;
         }
       break;
diff --git a/src/session-events.cpp b/src/session-events.cpp
index ab24b40..c760adf 100644
--- a/src/session-events.cpp
+++ b/src/session-events.cpp
@@ -101,7 +101,7 @@ GpgolSessionEvents::OnDelivery (LPEXCHEXTCALLBACK pEECB)
          the message class IPM.Note.SMIME.MultipartSigned.  If we
          would not change the message class here, OL will change it
          later (before an OnRead) to IPM.Note. */
-      mapi_change_message_class (pMessage, 0);
+      mapi_change_message_class (pMessage, 0, NULL);
       log_mapi_property (pMessage, PR_MESSAGE_CLASS,"PR_MESSAGE_CLASS");
       ul_release (pMessage, __func__, __LINE__);
       ul_release (pMDB, __func__, __LINE__);
diff --git a/src/user-events.cpp b/src/user-events.cpp
index 8b122f1..d89f11d 100644
--- a/src/user-events.cpp
+++ b/src/user-events.cpp
@@ -161,7 +161,7 @@ GpgolUserEvents::OnSelectionChange (LPEXCHEXTCALLBACK eecb)
                                      SRCNAME, __func__);
                           /* We sync the message class here to get rid
                              of IPM.Note.SMIME etc. */
-                          mapi_change_message_class (message, 1);
+                          mapi_change_message_class (message, 1, NULL);
                         }
                     }
                   else

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

Summary of changes:
 src/inspectors.cpp     |   2 +-
 src/mail.cpp           |  11 ++--
 src/mapihelp.cpp       | 151 ++++++++++++++++++++++++++++++++-----------------
 src/mapihelp.h         |   3 +-
 src/message.cpp        |   4 +-
 src/session-events.cpp |   2 +-
 src/user-events.cpp    |   2 +-
 7 files changed, 112 insertions(+), 63 deletions(-)


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




More information about the Gnupg-commits mailing list