From 68774b20da5783ba795c4536989963bb2d5e8141 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 12 Apr 2015 22:49:06 +0200 Subject: fix for #3626: make it easier to add additional validators --- src/util/json.c | 4 +- src/util/wireformats.c | 218 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 158 insertions(+), 64 deletions(-) (limited to 'src/util') diff --git a/src/util/json.c b/src/util/json.c index 59c624646..1cc04fe83 100644 --- a/src/util/json.c +++ b/src/util/json.c @@ -258,7 +258,9 @@ TALER_json_to_amount (json_t *json, json_int_t fraction; json_error_t error; - UNPACK_EXITIF (0 != json_unpack_ex (json, &error, JSON_STRICT, + UNPACK_EXITIF (0 != json_unpack_ex (json, + &error, + JSON_STRICT, "{s:s, s:I, s:I}", "curreny", ¤cy, "value", &value, diff --git a/src/util/wireformats.c b/src/util/wireformats.c index 36a60e7c9..df32f2d3d 100644 --- a/src/util/wireformats.c +++ b/src/util/wireformats.c @@ -17,20 +17,53 @@ * @file util/wireformats.c * @brief helper functions for JSON processing using libjansson * @author Sree Harsha Totakura + * @author Christian Grothoff */ #include "platform.h" #include #include "taler_util.h" #include "taler_json_lib.h" +/** + * Shorthand for exit jumps. + */ +#define EXITIF(cond) \ + do { \ + if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ + } while (0) + +/** + * Shorthand for JSON parsing related exit jumps. + */ +#define UNPACK_EXITIF(cond) \ + do { \ + if (cond) { TALER_json_warn (error); goto EXITIF_exit; } \ + } while (0) + + /* Taken from GNU gettext */ + +/** + * Entry in the country table. + */ struct table_entry { + /** + * 2-Character international country code. + */ const char *code; + + /** + * Long English name of the country. + */ const char *english; }; + /* Keep the following table in sync with gettext. WARNING: the entries should stay sorted according to the code */ +/** + * List of country codes. + */ static const struct table_entry country_table[] = { { "AE", "U.A.E." }, @@ -178,8 +211,17 @@ static const struct table_entry country_table[] = { "ZW", "Zimbabwe" } }; + +/** + * Country code comparator function, for binary search with bsearch(). + * + * @param ptr1 pointer to a `struct table_entry` + * @param ptr2 pointer to a `struct table_entry` + * @return result of strncmp()'ing the 2-digit country codes of the entries + */ static int -cmp_country_code (const void *ptr1, const void *ptr2) +cmp_country_code (const void *ptr1, + const void *ptr2) { const struct table_entry *cc1 = ptr1; const struct table_entry *cc2 = ptr2; @@ -187,12 +229,13 @@ cmp_country_code (const void *ptr1, const void *ptr2) return strncmp (cc1->code, cc2->code, 2); } + /** * Validates given IBAN according to the European Banking Standards. See: * http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf * * @param iban the IBAN number to validate - * @return 1 is validated successfully; 0 if not. + * @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not */ static int validate_iban (const char *iban) @@ -202,66 +245,138 @@ validate_iban (const char *iban) struct table_entry cc_entry; unsigned int len; char *nbuf; - int i,j; + unsigned int i; + unsigned int j; + unsigned long long dividend; + unsigned long long remainder; + int nread; + int ret; - len = strlen(iban); + len = strlen (iban); if (len > 34) - return 0; - (void) strncpy (cc, iban, 2); - (void) strncpy (ibancpy, iban+4, len - 4); - (void) strncpy (ibancpy + len - 4, iban, 4); + return GNUNET_NO; + strncpy (cc, iban, 2); + strncpy (ibancpy, iban + 4, len - 4); + strncpy (ibancpy + len - 4, iban, 4); ibancpy[len] = '\0'; cc_entry.code = cc; cc_entry.english = NULL; if (NULL == - bsearch (&cc_entry, country_table, - sizeof(country_table)/sizeof(struct table_entry), + bsearch (&cc_entry, + country_table, + sizeof (country_table) / sizeof (struct table_entry), sizeof (struct table_entry), &cmp_country_code)) - return 0; - nbuf = GNUNET_malloc((len * 2) + 1); + return GNUNET_NO; + nbuf = GNUNET_malloc ((len * 2) + 1); for (i=0, j=0; i < len; i++) { - if(isalpha(ibancpy[i])) + if (isalpha ((int) ibancpy[i])) { - EXITIF(2 != snprintf(&nbuf[j], 3, "%2u", (ibancpy[i] - 'A' + 10))); - j+=2; + EXITIF(2 != snprintf(&nbuf[j], + 3, + "%2u", + (ibancpy[i] - 'A' + 10))); + j += 2; continue; } nbuf[j] = ibancpy[i]; j++; } - for (j=0; ;j++) - { - if ('\0' == nbuf[j]) - break; + for (j=0;'\0' != nbuf[j];j++) GNUNET_assert (isdigit(nbuf[j])); - } - unsigned long long dividend; - unsigned long long remainder = 0; - int nread; - int ret; GNUNET_assert (sizeof(dividend) >= 8); + remainder = 0; for (i=0; i