diff options
Diffstat (limited to 'src/lib/merchant_api_get_templates.c')
-rw-r--r-- | src/lib/merchant_api_get_templates.c | 130 |
1 files changed, 63 insertions, 67 deletions
diff --git a/src/lib/merchant_api_get_templates.c b/src/lib/merchant_api_get_templates.c index 030d80cb..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 @@ -68,53 +74,52 @@ struct TALER_MERCHANT_TemplatesGetHandle * Parse template information from @a ia. * * @param ia JSON array (or NULL!) with template data + * @param[in] tgr partially filled response * @param tgh operation handle * @return #GNUNET_OK on success */ -static int +static enum GNUNET_GenericReturnValue parse_templates (const json_t *ia, + struct TALER_MERCHANT_TemplatesGetResponse *tgr, struct TALER_MERCHANT_TemplatesGetHandle *tgh) { - unsigned int ies_len = json_array_size (ia); - struct TALER_MERCHANT_TemplateEntry ies[ies_len]; - size_t index; - json_t *value; - int ret; - - ret = GNUNET_OK; - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_TemplateEntry *ie = &ies[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); - ret = GNUNET_SYSERR; - continue; - } - if (GNUNET_SYSERR == ret) - break; + 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; } - if (GNUNET_OK == ret) { - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = MHD_HTTP_OK - }; + 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, - &hr, - ies_len, - ies); + tgr); tgh->cb = NULL; /* just to be sure */ } - return ret; + return GNUNET_OK; } @@ -133,9 +138,9 @@ handle_get_templates_finished (void *cls, { struct TALER_MERCHANT_TemplatesGetHandle *tgh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_TemplatesGetResponse tgr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; tgh->job = NULL; @@ -146,10 +151,10 @@ handle_get_templates_finished (void *cls, { case MHD_HTTP_OK: { - json_t *templates; + const json_t *templates; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("templates", - &templates), + GNUNET_JSON_spec_array_const ("templates", + &templates), GNUNET_JSON_spec_end () }; @@ -158,48 +163,39 @@ handle_get_templates_finished (void *cls, spec, NULL, NULL)) { - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + tgr.hr.http_status = 0; + tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; } - else + if (GNUNET_OK == + parse_templates (templates, + &tgr, + tgh)) { - if ( (! json_is_array (templates)) || - (GNUNET_OK == - parse_templates (templates, - tgh)) ) - { - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_templates_get_cancel (tgh); - return; - } - else - { - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - } + TALER_MERCHANT_templates_get_cancel (tgh); + return; } - GNUNET_JSON_parse_free (spec); + tgr.hr.http_status = 0; + tgr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tgr.hr.ec = TALER_JSON_get_error_code (json); + tgr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; default: /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + tgr.hr.ec = TALER_JSON_get_error_code (json); + tgr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) tgr.hr.ec); break; } tgh->cb (tgh->cb_cls, - &hr, - 0, - NULL); + &tgr); TALER_MERCHANT_templates_get_cancel (tgh); } |