aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-03-22 14:38:37 +0100
committerChristian Grothoff <christian@grothoff.org>2024-03-22 14:38:37 +0100
commit3c1e6918f038404d226fe133e7b0895a72c592ac (patch)
treef04a412747cc00db63031380600e067dae2925d2
parentd9e3d0cdfe83368000068959fc32befbd5be0c46 (diff)
fix more json_XXX_size unsigned int issues
-rw-r--r--src/lib/merchant_api_get_accounts.c75
-rw-r--r--src/lib/merchant_api_get_instances.c112
-rw-r--r--src/lib/merchant_api_get_kyc.c141
-rw-r--r--src/lib/merchant_api_get_orders.c89
-rw-r--r--src/lib/merchant_api_get_otp_devices.c66
-rw-r--r--src/lib/merchant_api_get_products.c93
-rw-r--r--src/lib/merchant_api_get_templates.c65
-rw-r--r--src/lib/merchant_api_get_transfers.c2
-rw-r--r--src/lib/merchant_api_get_webhooks.c64
-rw-r--r--src/lib/merchant_api_merchant_get_order.c164
-rw-r--r--src/lib/merchant_api_post_order_abort.c15
-rw-r--r--src/lib/merchant_api_wallet_post_order_refund.c12
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 <taler/taler_json_lib.h>
#include <taler/taler_signatures.h>
+/**
+ * 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
@@ -32,6 +32,11 @@
/**
+ * Maximum number of instances permitted.
+ */
+#define MAX_INSTANCES 1024
+
+/**
* Handle for a GET /instances operation.
*/
struct TALER_MERCHANT_InstancesGetHandle
@@ -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; i<json_array_size (ii->payment_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; i<json_array_size (ii->payment_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
@@ -32,6 +32,11 @@
/**
+ * Maximum length of the KYC arrays supported.
+ */
+#define MAX_KYC 1024
+
+/**
* Handle for a GET /kyc operation.
*/
struct TALER_MERCHANT_KycGetHandle
@@ -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<num_pends; i++)
+ unsigned int num_pends = (unsigned int) json_array_size (pends);
+ unsigned int num_touts = (unsigned int) json_array_size (touts);
+
+ if ( (json_array_size (pends) != (size_t) num_pends) ||
+ (num_pends > 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; i<num_touts; i++)
+
{
- uint32_t hs;
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_web_url ("exchange_url",
- &timeout_kycs[i].exchange_url),
- TALER_JSON_spec_ec ("exchange_code",
- &timeout_kycs[i].exchange_code),
- GNUNET_JSON_spec_uint32 ("exchange_http_status",
- &hs),
- GNUNET_JSON_spec_end ()
- };
-
- if (GNUNET_OK !=
- GNUNET_JSON_parse (json_array_get (touts,
- i),
- spec,
- NULL, NULL))
+ 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<num_pends; i++)
{
- GNUNET_break (0);
- return GNUNET_SYSERR;
+ 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;
+ }
}
- timeout_kycs[i].exchange_http_status = (unsigned int) hs;
+ for (unsigned int i = 0; i<num_touts; i++)
+ {
+ uint32_t hs;
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_web_url ("exchange_url",
+ &timeout_kycs[i].exchange_url),
+ TALER_JSON_spec_ec ("exchange_code",
+ &timeout_kycs[i].exchange_code),
+ GNUNET_JSON_spec_uint32 ("exchange_http_status",
+ &hs),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (json_array_get (touts,
+ i),
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ timeout_kycs[i].exchange_http_status = (unsigned int) hs;
+ }
+ 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);
}
- 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 <taler/taler_json_lib.h>
#include <taler/taler_signatures.h>
+/**
+ * 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 <taler/taler_json_lib.h>
#include <taler/taler_signatures.h>
+/**
+ * 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
@@ -32,6 +32,12 @@
/**
+ * Maximum number of products we return.
+ */
+#define MAX_PRODUCTS 1024
+
+
+/**
* Handle for a GET /products operation.
*/
struct TALER_MERCHANT_ProductsGetHandle
@@ -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
@@ -32,6 +32,12 @@
/**
+ * Maximum number of templates we return.
+ */
+#define MAX_TEMPLATES 1024
+
+
+/**
* Handle for a GET /templates operation.
*/
struct TALER_MERCHANT_TemplatesGetHandle
@@ -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
@@ -32,6 +32,11 @@
/**
+ * Maximum number of webhooks we return.
+ */
+#define MAX_WEBHOOKS 1024
+
+/**
* Handle for a GET /webhooks operation.
*/
struct TALER_MERCHANT_WebhooksGetHandle
@@ -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
@@ -34,6 +34,17 @@
/**
+ * 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
*/
struct TALER_MERCHANT_OrderMerchantGetHandle
@@ -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<wts_len; i++)
+ if ( (json_array_size (wire_details) != (size_t) wts_len) ||
+ (wts_len > 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; i<wts_len; i++)
{
- GNUNET_break_op (0);
- osr->hr.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; i<ref_len; i++)
- {
- 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))
+ for (unsigned int i = 0; i<ref_len; i++)
{
- GNUNET_break_op (0);
- osr->hr.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
@@ -39,6 +39,12 @@
/**
+ * Maximum number of refunds we return.
+ */
+#define MAX_REFUNDS 1024
+
+
+/**
* @brief An abort Handle
*/
struct TALER_MERCHANT_OrderAbortHandle
@@ -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 <taler/taler_signatures.h>
#include <taler/taler_curl_lib.h>
+/**
+ * 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)];