From 3c1e6918f038404d226fe133e7b0895a72c592ac Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 22 Mar 2024 14:38:37 +0100 Subject: fix more json_XXX_size unsigned int issues --- src/lib/merchant_api_get_accounts.c | 75 ++++++----- src/lib/merchant_api_get_instances.c | 112 +++++++++------- src/lib/merchant_api_get_kyc.c | 141 +++++++++++--------- src/lib/merchant_api_get_orders.c | 89 ++++++++----- src/lib/merchant_api_get_otp_devices.c | 66 ++++++---- src/lib/merchant_api_get_products.c | 93 ++++++++------ src/lib/merchant_api_get_templates.c | 65 ++++++---- src/lib/merchant_api_get_transfers.c | 2 +- src/lib/merchant_api_get_webhooks.c | 64 +++++---- src/lib/merchant_api_merchant_get_order.c | 164 ++++++++++++++---------- src/lib/merchant_api_post_order_abort.c | 15 ++- src/lib/merchant_api_wallet_post_order_refund.c | 12 ++ 12 files changed, 541 insertions(+), 357 deletions(-) diff --git a/src/lib/merchant_api_get_accounts.c b/src/lib/merchant_api_get_accounts.c index 95238827..c08cd92d 100644 --- a/src/lib/merchant_api_get_accounts.c +++ b/src/lib/merchant_api_get_accounts.c @@ -30,6 +30,10 @@ #include #include +/** + * Maximum number of accounts permitted. + */ +#define MAX_ACCOUNTS 1024 /** * Handle for a GET /accounts operation. @@ -77,35 +81,44 @@ parse_accounts (const json_t *ia, struct TALER_MERCHANT_AccountsGetResponse *tgr, struct TALER_MERCHANT_AccountsGetHandle *tgh) { - unsigned int tmpl_len = json_array_size (ia); - struct TALER_MERCHANT_AccountEntry tmpl[GNUNET_NZL (tmpl_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_AccountEntry *ie = &tmpl[index]; - struct GNUNET_JSON_Specification spec[] = { - TALER_JSON_spec_payto_uri ("payto_uri", - &ie->payto_uri), - GNUNET_JSON_spec_fixed_auto ("h_wire", - &ie->h_wire), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; + unsigned int tmpl_len = (unsigned int) json_array_size (ia); + + if ( (json_array_size (ia) != (size_t) tmpl_len) || + (tmpl_len > MAX_ACCOUNTS) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_AccountEntry tmpl[GNUNET_NZL (tmpl_len)]; + size_t index; + json_t *value; + + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_AccountEntry *ie = &tmpl[index]; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_payto_uri ("payto_uri", + &ie->payto_uri), + GNUNET_JSON_spec_fixed_auto ("h_wire", + &ie->h_wire), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } } + tgr->details.ok.accounts_length = tmpl_len; + tgr->details.ok.accounts = tmpl; + tgh->cb (tgh->cb_cls, + tgr); + tgh->cb = NULL; /* just to be sure */ } - tgr->details.ok.accounts_length = tmpl_len; - tgr->details.ok.accounts = tmpl; - tgh->cb (tgh->cb_cls, - tgr); - tgh->cb = NULL; /* just to be sure */ return GNUNET_OK; } @@ -120,8 +133,8 @@ parse_accounts (const json_t *ia, */ static void handle_get_accounts_finished (void *cls, - long response_code, - const void *response) + long response_code, + const void *response) { struct TALER_MERCHANT_AccountsGetHandle *tgh = cls; const json_t *json = response; @@ -156,8 +169,8 @@ handle_get_accounts_finished (void *cls, } if (GNUNET_OK == parse_accounts (accounts, - &tgr, - tgh)) + &tgr, + tgh)) { TALER_MERCHANT_accounts_get_cancel (tgh); return; diff --git a/src/lib/merchant_api_get_instances.c b/src/lib/merchant_api_get_instances.c index c0553941..b2f99853 100644 --- a/src/lib/merchant_api_get_instances.c +++ b/src/lib/merchant_api_get_instances.c @@ -31,6 +31,11 @@ #include +/** + * Maximum number of instances permitted. + */ +#define MAX_INSTANCES 1024 + /** * Handle for a GET /instances operation. */ @@ -77,62 +82,71 @@ parse_instances (const json_t *json, const json_t *ia, struct TALER_MERCHANT_InstancesGetHandle *igh) { - unsigned int iis_len = json_array_size (ia); - struct TALER_MERCHANT_InstanceInformation iis[GNUNET_NZL (iis_len)]; - size_t index; - json_t *value; - struct TALER_MERCHANT_InstancesGetResponse igr = { - .hr.http_status = MHD_HTTP_OK, - .hr.reply = json, - .details.ok.iis_length = iis_len, - .details.ok.iis = iis - }; + unsigned int iis_len = (unsigned int) json_array_size (ia); - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_InstanceInformation *ii = &iis[index]; - const char *uts; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("name", - &ii->name), - GNUNET_JSON_spec_string ("user_type", - &uts), - GNUNET_JSON_spec_string ("id", - &ii->id), - GNUNET_JSON_spec_fixed_auto ("merchant_pub", - &ii->merchant_pub), - GNUNET_JSON_spec_array_const ("payment_targets", - &ii->payment_targets), - GNUNET_JSON_spec_end () + if ( (json_array_size (ia) != (size_t) iis_len) || + (iis_len > MAX_INSTANCES) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_InstanceInformation iis[GNUNET_NZL (iis_len)]; + size_t index; + json_t *value; + struct TALER_MERCHANT_InstancesGetResponse igr = { + .hr.http_status = MHD_HTTP_OK, + .hr.reply = json, + .details.ok.iis_length = iis_len, + .details.ok.iis = iis }; - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - TALER_KYCLOGIC_kyc_user_type_from_string (uts, - &ii->ut)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - for (unsigned int i = 0; ipayment_targets); i++) - { - if (! json_is_string (json_array_get (ii->payment_targets, - i))) + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_InstanceInformation *ii = &iis[index]; + const char *uts; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("name", + &ii->name), + GNUNET_JSON_spec_string ("user_type", + &uts), + GNUNET_JSON_spec_string ("id", + &ii->id), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &ii->merchant_pub), + GNUNET_JSON_spec_array_const ("payment_targets", + &ii->payment_targets), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - } - } /* for all instances */ - igh->cb (igh->cb_cls, - &igr); - igh->cb = NULL; /* just to be sure */ + if (GNUNET_OK != + TALER_KYCLOGIC_kyc_user_type_from_string (uts, + &ii->ut)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + for (size_t i = 0; ipayment_targets); i++) + { + if (! json_is_string (json_array_get (ii->payment_targets, + i))) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + } + } /* for all instances */ + igh->cb (igh->cb_cls, + &igr); + igh->cb = NULL; /* just to be sure */ + } return GNUNET_OK; } diff --git a/src/lib/merchant_api_get_kyc.c b/src/lib/merchant_api_get_kyc.c index a9aabbe0..d2a819ea 100644 --- a/src/lib/merchant_api_get_kyc.c +++ b/src/lib/merchant_api_get_kyc.c @@ -31,6 +31,11 @@ #include +/** + * Maximum length of the KYC arrays supported. + */ +#define MAX_KYC 1024 + /** * Handle for a GET /kyc operation. */ @@ -79,72 +84,88 @@ parse_kyc (struct TALER_MERCHANT_KycGetHandle *kyc, const json_t *pends, const json_t *touts) { - unsigned int num_pends = json_array_size (pends); - unsigned int num_touts = json_array_size (touts); - struct TALER_MERCHANT_AccountKycRedirectDetail pending_kycs[GNUNET_NZL ( - num_pends)]; - struct TALER_MERCHANT_ExchangeKycFailureDetail timeout_kycs[GNUNET_NZL ( - num_touts)]; - - memset (pending_kycs, - 0, - sizeof (pending_kycs)); - for (unsigned int i = 0; i MAX_KYC) ) { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_mark_optional ( - TALER_JSON_spec_web_url ("kyc_url", - &pending_kycs[i].kyc_url), - NULL), - TALER_JSON_spec_aml_decision ("aml_status", - &pending_kycs[i].aml_status), - TALER_JSON_spec_web_url ("exchange_url", - &pending_kycs[i].exchange_url), - TALER_JSON_spec_payto_uri ("payto_uri", - &pending_kycs[i].payto_uri), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (json_array_get (pends, - i), - spec, - NULL, NULL)) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } + GNUNET_break (0); + return GNUNET_SYSERR; + } + if ( (json_array_size (touts) != (size_t) num_touts) || + (num_touts > MAX_KYC) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; } - for (unsigned int i = 0; idetails.kyc_status.pending_kycs = pending_kycs; + kr->details.kyc_status.timeout_kycs = timeout_kycs; + kr->details.kyc_status.pending_kycs_length = num_pends; + kr->details.kyc_status.timeout_kycs_length = num_touts; + kyc->cb (kyc->cb_cls, + kr); } - kr->details.kyc_status.pending_kycs = pending_kycs; - kr->details.kyc_status.timeout_kycs = timeout_kycs; - kr->details.kyc_status.pending_kycs_length = num_pends; - kr->details.kyc_status.timeout_kycs_length = num_touts; - kyc->cb (kyc->cb_cls, - kr); return GNUNET_OK; } diff --git a/src/lib/merchant_api_get_orders.c b/src/lib/merchant_api_get_orders.c index af2b46d9..459409fd 100644 --- a/src/lib/merchant_api_get_orders.c +++ b/src/lib/merchant_api_get_orders.c @@ -30,6 +30,10 @@ #include #include +/** + * Maximum number of orders we return. + */ +#define MAX_ORDERS 1024 /** * Handle for a GET /orders operation. @@ -77,45 +81,54 @@ parse_orders (const json_t *ia, struct TALER_MERCHANT_OrdersGetResponse *ogr, struct TALER_MERCHANT_OrdersGetHandle *ogh) { - unsigned int oes_len = json_array_size (ia); - struct TALER_MERCHANT_OrderEntry oes[GNUNET_NZL (oes_len)]; - size_t index; - json_t *value; + unsigned int oes_len = (unsigned int) json_array_size (ia); - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_OrderEntry *ie = &oes[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("order_id", - &ie->order_id), - GNUNET_JSON_spec_timestamp ("timestamp", - &ie->timestamp), - GNUNET_JSON_spec_uint64 ("row_id", - &ie->order_serial), - TALER_JSON_spec_amount_any ("amount", - &ie->amount), - GNUNET_JSON_spec_string ("summary", - &ie->summary), - GNUNET_JSON_spec_bool ("refundable", - &ie->refundable), - GNUNET_JSON_spec_bool ("paid", - &ie->paid), - GNUNET_JSON_spec_end () - }; + if ( (json_array_size (ia) != (size_t) oes_len) || + (oes_len > MAX_ORDERS) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_OrderEntry oes[GNUNET_NZL (oes_len)]; + size_t index; + json_t *value; - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_OrderEntry *ie = &oes[index]; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("order_id", + &ie->order_id), + GNUNET_JSON_spec_timestamp ("timestamp", + &ie->timestamp), + GNUNET_JSON_spec_uint64 ("row_id", + &ie->order_serial), + TALER_JSON_spec_amount_any ("amount", + &ie->amount), + GNUNET_JSON_spec_string ("summary", + &ie->summary), + GNUNET_JSON_spec_bool ("refundable", + &ie->refundable), + GNUNET_JSON_spec_bool ("paid", + &ie->paid), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } } + ogr->details.ok.orders_length = oes_len; + ogr->details.ok.orders = oes; + ogh->cb (ogh->cb_cls, + ogr); + ogh->cb = NULL; /* just to be sure */ } - ogr->details.ok.orders_length = oes_len; - ogr->details.ok.orders = oes; - ogh->cb (ogh->cb_cls, - ogr); - ogh->cb = NULL; /* just to be sure */ return GNUNET_OK; } @@ -275,6 +288,12 @@ TALER_MERCHANT_orders_get3 ( / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us; GNUNET_assert (NULL != backend_url); + if ( (delta > MAX_ORDERS) || + (delta < -MAX_ORDERS) ) + { + GNUNET_break (0); + return NULL; + } if (0 == delta) { GNUNET_break (0); diff --git a/src/lib/merchant_api_get_otp_devices.c b/src/lib/merchant_api_get_otp_devices.c index 3e48486a..4737944c 100644 --- a/src/lib/merchant_api_get_otp_devices.c +++ b/src/lib/merchant_api_get_otp_devices.c @@ -30,6 +30,11 @@ #include #include +/** + * Maximum number of OTP devices we return. + */ +#define MAX_OTP 1024 + /** * Handle for a GET /otp-devices operation. @@ -77,35 +82,44 @@ parse_otp_devices (const json_t *ia, struct TALER_MERCHANT_OtpDevicesGetResponse *tgr, struct TALER_MERCHANT_OtpDevicesGetHandle *tgh) { - unsigned int tmpl_len = json_array_size (ia); - struct TALER_MERCHANT_OtpDeviceEntry tmpl[GNUNET_NZL (tmpl_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_OtpDeviceEntry *ie = &tmpl[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("otp_device_id", - &ie->otp_device_id), - GNUNET_JSON_spec_string ("device_description", - &ie->device_description), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) + unsigned int otp_len = (unsigned int) json_array_size (ia); + + if ( (json_array_size (ia) != (size_t) otp_len) || + (otp_len > MAX_OTP) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_OtpDeviceEntry otp[GNUNET_NZL (otp_len)]; + size_t index; + json_t *value; + + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_OtpDeviceEntry *ie = &otp[index]; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("otp_device_id", + &ie->otp_device_id), + GNUNET_JSON_spec_string ("device_description", + &ie->device_description), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) { GNUNET_break_op (0); return GNUNET_SYSERR; } + } + tgr->details.ok.otp_devices_length = otp_len; + tgr->details.ok.otp_devices = otp; + tgh->cb (tgh->cb_cls, + tgr); + tgh->cb = NULL; /* just to be sure */ } - tgr->details.ok.otp_devices_length = tmpl_len; - tgr->details.ok.otp_devices = tmpl; - tgh->cb (tgh->cb_cls, - tgr); - tgh->cb = NULL; /* just to be sure */ return GNUNET_OK; } @@ -156,8 +170,8 @@ handle_get_otp_devices_finished (void *cls, } if (GNUNET_OK == parse_otp_devices (otp_devices, - &tgr, - tgh)) + &tgr, + tgh)) { TALER_MERCHANT_otp_devices_get_cancel (tgh); return; diff --git a/src/lib/merchant_api_get_products.c b/src/lib/merchant_api_get_products.c index 21657cbd..c33e24c9 100644 --- a/src/lib/merchant_api_get_products.c +++ b/src/lib/merchant_api_get_products.c @@ -31,6 +31,12 @@ #include +/** + * Maximum number of products we return. + */ +#define MAX_PRODUCTS 1024 + + /** * Handle for a GET /products operation. */ @@ -78,48 +84,57 @@ parse_products (const json_t *json, struct TALER_MERCHANT_ProductsGetHandle *pgh) { unsigned int ies_len = json_array_size (ia); - struct TALER_MERCHANT_InventoryEntry ies[GNUNET_NZL (ies_len)]; - size_t index; - json_t *value; - enum GNUNET_GenericReturnValue ret; - - ret = GNUNET_OK; - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_InventoryEntry *ie = &ies[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("product_id", - &ie->product_id), - GNUNET_JSON_spec_uint64 ("product_serial", - &ie->product_serial), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - ret = GNUNET_SYSERR; - continue; - } - if (GNUNET_SYSERR == ret) - break; + + if ( (json_array_size (ia) != (size_t) ies_len) || + (ies_len > MAX_PRODUCTS) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; } - if (GNUNET_OK == ret) { - struct TALER_MERCHANT_GetProductsResponse gpr = { - .hr.http_status = MHD_HTTP_OK, - .hr.reply = json, - .details.ok.products_length = ies_len, - .details.ok.products = ies - }; - - pgh->cb (pgh->cb_cls, - &gpr); - pgh->cb = NULL; /* just to be sure */ + struct TALER_MERCHANT_InventoryEntry ies[GNUNET_NZL (ies_len)]; + size_t index; + json_t *value; + enum GNUNET_GenericReturnValue ret; + + ret = GNUNET_OK; + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_InventoryEntry *ie = &ies[index]; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("product_id", + &ie->product_id), + GNUNET_JSON_spec_uint64 ("product_serial", + &ie->product_serial), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + ret = GNUNET_SYSERR; + continue; + } + if (GNUNET_SYSERR == ret) + break; + } + if (GNUNET_OK == ret) + { + struct TALER_MERCHANT_GetProductsResponse gpr = { + .hr.http_status = MHD_HTTP_OK, + .hr.reply = json, + .details.ok.products_length = ies_len, + .details.ok.products = ies + }; + + pgh->cb (pgh->cb_cls, + &gpr); + pgh->cb = NULL; /* just to be sure */ + } + return ret; } - return ret; } diff --git a/src/lib/merchant_api_get_templates.c b/src/lib/merchant_api_get_templates.c index 98f2e304..f1f973b5 100644 --- a/src/lib/merchant_api_get_templates.c +++ b/src/lib/merchant_api_get_templates.c @@ -31,6 +31,12 @@ #include +/** + * Maximum number of templates we return. + */ +#define MAX_TEMPLATES 1024 + + /** * Handle for a GET /templates operation. */ @@ -77,33 +83,42 @@ parse_templates (const json_t *ia, struct TALER_MERCHANT_TemplatesGetResponse *tgr, struct TALER_MERCHANT_TemplatesGetHandle *tgh) { - unsigned int tmpl_len = json_array_size (ia); - struct TALER_MERCHANT_TemplateEntry tmpl[GNUNET_NZL (tmpl_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_TemplateEntry *ie = &tmpl[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("template_id", - &ie->template_id), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; + unsigned int tmpl_len = (unsigned int) json_array_size (ia); + + if ( (json_array_size (ia) != (size_t) tmpl_len) || + (tmpl_len > MAX_TEMPLATES) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_TemplateEntry tmpl[GNUNET_NZL (tmpl_len)]; + size_t index; + json_t *value; + + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_TemplateEntry *ie = &tmpl[index]; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("template_id", + &ie->template_id), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } } + tgr->details.ok.templates_length = tmpl_len; + tgr->details.ok.templates = tmpl; + tgh->cb (tgh->cb_cls, + tgr); + tgh->cb = NULL; /* just to be sure */ } - tgr->details.ok.templates_length = tmpl_len; - tgr->details.ok.templates = tmpl; - tgh->cb (tgh->cb_cls, - tgr); - tgh->cb = NULL; /* just to be sure */ return GNUNET_OK; } diff --git a/src/lib/merchant_api_get_transfers.c b/src/lib/merchant_api_get_transfers.c index 66a11edb..6116a54f 100644 --- a/src/lib/merchant_api_get_transfers.c +++ b/src/lib/merchant_api_get_transfers.c @@ -116,7 +116,7 @@ handle_transfers_get_finished (void *cls, size_t tds_length; struct TALER_MERCHANT_TransferData *tds; json_t *transfer; - unsigned int i; + size_t i; bool ok; tds_length = json_array_size (transfers); diff --git a/src/lib/merchant_api_get_webhooks.c b/src/lib/merchant_api_get_webhooks.c index 521230e6..e702baac 100644 --- a/src/lib/merchant_api_get_webhooks.c +++ b/src/lib/merchant_api_get_webhooks.c @@ -31,6 +31,11 @@ #include +/** + * Maximum number of webhooks we return. + */ +#define MAX_WEBHOOKS 1024 + /** * Handle for a GET /webhooks operation. */ @@ -77,33 +82,42 @@ parse_webhooks (const json_t *ia, struct TALER_MERCHANT_WebhooksGetResponse *wgr, struct TALER_MERCHANT_WebhooksGetHandle *wgh) { - unsigned int whook_len = json_array_size (ia); - struct TALER_MERCHANT_WebhookEntry whook[GNUNET_NZL (whook_len)]; - size_t index; - json_t *value; - - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_WebhookEntry *ie = &whook[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("webhook_id", - &ie->webhook_id), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; + unsigned int whook_len = (unsigned int) json_array_size (ia); + + if ( (json_array_size (ia) != (size_t) whook_len) || + (whook_len > MAX_WEBHOOKS) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_WebhookEntry whook[GNUNET_NZL (whook_len)]; + size_t index; + json_t *value; + + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_WebhookEntry *ie = &whook[index]; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("webhook_id", + &ie->webhook_id), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } } + wgr->details.ok.webhooks_length = whook_len; + wgr->details.ok.webhooks = whook; + wgh->cb (wgh->cb_cls, + wgr); + wgh->cb = NULL; /* just to be sure */ } - wgr->details.ok.webhooks_length = whook_len; - wgr->details.ok.webhooks = whook; - wgh->cb (wgh->cb_cls, - wgr); - wgh->cb = NULL; /* just to be sure */ return GNUNET_OK; } diff --git a/src/lib/merchant_api_merchant_get_order.c b/src/lib/merchant_api_merchant_get_order.c index afef8853..3a49db34 100644 --- a/src/lib/merchant_api_merchant_get_order.c +++ b/src/lib/merchant_api_merchant_get_order.c @@ -33,6 +33,17 @@ #include +/** + * Maximum number of refund details we return. + */ +#define MAX_REFUND_DETAILS 1024 + +/** + * Maximum number of wire details we return. + */ +#define MAX_WIRE_DETAILS 1024 + + /** * @brief A GET /private/orders/$ORDER handle */ @@ -210,79 +221,102 @@ handle_paid (struct TALER_MERCHANT_OrderMerchantGetHandle *omgh, osr->details.ok.details.paid.exchange_hc = (unsigned int) hc32; { - unsigned int wts_len = json_array_size (wire_details); - unsigned int ref_len = json_array_size (refund_details); - struct TALER_MERCHANT_WireTransfer wts[GNUNET_NZL (wts_len)]; - struct TALER_MERCHANT_RefundOrderDetail ref[GNUNET_NZL (ref_len)]; + unsigned int wts_len = (unsigned int) json_array_size (wire_details); + unsigned int ref_len = (unsigned int) json_array_size (refund_details); - for (unsigned int i = 0; i MAX_WIRE_DETAILS) ) + { + GNUNET_break (0); + osr->hr.http_status = 0; + osr->hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; + omgh->cb (omgh->cb_cls, + osr); + return; + } + if ( (json_array_size (refund_details) != (size_t) ref_len) || + (ref_len > MAX_REFUND_DETAILS) ) { - struct TALER_MERCHANT_WireTransfer *wt = &wts[i]; - const json_t *w = json_array_get (wire_details, - i); - struct GNUNET_JSON_Specification ispec[] = { - TALER_JSON_spec_web_url ("exchange_url", - &wt->exchange_url), - GNUNET_JSON_spec_fixed_auto ("wtid", - &wt->wtid), - GNUNET_JSON_spec_timestamp ("execution_time", - &wt->execution_time), - TALER_JSON_spec_amount_any ("amount", - &wt->total_amount), - GNUNET_JSON_spec_bool ("confirmed", - &wt->confirmed), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (w, - ispec, - NULL, NULL)) + GNUNET_break (0); + osr->hr.http_status = 0; + osr->hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; + omgh->cb (omgh->cb_cls, + osr); + return; + } + { + struct TALER_MERCHANT_WireTransfer wts[GNUNET_NZL (wts_len)]; + struct TALER_MERCHANT_RefundOrderDetail ref[GNUNET_NZL (ref_len)]; + + for (unsigned int i = 0; ihr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - osr); - return; + struct TALER_MERCHANT_WireTransfer *wt = &wts[i]; + const json_t *w = json_array_get (wire_details, + i); + struct GNUNET_JSON_Specification ispec[] = { + TALER_JSON_spec_web_url ("exchange_url", + &wt->exchange_url), + GNUNET_JSON_spec_fixed_auto ("wtid", + &wt->wtid), + GNUNET_JSON_spec_timestamp ("execution_time", + &wt->execution_time), + TALER_JSON_spec_amount_any ("amount", + &wt->total_amount), + GNUNET_JSON_spec_bool ("confirmed", + &wt->confirmed), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (w, + ispec, + NULL, NULL)) + { + GNUNET_break_op (0); + osr->hr.http_status = 0; + osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + omgh->cb (omgh->cb_cls, + osr); + return; + } } - } - for (unsigned int i = 0; irefund_amount), - GNUNET_JSON_spec_string ("reason", - &ro->reason), - GNUNET_JSON_spec_timestamp ("timestamp", - &ro->refund_time), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (w, - ispec, - NULL, NULL)) + for (unsigned int i = 0; ihr.http_status = 0; - osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; - omgh->cb (omgh->cb_cls, - osr); - return; + struct TALER_MERCHANT_RefundOrderDetail *ro = &ref[i]; + const json_t *w = json_array_get (refund_details, + i); + struct GNUNET_JSON_Specification ispec[] = { + TALER_JSON_spec_amount_any ("amount", + &ro->refund_amount), + GNUNET_JSON_spec_string ("reason", + &ro->reason), + GNUNET_JSON_spec_timestamp ("timestamp", + &ro->refund_time), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (w, + ispec, + NULL, NULL)) + { + GNUNET_break_op (0); + osr->hr.http_status = 0; + osr->hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + omgh->cb (omgh->cb_cls, + osr); + return; + } } - } - osr->details.ok.details.paid.wts = wts; - osr->details.ok.details.paid.wts_len = wts_len; - osr->details.ok.details.paid.refunds = ref; - osr->details.ok.details.paid.refunds_len = ref_len; - omgh->cb (omgh->cb_cls, - osr); + osr->details.ok.details.paid.wts = wts; + osr->details.ok.details.paid.wts_len = wts_len; + osr->details.ok.details.paid.refunds = ref; + osr->details.ok.details.paid.refunds_len = ref_len; + omgh->cb (omgh->cb_cls, + osr); + } } } diff --git a/src/lib/merchant_api_post_order_abort.c b/src/lib/merchant_api_post_order_abort.c index 82cca481..270ceb7e 100644 --- a/src/lib/merchant_api_post_order_abort.c +++ b/src/lib/merchant_api_post_order_abort.c @@ -38,6 +38,12 @@ #include +/** + * Maximum number of refunds we return. + */ +#define MAX_REFUNDS 1024 + + /** * @brief An abort Handle */ @@ -127,7 +133,14 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah, GNUNET_break_op (0); return GNUNET_SYSERR; } - num_refunds = json_array_size (refunds); + num_refunds = (unsigned int) json_array_size (refunds); + if ( (json_array_size (refunds) != (size_t) num_refunds) || + (num_refunds > MAX_REFUNDS) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { struct TALER_MERCHANT_AbortedCoin res[GNUNET_NZL (num_refunds)]; diff --git a/src/lib/merchant_api_wallet_post_order_refund.c b/src/lib/merchant_api_wallet_post_order_refund.c index 405231ef..e72982f3 100644 --- a/src/lib/merchant_api_wallet_post_order_refund.c +++ b/src/lib/merchant_api_wallet_post_order_refund.c @@ -32,6 +32,10 @@ #include #include +/** + * Maximum number of refunds we return. + */ +#define MAX_REFUNDS 1024 /** * Handle for a (public) POST /orders/ID/refund operation. @@ -123,6 +127,14 @@ handle_refund_finished (void *cls, break; } refund_len = json_array_size (refunds); + if ( (json_array_size (refunds) != (size_t) refund_len) || + (refund_len > MAX_REFUNDS) ) + { + GNUNET_break (0); + wrr.hr.ec = TALER_EC_GENERIC_ALLOCATION_FAILURE; + wrr.hr.http_status = 0; + break; + } { struct TALER_MERCHANT_RefundDetail rds[GNUNET_NZL (refund_len)]; -- cgit v1.2.3