Blame SOURCES/gpgme-1.13.1-fix-resource-leaks.patch

8b26e8
diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp
8b26e8
index c0a1dc21..e991dbc8 100644
8b26e8
--- a/lang/cpp/src/context.cpp
8b26e8
+++ b/lang/cpp/src/context.cpp
8b26e8
@@ -223,6 +223,7 @@ Context *Context::createForProtocol(Protocol proto)
8b26e8
         }
8b26e8
         break;
8b26e8
     default:
8b26e8
+        gpgme_release(ctx);
8b26e8
         return nullptr;
8b26e8
     }
8b26e8
 
8b26e8
@@ -273,6 +274,7 @@ std::unique_ptr<Context> Context::createForEngine(Engine eng, Error *error)
8b26e8
         }
8b26e8
         break;
8b26e8
     default:
8b26e8
+        gpgme_release(ctx);
8b26e8
         if (error) {
8b26e8
             *error = Error::fromCode(GPG_ERR_INV_ARG);
8b26e8
         }
8b26e8
diff --git a/lang/cpp/src/data.cpp b/lang/cpp/src/data.cpp
8b26e8
index 7a93cbc2..d08a29db 100644
8b26e8
--- a/lang/cpp/src/data.cpp
8b26e8
+++ b/lang/cpp/src/data.cpp
8b26e8
@@ -249,6 +249,7 @@ std::vector<GpgME::Key> GpgME::Data::toKeys(Protocol proto) const
8b26e8
     }
8b26e8
 
8b26e8
     if (gpgme_op_keylist_from_data_start (ctx->impl()->ctx, d->data, 0)) {
8b26e8
+        delete ctx;
8b26e8
         return ret;
8b26e8
     }
8b26e8
 
8b26e8
diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i
8b26e8
index 87371af8..64b88d54 100644
8b26e8
--- a/lang/python/gpgme.i
8b26e8
+++ b/lang/python/gpgme.i
8b26e8
@@ -53,7 +53,7 @@
8b26e8
     {
8b26e8
       encodedInput = PyUnicode_AsUTF8String($input);
8b26e8
       if (encodedInput == NULL)
8b26e8
-        return NULL;
8b26e8
+        SWIG_fail;
8b26e8
       $1 = PyBytes_AsString(encodedInput);
8b26e8
     }
8b26e8
   else if (PyBytes_Check($input))
8b26e8
@@ -62,22 +62,25 @@
8b26e8
     PyErr_Format(PyExc_TypeError,
8b26e8
                  "arg %d: expected str, bytes, or None, got %s",
8b26e8
 		 $argnum, $input->ob_type->tp_name);
8b26e8
-    return NULL;
8b26e8
+    SWIG_fail;
8b26e8
   }
8b26e8
 }
8b26e8
 %typemap(freearg) const char * {
8b26e8
   Py_XDECREF(encodedInput$argnum);
8b26e8
 }
8b26e8
 
8b26e8
+%typemap(arginit) const char *[] {
8b26e8
+  $1 = NULL;
8b26e8
+}
8b26e8
+
8b26e8
 /* Likewise for a list of strings.  */
8b26e8
-%typemap(in) const char *[] (void *vector = NULL,
8b26e8
-                             size_t size,
8b26e8
+%typemap(in) const char *[] (size_t size,
8b26e8
                              PyObject **pyVector = NULL) {
8b26e8
   /* Check if is a list */
8b26e8
   if (PyList_Check($input)) {
8b26e8
     size_t i, j;
8b26e8
     size = PyList_Size($input);
8b26e8
-    $1 = (char **) (vector = malloc((size+1) * sizeof(char *)));
8b26e8
+    $1 = (char **) malloc((size+1) * sizeof(char *));
8b26e8
     pyVector = calloc(sizeof *pyVector, size);
8b26e8
 
8b26e8
     for (i = 0; i < size; i++) {
8b26e8
@@ -86,12 +89,7 @@
8b26e8
         {
8b26e8
           pyVector[i] = PyUnicode_AsUTF8String(o);
8b26e8
           if (pyVector[i] == NULL)
8b26e8
-            {
8b26e8
-              free(vector);
8b26e8
-              for (j = 0; j < i; j++)
8b26e8
-                Py_XDECREF(pyVector[j]);
8b26e8
-              return NULL;
8b26e8
-            }
8b26e8
+            SWIG_fail;
8b26e8
           $1[i] = PyBytes_AsString(pyVector[i]);
8b26e8
         }
8b26e8
       else if (PyString_Check(o))
8b26e8
@@ -101,8 +99,7 @@
8b26e8
                      "arg %d: list must contain only str or bytes, got %s "
8b26e8
                      "at position %d",
8b26e8
                      $argnum, o->ob_type->tp_name, i);
8b26e8
-	free($1);
8b26e8
-	return NULL;
8b26e8
+	SWIG_fail;
8b26e8
       }
8b26e8
     }
8b26e8
     $1[i] = NULL;
8b26e8
@@ -110,14 +107,17 @@
8b26e8
     PyErr_Format(PyExc_TypeError,
8b26e8
                  "arg %d: expected a list of str or bytes, got %s",
8b26e8
                  $argnum, $input->ob_type->tp_name);
8b26e8
-    return NULL;
8b26e8
+    SWIG_fail;
8b26e8
   }
8b26e8
 }
8b26e8
 %typemap(freearg) const char *[] {
8b26e8
-  size_t i;
8b26e8
-  free(vector$argnum);
8b26e8
-  for (i = 0; i < size$argnum; i++)
8b26e8
-    Py_XDECREF(pyVector$argnum[i]);
8b26e8
+  if (pyVector$argnum) {
8b26e8
+    size_t i;
8b26e8
+    for (i = 0; i < size$argnum; i++)
8b26e8
+      Py_XDECREF(pyVector$argnum[i]);
8b26e8
+    free(pyVector$argnum);
8b26e8
+  }
8b26e8
+  if ($1) free($1);
8b26e8
 }
8b26e8
 
8b26e8
 /* Release returned buffers as necessary.  */
8b26e8
@@ -135,7 +135,7 @@
8b26e8
   if (!PySequence_Check($input)) {
8b26e8
     PyErr_Format(PyExc_ValueError, "arg %d: Expected a list of gpgme_key_t",
8b26e8
 		 $argnum);
8b26e8
-    return NULL;
8b26e8
+    SWIG_fail;
8b26e8
   }
8b26e8
   if((numb = PySequence_Length($input)) != 0) {
8b26e8
     $1 = (gpgme_key_t*)malloc((numb+1)*sizeof(gpgme_key_t));
8b26e8
@@ -152,8 +152,7 @@
8b26e8
                      "arg %d: list must contain only gpgme_key_ts, got %s "
8b26e8
                      "at position %d",
8b26e8
                      $argnum, pypointer->ob_type->tp_name, i);
8b26e8
-        free($1);
8b26e8
-	return NULL;
8b26e8
+	SWIG_fail;
8b26e8
       }
8b26e8
       Py_DECREF(pypointer);
8b26e8
     }
8b26e8
@@ -179,7 +178,7 @@
8b26e8
     pypointer = _gpg_obj2gpgme_data_t($input, $argnum, &wrapper,
8b26e8
                                        &bytesio, &view);
8b26e8
     if (pypointer == NULL)
8b26e8
-      return NULL;
8b26e8
+      SWIG_fail;
8b26e8
     have_view = !! view.obj;
8b26e8
 
8b26e8
     /* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
8b26e8
@@ -189,7 +188,7 @@
8b26e8
     if ((SWIG_ConvertPtr(pypointer,(void **) &$1, $1_descriptor,
8b26e8
          SWIG_POINTER_EXCEPTION | $disown )) == -1) {
8b26e8
       Py_DECREF(pypointer);
8b26e8
-      return NULL;
8b26e8
+      SWIG_fail;
8b26e8
     }
8b26e8
     Py_DECREF(pypointer);
8b26e8
   }
8b26e8
@@ -346,6 +345,11 @@
8b26e8
     PyErr_SetString(PyExc_TypeError, "Numeric argument expected");
8b26e8
 }
8b26e8
 
8b26e8
+%typemap(arginit) (void *buffer, size_t size), (char *buf, size_t buflen) {
8b26e8
+  $1 = NULL;
8b26e8
+  $2 = 0;
8b26e8
+}
8b26e8
+
8b26e8
 /* Those are for gpgme_data_read() and gpgme_strerror_r().  */
8b26e8
 %typemap(in) (void *buffer, size_t size), (char *buf, size_t buflen) {
8b26e8
   {
8b26e8
@@ -359,12 +363,12 @@
8b26e8
     else
8b26e8
       {
8b26e8
         PyErr_SetString(PyExc_TypeError, "Numeric argument expected");
8b26e8
-        return NULL;
8b26e8
+        SWIG_fail;
8b26e8
       }
8b26e8
 
8b26e8
     if (tmp$argnum < 0) {
8b26e8
       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
8b26e8
-      return NULL;
8b26e8
+      SWIG_fail;
8b26e8
     }
8b26e8
     $2 = (size_t) tmp$argnum;
8b26e8
     $1 = ($1_ltype) malloc($2+1);
8b26e8
@@ -373,11 +377,11 @@
8b26e8
 %typemap(argout) (void *buffer, size_t size), (char *buf, size_t buflen) {
8b26e8
   Py_XDECREF($result);   /* Blow away any previous result */
8b26e8
   if (result < 0) {      /* Check for I/O error */
8b26e8
-    free($1);
8b26e8
+    if ($1) free($1);
8b26e8
     return PyErr_SetFromErrno(PyExc_RuntimeError);
8b26e8
   }
8b26e8
   $result = PyBytes_FromStringAndSize($1,result);
8b26e8
-  free($1);
8b26e8
+  if ($1) free($1);
8b26e8
 }
8b26e8
 
8b26e8
 /* For gpgme_data_write, but should be universal.  */
8b26e8
@@ -390,11 +394,11 @@
8b26e8
     {
8b26e8
       encodedInput = PyUnicode_AsUTF8String($input);
8b26e8
       if (encodedInput == NULL)
8b26e8
-        return NULL;
8b26e8
+        SWIG_fail;
8b26e8
       if (PyBytes_AsStringAndSize(encodedInput, (char **) &$1, &ssize) == -1)
8b26e8
         {
8b26e8
           Py_DECREF(encodedInput);
8b26e8
-          return NULL;
8b26e8
+          SWIG_fail;
8b26e8
         }
8b26e8
     }
8b26e8
   else if (PyBytes_Check($input))
8b26e8
@@ -403,7 +407,7 @@
8b26e8
     PyErr_Format(PyExc_TypeError,
8b26e8
                  "arg %d: expected str, bytes, or None, got %s",
8b26e8
 		 $argnum, $input->ob_type->tp_name);
8b26e8
-    return NULL;
8b26e8
+    SWIG_fail;
8b26e8
   }
8b26e8
 
8b26e8
   if (! $1)
8b26e8
@@ -432,8 +436,17 @@
8b26e8
     size++;
8b26e8
   }
8b26e8
   $result = PyList_New(size);
8b26e8
+  if ($result == NULL)
8b26e8
+    SWIG_fail;
8b26e8
   for (i=0,curr=$1; i<size; i++,curr=curr->next) {
8b26e8
     PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor, %newpointer_flags);
8b26e8
+    if (o == NULL) {
8b26e8
+      int j;
8b26e8
+      for (j = 0; j < i; j++)
8b26e8
+        Py_XDECREF(PyList_GetItem($result, j));
8b26e8
+      Py_DECREF($result);
8b26e8
+      SWIG_fail;
8b26e8
+    }
8b26e8
     PyList_SetItem($result, i, o);
8b26e8
   }
8b26e8
 }
8b26e8
@@ -446,6 +459,8 @@
8b26e8
   PyObject *fragile;
8b26e8
   fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
8b26e8
                                %newpointer_flags);
8b26e8
+  if (fragile == NULL)
8b26e8
+    SWIG_fail;
8b26e8
   $result = _gpg_wrap_result(fragile, name);
8b26e8
   Py_DECREF(fragile);
8b26e8
 }
8b26e8
@@ -469,22 +484,28 @@ wrapresult(gpgme_vfs_mount_result_t, "VFSMountResult")
8b26e8
   }
8b26e8
   $result = PyList_New(size);
8b26e8
   if ($result == NULL)
8b26e8
-    return NULL;	/* raise */
8b26e8
+    SWIG_fail;	/* raise */
8b26e8
   for (i=0,curr=$1; i<size; i++,curr=curr->next) {
8b26e8
     PyObject *fragile, *o;
8b26e8
     fragile = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor,
8b26e8
                                  %newpointer_flags);
8b26e8
     if (fragile == NULL)
8b26e8
       {
8b26e8
+        int j;
8b26e8
+        for (j = 0; j < i; j++)
8b26e8
+          Py_XDECREF(PyList_GetItem($result, j));
8b26e8
         Py_DECREF($result);
8b26e8
-        return NULL;	/* raise */
8b26e8
+        SWIG_fail;	/* raise */
8b26e8
       }
8b26e8
     o = _gpg_wrap_result(fragile, "EngineInfo");
8b26e8
     Py_DECREF(fragile);
8b26e8
     if (o == NULL)
8b26e8
       {
8b26e8
+        int j;
8b26e8
+        for (j = 0; j < i; j++)
8b26e8
+          Py_XDECREF(PyList_GetItem($result, j));
8b26e8
         Py_DECREF($result);
8b26e8
-        return NULL;	/* raise */
8b26e8
+        SWIG_fail;	/* raise */
8b26e8
       }
8b26e8
     PyList_SetItem($result, i, o);
8b26e8
   }
8b26e8
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
8b26e8
index dc2d9455..a1e40fe2 100644
8b26e8
--- a/src/engine-gpg.c
8b26e8
+++ b/src/engine-gpg.c
8b26e8
@@ -1122,6 +1122,7 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
8b26e8
                    to avoid and given that we reach this here only
8b26e8
                    after a malloc failure for a small object, it is
8b26e8
                    probably better not to do anything.  */
8b26e8
+		free_argv (argv);
8b26e8
 		return gpg_error (GPG_ERR_GENERAL);
8b26e8
 	      }
8b26e8
 	    /* If the data_type is FD, we have to do a dup2 here.  */
8b26e8
@@ -1239,6 +1240,9 @@ read_status (engine_gpg_t gpg)
8b26e8
       buffer = realloc (buffer, bufsize);
8b26e8
       if (!buffer)
8b26e8
 	return gpg_error_from_syserror ();
8b26e8
+      /* Update buffer and bufsize here to prevent memory leaks.  */
8b26e8
+      gpg->status.buffer = buffer;
8b26e8
+      gpg->status.bufsize = bufsize;
8b26e8
     }
8b26e8
 
8b26e8
   nread = _gpgme_io_read (gpg->status.fd[0],
8b26e8
@@ -1351,8 +1355,6 @@ read_status (engine_gpg_t gpg)
8b26e8
     }
8b26e8
 
8b26e8
   /* Update the gpg object.  */
8b26e8
-  gpg->status.bufsize = bufsize;
8b26e8
-  gpg->status.buffer = buffer;
8b26e8
   gpg->status.readpos = readpos;
8b26e8
   return 0;
8b26e8
 }
8b26e8
@@ -1392,6 +1394,9 @@ read_colon_line (engine_gpg_t gpg)
8b26e8
       buffer = realloc (buffer, bufsize);
8b26e8
       if (!buffer)
8b26e8
 	return gpg_error_from_syserror ();
8b26e8
+      /* Prevent memory leaks.  */
8b26e8
+      gpg->colon.bufsize = bufsize;
8b26e8
+      gpg->colon.buffer  = buffer;
8b26e8
     }
8b26e8
 
8b26e8
   nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos);
8b26e8
@@ -1471,8 +1476,6 @@ read_colon_line (engine_gpg_t gpg)
8b26e8
     }
8b26e8
 
8b26e8
   /* Update the gpg object.  */
8b26e8
-  gpg->colon.bufsize = bufsize;
8b26e8
-  gpg->colon.buffer  = buffer;
8b26e8
   gpg->colon.readpos = readpos;
8b26e8
   return 0;
8b26e8
 }
8b26e8
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
8b26e8
index ae5d8ef1..1f603f19 100644
8b26e8
--- a/src/engine-gpgsm.c
8b26e8
+++ b/src/engine-gpgsm.c
8b26e8
@@ -1533,8 +1533,10 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
8b26e8
   gpgsm->output_cb.data = keydata;
8b26e8
   err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
8b26e8
 		      : map_data_enc (gpgsm->output_cb.data));
8b26e8
-  if (err)
8b26e8
+  if (err) {
8b26e8
+    free (cmd);
8b26e8
     return err;
8b26e8
+  }
8b26e8
   gpgsm_clear_fd (gpgsm, INPUT_FD);
8b26e8
   gpgsm_clear_fd (gpgsm, MESSAGE_FD);
8b26e8
   gpgsm->inline_data = NULL;
8b26e8
@@ -1634,8 +1636,10 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
8b26e8
   gpgsm->output_cb.data = keydata;
8b26e8
   err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
8b26e8
 		      : map_data_enc (gpgsm->output_cb.data));
8b26e8
-  if (err)
8b26e8
+  if (err) {
8b26e8
+    free (line);
8b26e8
     return err;
8b26e8
+  }
8b26e8
   gpgsm_clear_fd (gpgsm, INPUT_FD);
8b26e8
   gpgsm_clear_fd (gpgsm, MESSAGE_FD);
8b26e8
   gpgsm->inline_data = NULL;
8b26e8
diff --git a/src/engine.c b/src/engine.c
8b26e8
index 05979c15..7e2e3800 100644
8b26e8
--- a/src/engine.c
8b26e8
+++ b/src/engine.c
8b26e8
@@ -460,7 +460,8 @@ _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
8b26e8
       if (!new_version)
8b26e8
         {
8b26e8
           free (new_file_name);
8b26e8
-          free (new_home_dir);
8b26e8
+          if (new_home_dir)
8b26e8
+            free (new_home_dir);
8b26e8
           return gpg_error_from_syserror ();
8b26e8
         }
8b26e8
     }
8b26e8
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
8b26e8
index 7a0bfcb3..f4ddd83b 100644
8b26e8
--- a/src/gpgme-tool.c
8b26e8
+++ b/src/gpgme-tool.c
8b26e8
@@ -1189,6 +1189,7 @@ gt_get_key (gpgme_tool_t gt, const char *pattern, gpgme_key_t *r_key)
8b26e8
                  similar hack to sort out such duplicates but it can't
8b26e8
                  do that while listing keys.  */
8b26e8
               gpgme_key_unref (key);
8b26e8
+              key = NULL;
8b26e8
               goto try_next_key;
8b26e8
             }
8b26e8
 	  if (!err)
8b26e8
diff --git a/src/keylist.c b/src/keylist.c
8b26e8
index cdb115fd..b7cbf3c3 100644
8b26e8
--- a/src/keylist.c
8b26e8
+++ b/src/keylist.c
8b26e8
@@ -1321,6 +1321,7 @@ gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
8b26e8
                  similar hack to sort out such duplicates but it can't
8b26e8
                  do that while listing keys.  */
8b26e8
               gpgme_key_unref (key);
8b26e8
+              key = NULL;
8b26e8
               goto try_next_key;
8b26e8
             }
8b26e8
 	  if (!err)