aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-03-18 18:55:41 +0100
committerChristian Grothoff <christian@grothoff.org>2015-03-18 18:55:41 +0100
commit23bf1eee74bed73cf98264c247ab44df8dadfcd9 (patch)
tree3d7fcba4b6fb8a84b79585b4fa6ccdf0fff6ade4 /src/include
parent08958c73e8ba6ad30e98a30968077cdf55bc86e8 (diff)
fix #3716: make sure amount-API offers proper checks against overflow and other issues
Diffstat (limited to 'src/include')
-rw-r--r--src/include/taler_amount_lib.h121
-rw-r--r--src/include/taler_json_lib.h2
2 files changed, 91 insertions, 32 deletions
diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h
index 8bea0256c..e64ff4d92 100644
--- a/src/include/taler_amount_lib.h
+++ b/src/include/taler_amount_lib.h
@@ -25,10 +25,27 @@
/**
* Number of characters (plus 1 for 0-termination) we use to
* represent currency names (i.e. EUR, USD, etc.). We use
- * 8 for alignment (!).
+ * 4 for alignment as 3 characters are typical and we need a
+ * 0-terminator. So do not change this.
*/
#define TALER_CURRENCY_LEN 4
+/**
+ * The "fraction" value in a `struct TALER_Amount` represents which
+ * fraction of the "main" value?
+ *
+ * Note that we need sub-cent precision here as transaction fees might
+ * be that low, and as we want to support microdonations.
+ */
+#define TALER_AMOUNT_FRAC_BASE 1000000
+
+/**
+ * How many digits behind the comma are required to represent the
+ * fractional value in human readable decimal format? Must match
+ * lg(#TALER_AMOUNT_FRAC_BASE).
+ */
+#define TALER_AMOUNT_FRAC_LEN 6
+
GNUNET_NETWORK_STRUCT_BEGIN
@@ -41,12 +58,12 @@ struct TALER_AmountNBO
/**
* Value in the main currency, in NBO.
*/
- uint32_t value;
+ uint64_t value GNUNET_PACKED;
/**
* Additinal fractional value, in NBO.
*/
- uint32_t fraction;
+ uint32_t fraction GNUNET_PACKED;
/**
* Type of the currency being represented.
@@ -65,7 +82,7 @@ struct TALER_Amount
/**
* Value (numerator of fraction)
*/
- uint32_t value;
+ uint64_t value;
/**
* Fraction (denominator of fraction)
@@ -73,7 +90,8 @@ struct TALER_Amount
uint32_t fraction;
/**
- * Currency string, left adjusted and padded with zeros.
+ * Currency string, left adjusted and padded with zeros. All zeros
+ * for "invalid" values.
*/
char currency[TALER_CURRENCY_LEN];
};
@@ -93,81 +111,122 @@ TALER_string_to_amount (const char *str,
/**
+ * Get the value of "zero" in a particular currency.
+ *
+ * @param cur currency description
+ * @param denom denomination to write the result to
+ * @return #GNUNET_OK if @a cur is a valid currency specification,
+ * #GNUNET_SYSERR if it is invalid.
+ */
+int
+TALER_amount_get_zero (const char *cur,
+ struct TALER_Amount *denom);
+
+
+/**
* Convert amount from host to network representation.
*
+ * @param res where to store amount in network representation
* @param d amount in host representation
- * @return amount in network representation
*/
-struct TALER_AmountNBO
-TALER_amount_hton (const struct TALER_Amount d);
+void
+TALER_amount_hton (struct TALER_AmountNBO *res,
+ const struct TALER_Amount *d);
/**
* Convert amount from network to host representation.
*
+ * @param res where to store amount in host representation
* @param d amount in network representation
- * @return amount in host representation
*/
-struct TALER_Amount
-TALER_amount_ntoh (const struct TALER_AmountNBO dn);
+void
+TALER_amount_ntoh (struct TALER_Amount *res,
+ const struct TALER_AmountNBO *dn);
/**
- * Compare the value/fraction of two amounts. Does not compare the currency,
- * i.e. comparing amounts with the same value and fraction but different
- * currency would return 0.
+ * Compare the value/fraction of two amounts. Does not compare the currency.
+ * Comparing amounts of different currencies will cause the program to abort().
+ * If unsure, check with #TALER_amount_cmp_currency() first to be sure that
+ * the currencies of the two amounts are identical.
*
* @param a1 first amount
* @param a2 second amount
* @return result of the comparison
*/
int
-TALER_amount_cmp (struct TALER_Amount a1,
- struct TALER_Amount a2);
+TALER_amount_cmp (const struct TALER_Amount *a1,
+ const struct TALER_Amount *a2);
+
+
+/**
+ * Test if @a a1 and @a a2 are the same currency.
+ *
+ * @param a1 amount to test
+ * @param a2 amount to test
+ * @return #GNUNET_YES if @a a1 and @a a2 are the same currency
+ * #GNUNET_NO if the currencies are different
+ * #GNUNET_SYSERR if either amount is invalid
+ */
+int
+TALER_amount_cmp_currency (const struct TALER_Amount *a1,
+ const struct TALER_Amount *a2);
/**
* Perform saturating subtraction of amounts.
*
+ * @param diff where to store (@a a1 - @a a2), or invalid if @a a2 > @a a1
* @param a1 amount to subtract from
* @param a2 amount to subtract
- * @return (a1-a2) or 0 if a2>=a1
+ * @return #GNUNET_OK if the subtraction worked,
+ * #GNUNET_NO if @a a1 = @a a2
+ * #GNUNET_SYSERR if @a a2 > @a a1 or currencies are incompatible;
+ * @a diff is set to invalid
*/
-struct TALER_Amount
-TALER_amount_subtract (struct TALER_Amount a1,
- struct TALER_Amount a2);
+int
+TALER_amount_subtract (struct TALER_Amount *diff,
+ const struct TALER_Amount *a1,
+ const struct TALER_Amount *a2);
/**
- * Perform saturating addition of amounts
+ * Perform addition of amounts.
*
+ * @param sum where to store @a a1 + @a a2, set to "invalid" on overflow
* @param a1 first amount to add
* @param a2 second amount to add
- * @return sum of a1 and a2
+ * @return #GNUNET_OK if the addition worked,
+ * #GNUNET_SYSERR on overflow
*/
-struct TALER_Amount
-TALER_amount_add (struct TALER_Amount a1,
- struct TALER_Amount a2);
+int
+TALER_amount_add (struct TALER_Amount *sum,
+ const struct TALER_Amount *a1,
+ const struct TALER_Amount *a2);
/**
* Normalize the given amount.
*
- * @param amout amount to normalize
- * @return normalized amount
+ * @param amount amount to normalize
+ * @return #GNUNET_OK if normalization worked
+ * #GNUNET_NO if value was already normalized
+ * #GNUNET_SYSERR if value was invalid or could not be normalized
*/
-struct TALER_Amount
-TALER_amount_normalize (struct TALER_Amount amount);
+int
+TALER_amount_normalize (struct TALER_Amount *amount);
/**
* Convert amount to string.
*
* @param amount amount to convert to string
- * @return freshly allocated string representation
+ * @return freshly allocated string representation,
+ * NULL if the @a amount was invalid
*/
char *
-TALER_amount_to_string (struct TALER_Amount amount);
+TALER_amount_to_string (const struct TALER_Amount *amount);
#endif
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index 1048b89f6..c5515966f 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -39,7 +39,7 @@
* @return a json object describing the amount
*/
json_t *
-TALER_JSON_from_amount (struct TALER_Amount amount);
+TALER_JSON_from_amount (const struct TALER_Amount *amount);
/**