gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: fix more json_XXX_size unsigned


From: gnunet
Subject: [taler-merchant] branch master updated: fix more json_XXX_size unsigned int issues
Date: Fri, 22 Mar 2024 14:38:40 +0100

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

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 3c1e6918 fix more json_XXX_size unsigned int issues
3c1e6918 is described below

commit 3c1e6918f038404d226fe133e7b0895a72c592ac
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Mar 22 14:38:37 2024 +0100

    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 <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
@@ -31,6 +31,11 @@
 #include <taler/taler_signatures.h>
 
 
+/**
+ * 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; 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
@@ -31,6 +31,11 @@
 #include <taler/taler_signatures.h>
 
 
+/**
+ * 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<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
@@ -31,6 +31,12 @@
 #include <taler/taler_signatures.h>
 
 
+/**
+ * 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 <taler/taler_signatures.h>
 
 
+/**
+ * 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 <taler/taler_signatures.h>
 
 
+/**
+ * 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 <taler/taler_signatures.h>
 
 
+/**
+ * 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<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
@@ -38,6 +38,12 @@
 #include <taler/taler_curl_lib.h>
 
 
+/**
+ * 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 <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)];
 

-- 
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]