gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] 05/05: fix memory leak from interaction of templates an


From: gnunet
Subject: [taler-merchant] 05/05: fix memory leak from interaction of templates and new order logic
Date: Thu, 04 May 2023 10:50:40 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

commit 9316c050740bf275468ca5429d402718d7e69a07
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu May 4 10:44:32 2023 +0200

    fix memory leak from interaction of templates and new order logic
---
 .../taler-merchant-httpd_post-using-templates.c    | 165 +++++++++++++--------
 .../taler-merchant-httpd_private-post-orders.c     |  37 +++--
 2 files changed, 121 insertions(+), 81 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_post-using-templates.c 
b/src/backend/taler-merchant-httpd_post-using-templates.c
index e2fb7d23..74eb0f44 100644
--- a/src/backend/taler-merchant-httpd_post-using-templates.c
+++ b/src/backend/taler-merchant-httpd_post-using-templates.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2022 Taler Systems SA
+  (C) 2022-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as
@@ -21,6 +21,7 @@
  * @file taler-merchant-httpd_post-using-templates.c
  * @brief implementing POST /using-templates request handling
  * @author Priscilla HUANG
+ * @author Christian Grothoff
  */
 #include "platform.h"
 #include "taler-merchant-httpd_post-using-templates.h"
@@ -29,6 +30,43 @@
 #include <taler/taler_json_lib.h>
 
 
+/**
+ * Our context.
+ */
+struct UseContext
+{
+  /**
+   * Internal handler context we are passing into the
+   * POST /private/orders handler.
+   */
+  struct TMH_HandlerContext ihc;
+
+  /**
+   * Our template details from the DB.
+   */
+  struct TALER_MERCHANTDB_TemplateDetails etp;
+
+};
+
+
+/**
+ * Clean up a `struct UseContext *`
+ *
+ * @param cls a `struct UseContext *`
+ */
+static void
+cleanup_use_context (void *cls)
+{
+  struct UseContext *uc = cls;
+
+  TALER_MERCHANTDB_template_details_free (&uc->etp);
+  if (NULL != uc->ihc.cc)
+    uc->ihc.cc (uc->ihc.ctx);
+  json_decref (uc->ihc.request_body);
+  GNUNET_free (uc);
+}
+
+
 MHD_RESULT
 TMH_post_using_templates_ID (const struct TMH_RequestHandler *rh,
                              struct MHD_Connection *connection,
@@ -44,7 +82,6 @@ TMH_post_using_templates_ID (const struct TMH_RequestHandler 
*rh,
   bool no_amount;
   json_t *fake_body;
   bool no_summary;
-  struct TALER_MERCHANTDB_TemplateDetails etp;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_string ("summary",
@@ -57,6 +94,15 @@ TMH_post_using_templates_ID (const struct TMH_RequestHandler 
*rh,
       &no_amount),
     GNUNET_JSON_spec_end ()
   };
+  struct UseContext *uc = hc->ctx;
+
+  if (NULL == uc)
+  {
+    uc = GNUNET_new (struct UseContext);
+    hc->ctx = uc;
+    hc->cc = &cleanup_use_context;
+    uc->ihc.instance = hc->instance;
+  }
 
   {
     enum GNUNET_GenericReturnValue res;
@@ -79,32 +125,35 @@ TMH_post_using_templates_ID (const struct 
TMH_RequestHandler *rh,
     qs = TMH_db->lookup_template (TMH_db->cls,
                                   mi->settings.id,
                                   template_id,
-                                  &etp);
+                                  &uc->etp);
     switch (qs)
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
       /* Clean up and fail hard */
       GNUNET_break (0);
       GNUNET_JSON_parse_free (spec);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                         NULL);
+      return TALER_MHD_reply_with_error (
+        connection,
+        MHD_HTTP_INTERNAL_SERVER_ERROR,
+        TALER_EC_GENERIC_DB_FETCH_FAILED,
+        NULL);
     case GNUNET_DB_STATUS_SOFT_ERROR:
       /* this should be impossible (single select) */
       GNUNET_break (0);
       GNUNET_JSON_parse_free (spec);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                         NULL);
+      return TALER_MHD_reply_with_error (
+        connection,
+        MHD_HTTP_INTERNAL_SERVER_ERROR,
+        TALER_EC_GENERIC_DB_FETCH_FAILED,
+        NULL);
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       /* template not found! */
       GNUNET_JSON_parse_free (spec);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_NOT_FOUND,
-                                         
TALER_EC_MERCHANT_GENERIC_TEMPLATE_UNKNOWN,
-                                         template_id);
+      return TALER_MHD_reply_with_error (
+        connection,
+        MHD_HTTP_NOT_FOUND,
+        TALER_EC_MERCHANT_GENERIC_TEMPLATE_UNKNOWN,
+        template_id);
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
       /* all good */
       break;
@@ -140,22 +189,22 @@ TMH_post_using_templates_ID (const struct 
TMH_RequestHandler *rh,
       const char *err_name;
       unsigned int err_line;
 
-      res = GNUNET_JSON_parse (etp.template_contract,
+      res = GNUNET_JSON_parse (uc->etp.template_contract,
                                tspec,
                                &err_name,
                                &err_line);
       if (GNUNET_OK != res)
       {
         GNUNET_break (0);
-        json_dumpf (etp.template_contract,
+        json_dumpf (uc->etp.template_contract,
                     stderr,
                     JSON_INDENT (2));
-        TALER_MERCHANTDB_template_details_free (&etp);
         GNUNET_JSON_parse_free (spec);
-        return TALER_MHD_reply_with_error (connection,
-                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                           TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                           err_name);
+        return TALER_MHD_reply_with_error (
+          connection,
+          MHD_HTTP_INTERNAL_SERVER_ERROR,
+          TALER_EC_GENERIC_DB_FETCH_FAILED,
+          err_name);
       }
     }
 
@@ -163,7 +212,6 @@ TMH_post_using_templates_ID (const struct 
TMH_RequestHandler *rh,
          (! no_tamount) )
     {
       GNUNET_JSON_parse_free (spec);
-      TALER_MERCHANTDB_template_details_free (&etp);
       return TALER_MHD_reply_with_error (
         connection,
         MHD_HTTP_CONFLICT,
@@ -174,7 +222,6 @@ TMH_post_using_templates_ID (const struct 
TMH_RequestHandler *rh,
     if (no_amount && no_tamount)
     {
       GNUNET_JSON_parse_free (spec);
-      TALER_MERCHANTDB_template_details_free (&etp);
       return TALER_MHD_reply_with_error (
         connection,
         MHD_HTTP_CONFLICT,
@@ -186,7 +233,6 @@ TMH_post_using_templates_ID (const struct 
TMH_RequestHandler *rh,
          (NULL != tsummary) )
     {
       GNUNET_JSON_parse_free (spec);
-      TALER_MERCHANTDB_template_details_free (&etp);
       return TALER_MHD_reply_with_error (
         connection,
         MHD_HTTP_CONFLICT,
@@ -198,48 +244,43 @@ TMH_post_using_templates_ID (const struct 
TMH_RequestHandler *rh,
          (NULL == tsummary) )
     {
       GNUNET_JSON_parse_free (spec);
-      TALER_MERCHANTDB_template_details_free (&etp);
-      return TALER_MHD_reply_with_error (connection,
-                                         MHD_HTTP_CONFLICT,
-                                         
TALER_EC_MERCHANT_POST_USING_TEMPLATES_NO_SUMMARY,
-                                         NULL);
+      return TALER_MHD_reply_with_error (
+        connection,
+        MHD_HTTP_CONFLICT,
+        TALER_EC_MERCHANT_POST_USING_TEMPLATES_NO_SUMMARY,
+        NULL);
     }
     no_summary = (NULL == summary);
     fake_body = GNUNET_JSON_PACK (
-      GNUNET_JSON_pack_object_steal ("order",
-                                     GNUNET_JSON_PACK (
-                                       TALER_JSON_pack_amount ("amount",
-                                                               no_amount ?
-                                                               &tamount :
-                                                               &amount),
-                                       GNUNET_JSON_pack_string ("summary",
-                                                                no_summary ?
-                                                                tsummary :
-                                                                summary),
-                                       GNUNET_JSON_pack_allow_null (
-                                         GNUNET_JSON_pack_string (
-                                           "fulfillment_url",
-                                           fulfillment_url)),
-                                       GNUNET_JSON_pack_allow_null (
-                                         GNUNET_JSON_pack_string (
-                                           "fulfillment_message",
-                                           fulfillment_message))
-                                       ))
+      GNUNET_JSON_pack_object_steal (
+        "order",
+        GNUNET_JSON_PACK (
+          TALER_JSON_pack_amount ("amount",
+                                  no_amount ?
+                                  &tamount :
+                                  &amount),
+          GNUNET_JSON_pack_string ("summary",
+                                   no_summary ?
+                                   tsummary :
+                                   summary),
+          GNUNET_JSON_pack_allow_null (
+            GNUNET_JSON_pack_string (
+              "fulfillment_url",
+              fulfillment_url)),
+          GNUNET_JSON_pack_allow_null (
+            GNUNET_JSON_pack_string (
+              "fulfillment_message",
+              fulfillment_message))
+          ))
       );
   }
-  {
-    struct TMH_HandlerContext fake_hc = {
-      .request_body = fake_body,
-      .instance = hc->instance
-    };
 
-    mret = TMH_private_post_orders_with_pos_secrets (NULL,   /* not even used 
*/
-                                                     connection,
-                                                     &fake_hc,
-                                                     etp.pos_key,
-                                                     etp.pos_algorithm);
-  }
-  TALER_MERCHANTDB_template_details_free (&etp);
-  json_decref (fake_body);
+  uc->ihc.request_body = fake_body;
+  mret = TMH_private_post_orders_with_pos_secrets (
+    NULL,                                                  /* not even used */
+    connection,
+    &uc->ihc,
+    uc->etp.pos_key,
+    uc->etp.pos_algorithm);
   return mret;
 }
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c 
b/src/backend/taler-merchant-httpd_private-post-orders.c
index 951130d0..2c68e680 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -175,7 +175,7 @@ struct OrderContext
   /**
    * Shared key to use with @e pos_algorithm.
    */
-  char *pos_key;
+  const char *pos_key;
 
   /**
    * Our order ID. Pointer into @e order.
@@ -293,7 +293,6 @@ clean_order (void *cls)
                      oc->uuids_length,
                      0);
   json_decref (oc->order);
-  GNUNET_free (oc->pos_key);
   GNUNET_free (oc);
 }
 
@@ -414,10 +413,10 @@ execute_order (struct OrderContext *oc)
   struct TALER_Amount total;
   const char *summary;
   const char *fulfillment_msg = NULL;
-  json_t *products;
-  json_t *merchant;
-  json_t *summary_i18n = NULL;
-  json_t *fulfillment_i18n = NULL;
+  const json_t *products;
+  const json_t *merchant;
+  const json_t *summary_i18n = NULL;
+  const json_t *fulfillment_i18n = NULL;
   struct GNUNET_TIME_Timestamp timestamp;
   struct GNUNET_TIME_Timestamp refund_deadline = { 0 };
   struct GNUNET_TIME_Timestamp wire_transfer_deadline;
@@ -432,21 +431,21 @@ execute_order (struct OrderContext *oc)
     /**
      * The following entries we don't actually need,
      * except to check that the order is well-formed */
-    GNUNET_JSON_spec_json ("products",
-                           &products),
-    GNUNET_JSON_spec_json ("merchant",
-                           &merchant),
+    GNUNET_JSON_spec_array_const ("products",
+                                  &products),
+    GNUNET_JSON_spec_object_const ("merchant",
+                                   &merchant),
     GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_json ("summary_i18n",
-                             &summary_i18n),
+      GNUNET_JSON_spec_object_const ("summary_i18n",
+                                     &summary_i18n),
       NULL),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_string ("fulfillment_message",
                                &fulfillment_msg),
       NULL),
     GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_json ("fulfillment_message_i18n",
-                             &fulfillment_i18n),
+      GNUNET_JSON_spec_object_const ("fulfillment_message_i18n",
+                                     &fulfillment_i18n),
       NULL),
     GNUNET_JSON_spec_timestamp ("timestamp",
                                 &timestamp),
@@ -574,6 +573,7 @@ execute_order (struct OrderContext *oc)
         MHD_HTTP_CONFLICT,
         TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_ALREADY_EXISTS,
         oc->order_id);
+      GNUNET_JSON_parse_free (spec);
       return;
     }
   }
@@ -796,9 +796,9 @@ set_exchanges (struct OrderContext *oc)
     return;
   }
   GNUNET_assert (0 ==
-                 json_object_set (oc->order,
-                                  "exchanges",
-                                  exchanges));
+                 json_object_set_new (oc->order,
+                                      "exchanges",
+                                      exchanges));
   oc->phase++;
 }
 
@@ -1614,8 +1614,7 @@ TMH_private_post_orders_with_pos_secrets (
     hc->cc = &clean_order;
     oc->connection = connection;
     oc->hc = hc;
-    if (NULL != pos_key)
-      oc->pos_key = GNUNET_strdup (pos_key);
+    oc->pos_key = pos_key;
     oc->pos_algorithm = pos_algorithm;
   }
   while (1)

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]