[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant] branch master updated: -fix bugs, FTBFS
From: |
gnunet |
Subject: |
[taler-merchant] branch master updated: -fix bugs, FTBFS |
Date: |
Wed, 21 Jul 2021 15:29:58 +0200 |
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 4c184f7e -fix bugs, FTBFS
4c184f7e is described below
commit 4c184f7e685817b565013c3afb2a5c30ecf10161
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Jul 21 15:29:48 2021 +0200
-fix bugs, FTBFS
---
src/backend/taler-merchant-httpd_helper.c | 68 +++++++++++
src/backend/taler-merchant-httpd_helper.h | 21 ++++
...er-merchant-httpd_private-delete-instances-ID.c | 23 ++--
...ler-merchant-httpd_private-delete-products-ID.c | 12 +-
.../taler-merchant-httpd_private-get-products-ID.c | 30 ++---
...aler-merchant-httpd_private-patch-products-ID.c | 88 ++++++++++----
.../taler-merchant-httpd_private-post-products.c | 135 +++++++++++++++------
src/backenddb/plugin_merchantdb_postgres.c | 85 +++++++------
8 files changed, 335 insertions(+), 127 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_helper.c
b/src/backend/taler-merchant-httpd_helper.c
index fb0cf318..20be2b45 100644
--- a/src/backend/taler-merchant-httpd_helper.c
+++ b/src/backend/taler-merchant-httpd_helper.c
@@ -80,6 +80,74 @@ TMH_payto_uri_array_valid (const json_t *payto_uris)
}
+bool
+TMH_location_object_valid (const json_t *location)
+{
+ return true; // FIXME
+}
+
+
+// FIXME
+bool
+TMH_i18n_object_valid (const json_t *i18n)
+{
+ return true; // FIXME
+}
+
+
+// FIXME
+bool
+TMH_image_data_url_valid (const char *image_data_url)
+{
+ if (0 == strcmp (image_data_url,
+ ""))
+ return true;
+ if (0 != strncasecmp ("data:image/",
+ image_data_url,
+ strlen ("data:image/")))
+ return false;
+ if (NULL == strstr (";base64,",
+ image_data_url))
+ return false;
+ // FIXME: write generic URI syntax validation */
+ return true;
+}
+
+
+bool
+TMH_taxes_array_valid (const json_t *taxes)
+{
+ json_t *tax;
+ size_t idx;
+
+ if (! json_is_array (taxes))
+ return false;
+ json_array_foreach (taxes, idx, tax)
+ {
+ struct TALER_Amount amount;
+ const char *name;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("name",
+ &name),
+ TALER_JSON_spec_amount ("tax",
+ &amount),
+ GNUNET_JSON_spec_end ()
+ };
+ enum GNUNET_GenericReturnValue res;
+
+ res = TALER_MHD_parse_json_data (NULL,
+ tax,
+ spec);
+ if (GNUNET_OK != res)
+ {
+ GNUNET_break_op (0);
+ return false;
+ }
+ }
+ return true;
+}
+
+
struct TMH_WireMethod *
TMH_setup_wire_account (const char *payto_uri)
{
diff --git a/src/backend/taler-merchant-httpd_helper.h
b/src/backend/taler-merchant-httpd_helper.h
index d15ef2e0..0460665b 100644
--- a/src/backend/taler-merchant-httpd_helper.h
+++ b/src/backend/taler-merchant-httpd_helper.h
@@ -37,6 +37,27 @@ bool
TMH_payto_uri_array_valid (const json_t *payto_uris);
+/**
+ * FIXME.
+ */
+bool
+TMH_taxes_array_valid (const json_t *taxes);
+
+
+// FIXME
+bool
+TMH_location_object_valid (const json_t *location);
+
+
+// FIXME
+bool
+TMH_i18n_object_valid (const json_t *i18n);
+
+
+// FIXME
+bool
+TMH_image_data_url_valid (const char *image_data_url);
+
/**
* Setup new wire method for the given @ payto_uri.
*
diff --git a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c
b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c
index 919c21c9..0de88164 100644
--- a/src/backend/taler-merchant-httpd_private-delete-instances-ID.c
+++ b/src/backend/taler-merchant-httpd_private-delete-instances-ID.c
@@ -34,16 +34,19 @@ static MHD_RESULT
delete_instances_ID (struct TMH_MerchantInstance *mi,
struct MHD_Connection *connection)
{
- const char *purge;
+ const char *purge_s;
+ bool purge;
enum GNUNET_DB_QueryStatus qs;
GNUNET_assert (NULL != mi);
- purge = MHD_lookup_connection_value (connection,
- MHD_GET_ARGUMENT_KIND,
- "purge");
- if ( (NULL != purge) &&
- (0 == strcmp (purge,
- "yes")) )
+ purge_s = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "purge");
+ if (NULL == purge_s)
+ purge_s = "no";
+ purge = (0 == strcmp (purge_s,
+ "yes"));
+ if (purge)
qs = TMH_db->purge_instance (TMH_db->cls,
mi->settings.id);
else
@@ -66,13 +69,11 @@ delete_instances_ID (struct TMH_MerchantInstance *mi,
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN,
- ( (NULL != purge) &&
- (0 == strcmp (purge,
- "yes")) )
+ purge
? "Instance unknown"
: "Private key unknown");
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- if (NULL != purge)
+ if (purge)
TMH_instance_decref (mi);
else
mi->deleted = true;
diff --git a/src/backend/taler-merchant-httpd_private-delete-products-ID.c
b/src/backend/taler-merchant-httpd_private-delete-products-ID.c
index 2d17bafc..bb7964aa 100644
--- a/src/backend/taler-merchant-httpd_private-delete-products-ID.c
+++ b/src/backend/taler-merchant-httpd_private-delete-products-ID.c
@@ -40,6 +40,7 @@ TMH_private_delete_products_ID (const struct
TMH_RequestHandler *rh,
enum GNUNET_DB_QueryStatus qs;
GNUNET_assert (NULL != mi);
+ GNUNET_assert (NULL != hc->infix);
qs = TMH_db->delete_product (TMH_db->cls,
mi->settings.id,
hc->infix);
@@ -49,18 +50,25 @@ TMH_private_delete_products_ID (const struct
TMH_RequestHandler *rh,
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
- NULL);
+ "delete_product");
case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_break (0);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- NULL);
+ "delete_product (soft)");
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ /* check if deletion must have failed because of locks by
+ checking if the product exists */
qs = TMH_db->lookup_product (TMH_db->cls,
mi->settings.id,
hc->infix,
NULL);
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_STORE_FAILED,
+ "lookup_product");
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
diff --git a/src/backend/taler-merchant-httpd_private-get-products-ID.c
b/src/backend/taler-merchant-httpd_private-get-products-ID.c
index 1fdabc8f..32be4d7c 100644
--- a/src/backend/taler-merchant-httpd_private-get-products-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-products-ID.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2019, 2020 Taler Systems SA
+ (C) 2019, 2020, 2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free
Software
@@ -51,28 +51,32 @@ TMH_private_get_products_ID (const struct
TMH_RequestHandler *rh,
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
- NULL);
+ "lookup_product");
}
- else if (0 == qs)
+ if (0 == qs)
{
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_NOT_FOUND,
TALER_EC_MERCHANT_GENERIC_PRODUCT_UNKNOWN,
- NULL);
+ hc->infix);
}
{
json_t *reply;
MHD_RESULT ret;
reply = json_pack (
- "{s:s, s:s, s:o, s:o, s:I,"
- " s:I, s:I, s:o, s:o, s:s}",
+ "{s:s, s:o, s:s, s:o, s:o,"
+ " s:o, s:I, s:I, s:I, s:o}",
"description",
pd.description,
+ "description_i18n",
+ pd.description_i18n,
"unit",
pd.unit,
"price",
TALER_JSON_from_amount (&pd.price),
+ "image",
+ pd.image,
"taxes",
pd.taxes,
"total_stock",
@@ -84,18 +88,16 @@ TMH_private_get_products_ID (const struct
TMH_RequestHandler *rh,
(json_int_t) pd.total_sold,
"total_lost",
(json_int_t) pd.total_lost,
- "description_i18n",
- pd.description_i18n,
"address",
- pd.address,
- "image",
- pd.image);
+ pd.address);
GNUNET_free (pd.description);
GNUNET_free (pd.unit);
if (0 != pd.next_restock.abs_value_us)
- json_object_set_new (reply,
- "next_restock",
- GNUNET_JSON_from_time_abs (pd.next_restock));
+ GNUNET_assert (0 ==
+ json_object_set_new (
+ reply,
+ "next_restock",
+ GNUNET_JSON_from_time_abs (pd.next_restock)));
ret = TALER_MHD_reply_json (connection,
reply,
MHD_HTTP_OK);
diff --git a/src/backend/taler-merchant-httpd_private-patch-products-ID.c
b/src/backend/taler-merchant-httpd_private-patch-products-ID.c
index 3ea9b112..46436d06 100644
--- a/src/backend/taler-merchant-httpd_private-patch-products-ID.c
+++ b/src/backend/taler-merchant-httpd_private-patch-products-ID.c
@@ -24,6 +24,7 @@
*/
#include "platform.h"
#include "taler-merchant-httpd_private-patch-products-ID.h"
+#include "taler-merchant-httpd_helper.h"
#include <taler/taler_json_lib.h>
@@ -87,8 +88,6 @@ determine_cause (struct MHD_Connection *connection,
ec = TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_SOLD_REDUCED;
if (pdx.total_stock > pd->total_stock)
ec = TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_STOCKED_REDUCED;
- if (pd->total_stock < pd->total_sold + pd->total_lost)
- ec = TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_EXCEEDS_STOCKS;
TALER_MERCHANTDB_product_details_free (&pdx);
GNUNET_break (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE != ec);
return TALER_MHD_reply_with_error (connection,
@@ -133,14 +132,14 @@ TMH_private_patch_products_ID (const struct
TMH_RequestHandler *rh,
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("taxes",
&pd.taxes)),
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_json ("address",
- &pd.address)),
GNUNET_JSON_spec_int64 ("total_stock",
&total_stock),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_uint64 ("total_lost",
&pd.total_lost)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_json ("address",
+ &pd.address)),
GNUNET_JSON_spec_mark_optional (
TALER_JSON_spec_absolute_time ("next_restock",
&pd.next_restock)),
@@ -170,7 +169,16 @@ TMH_private_patch_products_ID (const struct
TMH_RequestHandler *rh,
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_CONFLICT,
TALER_EC_GENERIC_CURRENCY_MISMATCH,
- NULL);
+ TMH_currency);
+ }
+ if (total_stock < -1)
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "total_stock");
}
if (-1 == total_stock)
pd.total_stock = INT64_MAX;
@@ -178,35 +186,63 @@ TMH_private_patch_products_ID (const struct
TMH_RequestHandler *rh,
pd.total_stock = (uint64_t) total_stock;
if (NULL == pd.address)
pd.address = json_object ();
+
+ if (! TMH_location_object_valid (pd.address))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "address");
+ }
if (NULL == pd.description_i18n)
pd.description_i18n = json_object ();
+
+ if (! TMH_i18n_object_valid (pd.description_i18n))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "description_i18n");
+ }
+
if (NULL == pd.taxes)
- pd.taxes = json_object ();
+ pd.taxes = json_array ();
+ /* check taxes is well-formed */
+ if (! TMH_taxes_array_valid (pd.taxes))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "taxes");
+ }
if (NULL == pd.image)
pd.image = "";
- if (NULL != json_object_get (hc->request_body,
- "next_restock"))
+ if (! TMH_image_data_url_valid (pd.image))
{
- enum GNUNET_GenericReturnValue res;
- struct GNUNET_JSON_Specification spec[] = {
- TALER_JSON_spec_absolute_time ("next_restock",
- &pd.next_restock),
- GNUNET_JSON_spec_end ()
- };
-
- res = TALER_MHD_parse_json_data (connection,
- hc->request_body,
- spec);
- if (GNUNET_OK != res)
- return (GNUNET_NO == res)
- ? MHD_YES
- : MHD_NO;
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "image");
}
- else
+ if ( (pd.total_stock < pd.total_sold + pd.total_lost) ||
+ (pd.total_sold + pd.total_lost < pd.total_sold) /* integer overflow */)
{
- pd.next_restock.abs_value_us = 0;
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (
+ connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_MERCHANT_PRIVATE_PATCH_PRODUCTS_TOTAL_LOST_EXCEEDS_STOCKS,
+ NULL);
}
-
qs = TMH_db->update_product (TMH_db->cls,
mi->settings.id,
product_id,
diff --git a/src/backend/taler-merchant-httpd_private-post-products.c
b/src/backend/taler-merchant-httpd_private-post-products.c
index 76413cc4..4cf97fd0 100644
--- a/src/backend/taler-merchant-httpd_private-post-products.c
+++ b/src/backend/taler-merchant-httpd_private-post-products.c
@@ -24,6 +24,7 @@
*/
#include "platform.h"
#include "taler-merchant-httpd_private-post-products.h"
+#include "taler-merchant-httpd_helper.h"
#include <taler/taler_json_lib.h>
@@ -50,8 +51,9 @@ products_equal (const struct TALER_MERCHANTDB_ProductDetails
*p1,
p2->description_i18n)) &&
(0 == strcmp (p1->unit,
p2->unit)) &&
- (GNUNET_OK == TALER_amount_cmp_currency (&p1->price,
- &p2->price)) &&
+ (GNUNET_OK ==
+ TALER_amount_cmp_currency (&p1->price,
+ &p2->price)) &&
(0 == TALER_amount_cmp (&p1->price,
&p2->price)) &&
(1 == json_equal (p1->taxes,
@@ -86,9 +88,6 @@ TMH_private_post_products (const struct TMH_RequestHandler
*rh,
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("description_i18n",
&pd.description_i18n)),
- GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_absolute_time ("next_restock",
- &pd.next_restock)),
GNUNET_JSON_spec_string ("unit",
(const char **) &pd.unit),
TALER_JSON_spec_amount ("price",
@@ -99,11 +98,11 @@ TMH_private_post_products (const struct TMH_RequestHandler
*rh,
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("taxes",
&pd.taxes)),
+ GNUNET_JSON_spec_int64 ("total_stock",
+ &total_stock),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("address",
&pd.address)),
- GNUNET_JSON_spec_int64 ("total_stock",
- &total_stock),
GNUNET_JSON_spec_mark_optional (
TALER_JSON_spec_absolute_time ("next_restock",
&pd.next_restock)),
@@ -134,8 +133,19 @@ TMH_private_post_products (const struct TMH_RequestHandler
*rh,
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_CONFLICT,
TALER_EC_GENERIC_CURRENCY_MISMATCH,
- NULL);
+ TMH_currency);
+ }
+ if (total_stock < -1)
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "total_stock");
}
+
+
if (-1 == total_stock)
pd.total_stock = INT64_MAX;
else
@@ -146,9 +156,52 @@ TMH_private_post_products (const struct TMH_RequestHandler
*rh,
if (NULL == pd.description_i18n)
pd.description_i18n = json_object ();
if (NULL == pd.taxes)
- pd.taxes = json_object ();
+ pd.taxes = json_array ();
+
+ /* check taxes is well-formed */
+ if (! TMH_taxes_array_valid (pd.taxes))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "taxes");
+ }
+
+ if (! TMH_location_object_valid (pd.address))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "address");
+ }
+
+ if (! TMH_i18n_object_valid (pd.description_i18n))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "description_i18n");
+ }
+
if (NULL == pd.image)
pd.image = "";
+ if (! TMH_image_data_url_valid (pd.image))
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "image");
+ }
+
+ /* finally, interact with DB until no serialization error */
for (unsigned int i = 0; i<MAX_RETRIES; i++)
{
/* Test if an product of this id is known */
@@ -173,7 +226,13 @@ TMH_private_post_products (const struct TMH_RequestHandler
*rh,
{
case GNUNET_DB_STATUS_HARD_ERROR:
/* Clean up and fail hard */
- break;
+ GNUNET_break (0);
+ TMH_db->rollback (TMH_db->cls);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ NULL);
case GNUNET_DB_STATUS_SOFT_ERROR:
/* restart transaction */
goto retry;
@@ -182,50 +241,50 @@ TMH_private_post_products (const struct
TMH_RequestHandler *rh,
break;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
/* idempotency check: is epd == pd? */
- if (products_equal (&pd,
- &epd))
- {
- TALER_MERCHANTDB_product_details_free (&epd);
- TMH_db->rollback (TMH_db->cls);
- GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_static (connection,
- MHD_HTTP_NO_CONTENT,
- NULL,
- NULL,
- 0);
- }
- else
{
+ bool eq;
+
+ eq = products_equal (&pd,
+ &epd);
TALER_MERCHANTDB_product_details_free (&epd);
TMH_db->rollback (TMH_db->cls);
GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_CONFLICT,
-
TALER_EC_MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS,
- product_id);
+ return eq
+ ? TALER_MHD_reply_static (connection,
+ MHD_HTTP_NO_CONTENT,
+ NULL,
+ NULL,
+ 0)
+ : TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_CONFLICT,
+
TALER_EC_MERCHANT_PRIVATE_POST_PRODUCTS_CONFLICT_PRODUCT_EXISTS,
+ product_id);
}
- }
+ } /* end switch (qs) */
qs = TMH_db->insert_product (TMH_db->cls,
mi->settings.id,
product_id,
&pd);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- goto retry;
- qs = TMH_db->commit (TMH_db->cls);
- if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
- break;
-retry:
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
TMH_db->rollback (TMH_db->cls);
- continue;
+ break;
}
- }
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+ {
+ qs = TMH_db->commit (TMH_db->cls);
+ if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
+ break;
+ }
+retry:
+ GNUNET_assert (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ TMH_db->rollback (TMH_db->cls);
+ } /* for RETRIES loop */
GNUNET_JSON_parse_free (spec);
if (qs < 0)
{
- GNUNET_break_op (0);
+ GNUNET_break (0);
return TALER_MHD_reply_with_error (
connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
diff --git a/src/backenddb/plugin_merchantdb_postgres.c
b/src/backenddb/plugin_merchantdb_postgres.c
index 86e30d0b..54a7241b 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -1000,42 +1000,53 @@ postgres_lookup_product (void *cls,
GNUNET_PQ_query_param_string (product_id),
GNUNET_PQ_query_param_end
};
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_string ("description",
- &pd->description),
- TALER_PQ_result_spec_json ("description_i18n",
- &pd->description_i18n),
- GNUNET_PQ_result_spec_string ("unit",
- &pd->unit),
- TALER_PQ_RESULT_SPEC_AMOUNT ("price",
- &pd->price),
- TALER_PQ_result_spec_json ("taxes",
- &pd->taxes),
- GNUNET_PQ_result_spec_uint64 ("total_stock",
- &pd->total_stock),
- GNUNET_PQ_result_spec_uint64 ("total_sold",
- &pd->total_sold),
- GNUNET_PQ_result_spec_uint64 ("total_lost",
- &pd->total_lost),
- GNUNET_PQ_result_spec_string ("image",
- &pd->image),
- TALER_PQ_result_spec_json ("address",
- &pd->address),
- GNUNET_PQ_result_spec_absolute_time ("next_restock",
- &pd->next_restock),
- GNUNET_PQ_result_spec_end
- };
- struct GNUNET_PQ_ResultSpec rs_null[] = {
- GNUNET_PQ_result_spec_end
- };
- check_connection (pg);
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_product",
- params,
- (NULL == pd)
- ? rs_null
- : rs);
+ if (NULL == pd)
+ {
+ struct GNUNET_PQ_ResultSpec rs_null[] = {
+ GNUNET_PQ_result_spec_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "lookup_product",
+ params,
+ rs_null);
+ }
+ else
+ {
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_string ("description",
+ &pd->description),
+ TALER_PQ_result_spec_json ("description_i18n",
+ &pd->description_i18n),
+ GNUNET_PQ_result_spec_string ("unit",
+ &pd->unit),
+ TALER_PQ_RESULT_SPEC_AMOUNT ("price",
+ &pd->price),
+ TALER_PQ_result_spec_json ("taxes",
+ &pd->taxes),
+ GNUNET_PQ_result_spec_uint64 ("total_stock",
+ &pd->total_stock),
+ GNUNET_PQ_result_spec_uint64 ("total_sold",
+ &pd->total_sold),
+ GNUNET_PQ_result_spec_uint64 ("total_lost",
+ &pd->total_lost),
+ GNUNET_PQ_result_spec_string ("image",
+ &pd->image),
+ TALER_PQ_result_spec_json ("address",
+ &pd->address),
+ GNUNET_PQ_result_spec_absolute_time ("next_restock",
+ &pd->next_restock),
+ GNUNET_PQ_result_spec_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "lookup_product",
+ params,
+ rs);
+ }
}
@@ -1148,7 +1159,9 @@ postgres_update_product (void *cls,
GNUNET_PQ_query_param_end
};
- if (pd->total_stock < pd->total_lost + pd->total_sold)
+ if ( (pd->total_stock < pd->total_lost + pd->total_sold) ||
+ (pd->total_lost < pd->total_lost
+ + pd->total_sold) /* integer overflow */)
{
GNUNET_break (0);
return GNUNET_DB_STATUS_HARD_ERROR;
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-merchant] branch master updated: -fix bugs, FTBFS,
gnunet <=