From 123b489455e63d9340ddc89e40fbbfc4ac273c18 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 2 Jan 2024 15:59:12 +0100 Subject: tighten check for 'extra' field --- .../taler-merchant-httpd_private-post-orders.c | 151 ++++++++++++--------- 1 file changed, 86 insertions(+), 65 deletions(-) diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index 2e59fc6d..054dd714 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -139,7 +139,8 @@ struct OrderContext /** * Information set in the ORDER_PHASE_PARSE_REQUEST phase. */ - struct { + struct + { /** * Order field of the request */ @@ -210,7 +211,8 @@ struct OrderContext /** * Information set in the ORDER_PHASE_ADD_PAYMENT_DETAILS phase. */ - struct { + struct + { /** * Wire method (and our bank account) we have selected * to be included for this order. @@ -221,7 +223,8 @@ struct OrderContext /** * Information set in the ORDER_PHASE_PARSE_ORDER phase. */ - struct { + struct + { /** * Our order ID. */ @@ -341,14 +344,15 @@ struct OrderContext /** * Extra data that is only interpreted by the merchant frontend. */ - json_t *extra; + const json_t *extra; } parse_order; /** * Information set in the ORDER_PHASE_MERGE_INVENTORY phase. */ - struct { + struct + { /** * Merged array of products in the @e order. */ @@ -358,7 +362,8 @@ struct OrderContext /** * Information set in the ORDER_PHASE_SET_EXCHANGES phase. */ - struct { + struct + { /** * Array of exchanges we find acceptable for this * order. @@ -401,7 +406,8 @@ struct OrderContext /** * Information set in the ORDER_PHASE_SET_MAX_FEE phase. */ - struct { + struct + { /** * Maximum fee */ @@ -411,14 +417,16 @@ struct OrderContext /** * Information set in the ORDER_PHASE_EXECUTE_ORDER phase. */ - struct { + struct + { /** * Which product (by offset) is out of stock, UINT_MAX if all were in-stock. */ unsigned int out_of_stock_index; } execute_order; - struct { + struct + { /** * Contract terms to store in the database. */ @@ -838,14 +846,17 @@ execute_order (struct OrderContext *oc) generate the details for the response. */ struct TALER_MERCHANTDB_ProductDetails pd; MHD_RESULT ret; + const struct InventoryProduct *ip; + ip = &oc->parse_request.inventory_products[ + oc->execute_order.out_of_stock_index]; memset (&pd, 0, sizeof (pd)); qs = TMH_db->lookup_product ( TMH_db->cls, oc->hc->instance->settings.id, - oc->parse_request.inventory_products[oc->execute_order.out_of_stock_index].product_id, + ip->product_id, &pd); switch (qs) { @@ -857,10 +868,10 @@ execute_order (struct OrderContext *oc) MHD_HTTP_GONE, GNUNET_JSON_pack_string ( "product_id", - oc->parse_request.inventory_products[oc->execute_order.out_of_stock_index].product_id), + ip->product_id), GNUNET_JSON_pack_uint64 ( "requested_quantity", - oc->parse_request.inventory_products[oc->execute_order.out_of_stock_index].quantity), + ip->quantity), GNUNET_JSON_pack_uint64 ( "available_quantity", pd.total_stock - pd.total_sold - pd.total_lost), @@ -881,12 +892,10 @@ execute_order (struct OrderContext *oc) MHD_HTTP_GONE, GNUNET_JSON_pack_string ( "product_id", - oc->parse_request.inventory_products[oc->execute_order.out_of_stock_index]. - product_id), + ip->product_id), GNUNET_JSON_pack_uint64 ( "requested_quantity", - oc->parse_request.inventory_products[oc->execute_order.out_of_stock_index]. - quantity), + ip->quantity), GNUNET_JSON_pack_uint64 ( "available_quantity", 0))); @@ -1222,30 +1231,30 @@ serialize_order (struct OrderContext *oc) { oc->serialize_order.contract = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("summary", - oc->parse_order.summary), + oc->parse_order.summary), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_steal ("summary_i18n", - oc->parse_order.summary_i18n)), + oc->parse_order.summary_i18n)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("public_reorder_url", - oc->parse_order.public_reorder_url)), + oc->parse_order.public_reorder_url)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("fulfillment_message", - oc->parse_order.fulfillment_message)), + oc->parse_order.fulfillment_message)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_steal ("fulfillment_message_i18n", - oc->parse_order.fulfillment_message_i18n)), + oc->parse_order.fulfillment_message_i18n)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("fulfillment_url", - oc->parse_order.fulfillment_url)), + oc->parse_order.fulfillment_url)), GNUNET_JSON_pack_array_steal ("products", - oc->merge_inventory.products), + oc->merge_inventory.products), GNUNET_JSON_pack_data_auto ("h_wire", &oc->add_payment_details.wm->h_wire), GNUNET_JSON_pack_string ("wire_method", - oc->add_payment_details.wm->wire_method), + oc->add_payment_details.wm->wire_method), GNUNET_JSON_pack_string ("order_id", - oc->parse_order.order_id), + oc->parse_order.order_id), GNUNET_JSON_pack_timestamp ("timestamp", oc->parse_order.timestamp), GNUNET_JSON_pack_timestamp ("pay_deadline", @@ -1257,9 +1266,9 @@ serialize_order (struct OrderContext *oc) oc->parse_order.delivery_date)), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_steal ("delivery_location", - oc->parse_order.delivery_location)), + oc->parse_order.delivery_location)), GNUNET_JSON_pack_string ("merchant_base_url", - oc->parse_order.merchant_base_url), + oc->parse_order.merchant_base_url), GNUNET_JSON_pack_object_steal ("merchant", oc->parse_order.merchant), GNUNET_JSON_pack_data_auto ("merchant_pub", @@ -1271,9 +1280,9 @@ serialize_order (struct OrderContext *oc) TALER_JSON_pack_amount ("amount", &oc->parse_order.brutto), GNUNET_JSON_pack_allow_null ( - GNUNET_JSON_pack_object_steal ("extra", - oc->parse_order.extra)) - ); + GNUNET_JSON_pack_object_incref ("extra", + (json_t *) oc->parse_order.extra)) + ); /* Pack does not work here, because it doesn't set zero-values for timestamps */ GNUNET_assert (0 == @@ -1284,12 +1293,13 @@ serialize_order (struct OrderContext *oc) /* Pack does not work here, because it sets zero-values for relative times */ /* auto_refund should only be set if it is not 0 */ - if (!GNUNET_TIME_relative_is_zero(oc->parse_order.auto_refund)) { + if (! GNUNET_TIME_relative_is_zero (oc->parse_order.auto_refund)) + { GNUNET_assert (0 == json_object_set_new (oc->serialize_order.contract, - "auto_refund", - GNUNET_JSON_from_time_rel ( - oc->parse_order.auto_refund))); + "auto_refund", + GNUNET_JSON_from_time_rel ( + oc->parse_order.auto_refund))); } oc->phase++; @@ -1414,15 +1424,15 @@ parse_order (struct OrderContext *oc) struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount_any ("amount", &oc->parse_order.brutto), - GNUNET_JSON_spec_string("summary", + GNUNET_JSON_spec_string ("summary", &oc->parse_order.summary), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_array_const ("products", &oc->parse_order.products), - NULL), + NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("summary_i18n", - &oc->parse_order.summary_i18n), + &oc->parse_order.summary_i18n), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("order_id", @@ -1433,16 +1443,16 @@ parse_order (struct OrderContext *oc) &oc->parse_order.public_reorder_url), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string("fulfillment_message", - &oc->parse_order.fulfillment_message), + GNUNET_JSON_spec_string ("fulfillment_message", + &oc->parse_order.fulfillment_message), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("fulfillment_message_i18n", - &oc->parse_order.fulfillment_message_i18n), + &oc->parse_order.fulfillment_message_i18n), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("fulfillment_url", - &oc->parse_order.fulfillment_url), + &oc->parse_order.fulfillment_url), NULL), GNUNET_JSON_spec_mark_optional ( TALER_JSON_spec_web_url ("merchant_base_url", @@ -1454,39 +1464,39 @@ parse_order (struct OrderContext *oc) NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("timestamp", - &oc->parse_order.timestamp), + &oc->parse_order.timestamp), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("refund_deadline", - &oc->parse_order.refund_deadline), + &oc->parse_order.refund_deadline), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("pay_deadline", - &oc->parse_order.pay_deadline), + &oc->parse_order.pay_deadline), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("wire_transfer_deadline", - &oc->parse_order.wire_deadline), + &oc->parse_order.wire_deadline), NULL), GNUNET_JSON_spec_mark_optional ( TALER_JSON_spec_amount_any ("max_fee", - &oc->parse_order.max_fee), + &oc->parse_order.max_fee), &no_fee), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("delivery_location", - &oc->parse_order.delivery_location), + &oc->parse_order.delivery_location), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("delivery_date", - &oc->parse_order.delivery_date), + &oc->parse_order.delivery_date), NULL), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_relative_time ("auto_refund", - &oc->parse_order.auto_refund), + &oc->parse_order.auto_refund), NULL), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("extra", - &oc->parse_order.extra), + GNUNET_JSON_spec_object_const ("extra", + &oc->parse_order.extra), NULL), GNUNET_JSON_spec_end () }; @@ -1502,7 +1512,8 @@ parse_order (struct OrderContext *oc) ret); return; } - if (! TMH_test_exchange_configured_for_currency (oc->parse_order.brutto.currency)) + if (! TMH_test_exchange_configured_for_currency ( + oc->parse_order.brutto.currency)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); @@ -1624,7 +1635,8 @@ parse_order (struct OrderContext *oc) } /* If no refund_deadline given, set one based on refund_delay. */ - if (GNUNET_TIME_absolute_is_never (oc->parse_order.refund_deadline.abs_time)) + if (GNUNET_TIME_absolute_is_never ( + oc->parse_order.refund_deadline.abs_time)) { if (GNUNET_TIME_relative_is_zero (oc->parse_request.refund_delay)) { @@ -1634,12 +1646,15 @@ parse_order (struct OrderContext *oc) } else { - oc->parse_order.refund_deadline = GNUNET_TIME_relative_to_timestamp (oc->parse_request.refund_delay); + oc->parse_order.refund_deadline = GNUNET_TIME_relative_to_timestamp ( + oc->parse_request.refund_delay); } } - if ( (! GNUNET_TIME_absolute_is_zero (oc->parse_order.delivery_date.abs_time)) && - (GNUNET_TIME_absolute_is_past (oc->parse_order.delivery_date.abs_time)) ) + if ( (! GNUNET_TIME_absolute_is_zero ( + oc->parse_order.delivery_date.abs_time)) && + (GNUNET_TIME_absolute_is_past ( + oc->parse_order.delivery_date.abs_time)) ) { GNUNET_break_op (0); reply_with_error ( @@ -1667,8 +1682,10 @@ parse_order (struct OrderContext *oc) return; } - if ( (! GNUNET_TIME_absolute_is_zero (oc->parse_order.refund_deadline.abs_time)) && - (GNUNET_TIME_absolute_is_past (oc->parse_order.refund_deadline.abs_time)) ) + if ( (! GNUNET_TIME_absolute_is_zero ( + oc->parse_order.refund_deadline.abs_time)) && + (GNUNET_TIME_absolute_is_past ( + oc->parse_order.refund_deadline.abs_time)) ) { GNUNET_break_op (0); reply_with_error ( @@ -1686,8 +1703,9 @@ parse_order (struct OrderContext *oc) t = GNUNET_TIME_relative_to_timestamp ( GNUNET_TIME_relative_max (settings->default_wire_transfer_delay, oc->parse_request.refund_delay)); - oc->parse_order.wire_deadline = GNUNET_TIME_timestamp_max (oc->parse_order.refund_deadline, - t); + oc->parse_order.wire_deadline = GNUNET_TIME_timestamp_max ( + oc->parse_order.refund_deadline, + t); if (GNUNET_TIME_absolute_is_never (oc->parse_order.wire_deadline.abs_time)) { GNUNET_break_op (0); @@ -1732,7 +1750,8 @@ parse_order (struct OrderContext *oc) GNUNET_free (url); } else if (('\0' == *oc->parse_order.merchant_base_url) || - ('/' != oc->parse_order.merchant_base_url[strlen (oc->parse_order.merchant_base_url) - 1])) + ('/' != oc->parse_order.merchant_base_url[ + strlen (oc->parse_order.merchant_base_url) - 1])) { GNUNET_break_op (0); reply_with_error ( @@ -1887,12 +1906,14 @@ merge_inventory (struct OrderContext *oc) GNUNET_assert (NULL != oc->merge_inventory.products); for (unsigned int i = 0; iparse_request.inventory_products_length; i++) { + const struct InventoryProduct *ip + = &oc->parse_request.inventory_products[i]; struct TALER_MERCHANTDB_ProductDetails pd; enum GNUNET_DB_QueryStatus qs; qs = TMH_db->lookup_product (TMH_db->cls, oc->hc->instance->settings.id, - oc->parse_request.inventory_products[i].product_id, + ip->product_id, &pd); if (qs <= 0) { @@ -1914,7 +1935,7 @@ merge_inventory (struct OrderContext *oc) case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Product %s from order unknown\n", - oc->parse_request.inventory_products[i].product_id); + ip->product_id); http_status = MHD_HTTP_NOT_FOUND; ec = TALER_EC_MERCHANT_GENERIC_PRODUCT_UNKNOWN; break; @@ -1926,7 +1947,7 @@ merge_inventory (struct OrderContext *oc) reply_with_error (oc, http_status, ec, - oc->parse_request.inventory_products[i].product_id); + ip->product_id); return; } { @@ -1947,7 +1968,7 @@ merge_inventory (struct OrderContext *oc) pd.image), GNUNET_JSON_pack_uint64 ( "quantity", - oc->parse_request.inventory_products[i].quantity)); + ip->quantity)); GNUNET_assert (NULL != p); GNUNET_assert (0 == json_array_append_new (oc->merge_inventory.products, -- cgit v1.2.3