diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-05-04 10:44:32 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-05-04 10:47:02 +0200 |
commit | 9316c050740bf275468ca5429d402718d7e69a07 (patch) | |
tree | c6999df971ee7a4e995fe655bd4c1dfc56b0017c /src | |
parent | 8fd6f27d836f27c22f2af20099166b9e6febf905 (diff) | |
download | merchant-9316c050740bf275468ca5429d402718d7e69a07.tar.gz merchant-9316c050740bf275468ca5429d402718d7e69a07.tar.bz2 merchant-9316c050740bf275468ca5429d402718d7e69a07.zip |
fix memory leak from interaction of templates and new order logic
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/taler-merchant-httpd_post-using-templates.c | 165 | ||||
-rw-r--r-- | src/backend/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", ×tamp), @@ -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) |