merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit b0c73f8d7c39b6c342b497030b31ec6dc089e9c5
parent c50f08ddd051b165012c9b331eb34acc5c03a828
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Mon, 20 Jul 2026 09:19:39 +0200

keep data_source alive while MHD needs it

Diffstat:
Msrc/backend/taler-merchant-httpd.c | 1+
Msrc/backend/taler-merchant-httpd.h | 11+++++++++++
Msrc/backend/taler-merchant-httpd_dispatcher.c | 4++++
Msrc/backend/taler-merchant-httpd_post-reports-REPORT_ID.c | 11+++++++++--
4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -329,6 +329,7 @@ handle_mhd_completion_callback (void *cls, hc->cc (hc->ctx); TALER_MHD_parse_post_cleanup_callback (hc->json_parse_context); GNUNET_free (hc->infix); + GNUNET_free (hc->rewritten_url); if (NULL != hc->request_body) json_decref (hc->request_body); if (NULL != hc->instance) diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h @@ -615,6 +615,17 @@ struct TMH_HandlerContext char *infix; /** + * URL a request was internally rewritten to (e.g. by the + * POST /reports/$REPORT_ID handler that re-dispatches to the + * report's data source). When a request is rewritten, query + * arguments are registered on the connection with pointers + * *into* this buffer via MHD_set_connection_value(), which does + * not copy them; the buffer must therefore stay alive until the + * connection is finished. Freed in the completion callback. + */ + char *rewritten_url; + + /** * Which connection was suspended. */ struct MHD_Connection *connection; diff --git a/src/backend/taler-merchant-httpd_dispatcher.c b/src/backend/taler-merchant-httpd_dispatcher.c @@ -1475,6 +1475,10 @@ identify_handler (struct TMH_HandlerContext *hc, suffix_url = slash + 1; /* skip the '/' */ suffix_strlen = strlen (suffix_url); } + /* free any previously set infix in case the request is being + re-dispatched (e.g. via POST /reports/$REPORT_ID), otherwise + the earlier infix would be leaked */ + GNUNET_free (hc->infix); hc->infix = GNUNET_strndup (infix_url, infix_strlen); } diff --git a/src/backend/taler-merchant-httpd_post-reports-REPORT_ID.c b/src/backend/taler-merchant-httpd_post-reports-REPORT_ID.c @@ -174,6 +174,15 @@ TMH_post_reports_ID ( } hc->rh = NULL; /* just to make it clear: current one will NOT remain */ + /* The query arguments parsed above were registered on the + connection with pointers *into* @e data_source (MHD does not + copy them). Ownership of @e data_source is therefore handed to + @e hc, which frees it only once the connection is finished; we + must NOT free it here (doing so would leave the connection -- + and the re-dispatched GET handler that reads those arguments -- + with dangling pointers). */ + GNUNET_free (hc->rewritten_url); + hc->rewritten_url = data_source; ret = TMH_dispatch_request (hc, data_source, MHD_HTTP_METHOD_GET, @@ -183,13 +192,11 @@ TMH_post_reports_ID ( if (GNUNET_OK != ret) { GNUNET_free (instance_id); - GNUNET_free (data_source); return (GNUNET_NO == ret) ? MHD_YES : MHD_NO; } GNUNET_break (NULL != hc->rh); } GNUNET_free (instance_id); - GNUNET_free (data_source); /* MHD will call the main handler again, which will now dispatch into the _new_ handler callback we just installed! */ return MHD_YES;