LCOV - code coverage report
Current view: top level - util - util.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 94 147 63.9 %
Date: 2025-06-05 21:03:14 Functions: 9 13 69.2 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2023 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it under the
       6             :   terms of the GNU General Public License as published by the Free Software
       7             :   Foundation; either version 3, or (at your option) any later version.
       8             : 
       9             :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10             :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11             :   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12             : 
      13             :   You should have received a copy of the GNU General Public License along with
      14             :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15             : */
      16             : /**
      17             :  * @file util.c
      18             :  * @brief Common utility functions
      19             :  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
      20             :  * @author Florian Dold
      21             :  * @author Benedikt Mueller
      22             :  * @author Christian Grothoff
      23             :  */
      24             : #include "platform.h"
      25             : #include "taler_util.h"
      26             : #include "taler_attributes.h"
      27             : #include <gnunet/gnunet_json_lib.h>
      28             : #include <unistr.h>
      29             : 
      30             : 
      31             : const char *
      32      224983 : TALER_b2s (const void *buf,
      33             :            size_t buf_size)
      34             : {
      35             :   static TALER_THREAD_LOCAL char ret[9];
      36             :   struct GNUNET_HashCode hc;
      37             :   char *tmp;
      38             : 
      39      224983 :   GNUNET_CRYPTO_hash (buf,
      40             :                       buf_size,
      41             :                       &hc);
      42      224983 :   tmp = GNUNET_STRINGS_data_to_string_alloc (&hc,
      43             :                                              sizeof (hc));
      44      224983 :   GNUNET_memcpy (ret,
      45             :                  tmp,
      46             :                  8);
      47      224983 :   GNUNET_free (tmp);
      48      224983 :   ret[8] = '\0';
      49      224983 :   return ret;
      50             : }
      51             : 
      52             : 
      53             : void
      54       93010 : TALER_denom_fee_set_hton (struct TALER_DenomFeeSetNBOP *nbo,
      55             :                           const struct TALER_DenomFeeSet *fees)
      56             : {
      57       93010 :   TALER_amount_hton (&nbo->withdraw,
      58             :                      &fees->withdraw);
      59       93010 :   TALER_amount_hton (&nbo->deposit,
      60             :                      &fees->deposit);
      61       93010 :   TALER_amount_hton (&nbo->refresh,
      62             :                      &fees->refresh);
      63       93010 :   TALER_amount_hton (&nbo->refund,
      64             :                      &fees->refund);
      65       93010 : }
      66             : 
      67             : 
      68             : void
      69           0 : TALER_denom_fee_set_ntoh (struct TALER_DenomFeeSet *fees,
      70             :                           const struct TALER_DenomFeeSetNBOP *nbo)
      71             : {
      72           0 :   TALER_amount_ntoh (&fees->withdraw,
      73             :                      &nbo->withdraw);
      74           0 :   TALER_amount_ntoh (&fees->deposit,
      75             :                      &nbo->deposit);
      76           0 :   TALER_amount_ntoh (&fees->refresh,
      77             :                      &nbo->refresh);
      78           0 :   TALER_amount_ntoh (&fees->refund,
      79             :                      &nbo->refund);
      80           0 : }
      81             : 
      82             : 
      83             : void
      84         127 : TALER_global_fee_set_hton (struct TALER_GlobalFeeSetNBOP *nbo,
      85             :                            const struct TALER_GlobalFeeSet *fees)
      86             : {
      87         127 :   TALER_amount_hton (&nbo->history,
      88             :                      &fees->history);
      89         127 :   TALER_amount_hton (&nbo->account,
      90             :                      &fees->account);
      91         127 :   TALER_amount_hton (&nbo->purse,
      92             :                      &fees->purse);
      93         127 : }
      94             : 
      95             : 
      96             : void
      97           0 : TALER_global_fee_set_ntoh (struct TALER_GlobalFeeSet *fees,
      98             :                            const struct TALER_GlobalFeeSetNBOP *nbo)
      99             : {
     100           0 :   TALER_amount_ntoh (&fees->history,
     101             :                      &nbo->history);
     102           0 :   TALER_amount_ntoh (&fees->account,
     103             :                      &nbo->account);
     104           0 :   TALER_amount_ntoh (&fees->purse,
     105             :                      &nbo->purse);
     106           0 : }
     107             : 
     108             : 
     109             : void
     110         161 : TALER_wire_fee_set_hton (struct TALER_WireFeeSetNBOP *nbo,
     111             :                          const struct TALER_WireFeeSet *fees)
     112             : {
     113         161 :   TALER_amount_hton (&nbo->wire,
     114             :                      &fees->wire);
     115         161 :   TALER_amount_hton (&nbo->closing,
     116             :                      &fees->closing);
     117         161 : }
     118             : 
     119             : 
     120             : void
     121           0 : TALER_wire_fee_set_ntoh (struct TALER_WireFeeSet *fees,
     122             :                          const struct TALER_WireFeeSetNBOP *nbo)
     123             : {
     124           0 :   TALER_amount_ntoh (&fees->wire,
     125             :                      &nbo->wire);
     126           0 :   TALER_amount_ntoh (&fees->closing,
     127             :                      &nbo->closing);
     128           0 : }
     129             : 
     130             : 
     131             : int
     132           0 : TALER_global_fee_set_cmp (const struct TALER_GlobalFeeSet *f1,
     133             :                           const struct TALER_GlobalFeeSet *f2)
     134             : {
     135             :   int ret;
     136             : 
     137           0 :   ret = TALER_amount_cmp (&f1->history,
     138             :                           &f2->history);
     139           0 :   if (0 != ret)
     140           0 :     return ret;
     141           0 :   ret = TALER_amount_cmp (&f1->account,
     142             :                           &f2->account);
     143           0 :   if (0 != ret)
     144           0 :     return ret;
     145           0 :   ret = TALER_amount_cmp (&f1->purse,
     146             :                           &f2->purse);
     147           0 :   if (0 != ret)
     148           0 :     return ret;
     149           0 :   return 0;
     150             : }
     151             : 
     152             : 
     153             : int
     154           4 : TALER_wire_fee_set_cmp (const struct TALER_WireFeeSet *f1,
     155             :                         const struct TALER_WireFeeSet *f2)
     156             : {
     157             :   int ret;
     158             : 
     159           4 :   ret = TALER_amount_cmp (&f1->wire,
     160             :                           &f2->wire);
     161           4 :   if (0 != ret)
     162           0 :     return ret;
     163           4 :   ret = TALER_amount_cmp (&f1->closing,
     164             :                           &f2->closing);
     165           4 :   if (0 != ret)
     166           2 :     return ret;
     167           2 :   return 0;
     168             : }
     169             : 
     170             : 
     171             : enum GNUNET_GenericReturnValue
     172       24904 : TALER_denom_fee_check_currency (
     173             :   const char *currency,
     174             :   const struct TALER_DenomFeeSet *fees)
     175             : {
     176       24904 :   if (GNUNET_YES !=
     177       24904 :       TALER_amount_is_currency (&fees->withdraw,
     178             :                                 currency))
     179             :   {
     180           0 :     GNUNET_break (0);
     181           0 :     return GNUNET_NO;
     182             :   }
     183       24904 :   if (GNUNET_YES !=
     184       24904 :       TALER_amount_is_currency (&fees->deposit,
     185             :                                 currency))
     186             :   {
     187           0 :     GNUNET_break (0);
     188           0 :     return GNUNET_NO;
     189             :   }
     190       24904 :   if (GNUNET_YES !=
     191       24904 :       TALER_amount_is_currency (&fees->refresh,
     192             :                                 currency))
     193             :   {
     194           0 :     GNUNET_break (0);
     195           0 :     return GNUNET_NO;
     196             :   }
     197       24904 :   if (GNUNET_YES !=
     198       24904 :       TALER_amount_is_currency (&fees->refund,
     199             :                                 currency))
     200             :   {
     201           0 :     GNUNET_break (0);
     202           0 :     return GNUNET_NO;
     203             :   }
     204       24904 :   return GNUNET_OK;
     205             : }
     206             : 
     207             : 
     208             : /**
     209             :  * Dump character in the low range into @a buf
     210             :  * following RFC 8785.
     211             :  *
     212             :  * @param[in,out] buf buffer to modify
     213             :  * @param val value to dump
     214             :  */
     215             : static void
     216           3 : lowdump (struct GNUNET_Buffer *buf,
     217             :          unsigned char val)
     218             : {
     219             :   char scratch[7];
     220             : 
     221           3 :   switch (val)
     222             :   {
     223           0 :   case 0x8:
     224           0 :     GNUNET_buffer_write (buf,
     225             :                          "\\b",
     226             :                          2);
     227           0 :     break;
     228           0 :   case 0x9:
     229           0 :     GNUNET_buffer_write (buf,
     230             :                          "\\t",
     231             :                          2);
     232           0 :     break;
     233           0 :   case 0xA:
     234           0 :     GNUNET_buffer_write (buf,
     235             :                          "\\n",
     236             :                          2);
     237           0 :     break;
     238           0 :   case 0xC:
     239           0 :     GNUNET_buffer_write (buf,
     240             :                          "\\f",
     241             :                          2);
     242           0 :     break;
     243           0 :   case 0xD:
     244           0 :     GNUNET_buffer_write (buf,
     245             :                          "\\r",
     246             :                          2);
     247           0 :     break;
     248           3 :   default:
     249           3 :     GNUNET_snprintf (scratch,
     250             :                      sizeof (scratch),
     251             :                      "\\u%04x",
     252             :                      (unsigned int) val);
     253           3 :     GNUNET_buffer_write (buf,
     254             :                          scratch,
     255             :                          6);
     256           3 :     break;
     257             :   }
     258           3 : }
     259             : 
     260             : 
     261             : size_t
     262         627 : TALER_rfc8785encode (char **inp)
     263             : {
     264         627 :   struct GNUNET_Buffer buf = { 0 };
     265         627 :   size_t left = strlen (*inp) + 1;
     266             :   size_t olen;
     267         627 :   char *in = *inp;
     268         627 :   const char *pos = in;
     269             : 
     270         627 :   GNUNET_buffer_prealloc (&buf,
     271             :                           left + 40);
     272         627 :   buf.warn_grow = 0; /* disable, + 40 is just a wild guess */
     273             :   while (1)
     274       50998 :   {
     275       51625 :     int mbl = u8_mblen ((unsigned char *) pos,
     276             :                         left);
     277             :     unsigned char val;
     278             : 
     279       51625 :     if (0 == mbl)
     280         627 :       break;
     281       50998 :     val = (unsigned char) *pos;
     282       50998 :     if ( (1 == mbl) &&
     283             :          (val <= 0x1F) )
     284             :     {
     285             :       /* Should not happen, as input is produced by
     286             :        * JSON stringification */
     287           0 :       GNUNET_break (0);
     288           0 :       lowdump (&buf,
     289             :                val);
     290             :     }
     291       50998 :     else if ( (1 == mbl) && ('\\' == *pos) )
     292             :     {
     293           8 :       switch (*(pos + 1))
     294             :       {
     295           1 :       case '\\':
     296           1 :         mbl = 2;
     297           1 :         GNUNET_buffer_write (&buf,
     298             :                              pos,
     299             :                              mbl);
     300           1 :         break;
     301           3 :       case 'u':
     302             :         {
     303             :           unsigned int num;
     304             :           uint32_t n32;
     305             :           unsigned char res[8];
     306             :           size_t rlen;
     307             : 
     308           3 :           GNUNET_assert ( (1 ==
     309             :                            sscanf (pos + 2,
     310             :                                    "%4x",
     311             :                                    &num)) ||
     312             :                           (1 ==
     313             :                            sscanf (pos + 2,
     314             :                                    "%4X",
     315             :                                    &num)) );
     316           3 :           mbl = 6;
     317           3 :           n32 = (uint32_t) num;
     318           3 :           rlen = sizeof (res);
     319           3 :           u32_to_u8 (&n32,
     320             :                      1,
     321             :                      res,
     322             :                      &rlen);
     323           3 :           if ( (1 == rlen) &&
     324           3 :                (res[0] <= 0x1F) )
     325             :           {
     326           3 :             lowdump (&buf,
     327           3 :                      res[0]);
     328             :           }
     329             :           else
     330             :           {
     331           0 :             GNUNET_buffer_write (&buf,
     332             :                                  (const char *) res,
     333             :                                  rlen);
     334             :           }
     335             :         }
     336           3 :         break;
     337           4 :       default:
     338           4 :         mbl = 2;
     339           4 :         GNUNET_buffer_write (&buf,
     340             :                              pos,
     341             :                              mbl);
     342           4 :         break;
     343             :       }
     344             :     }
     345             :     else
     346             :     {
     347       50990 :       GNUNET_buffer_write (&buf,
     348             :                            pos,
     349             :                            mbl);
     350             :     }
     351       50998 :     left -= mbl;
     352       50998 :     pos += mbl;
     353             :   }
     354             : 
     355             :   /* 0-terminate buffer */
     356         627 :   GNUNET_buffer_write (&buf,
     357             :                        "",
     358             :                        1);
     359         627 :   GNUNET_free (in);
     360         627 :   *inp = GNUNET_buffer_reap (&buf,
     361             :                              &olen);
     362         627 :   return olen;
     363             : }
     364             : 
     365             : 
     366             : /**
     367             :  * Hash normalized @a j JSON object or array and
     368             :  * store the result in @a hc.
     369             :  *
     370             :  * @param j JSON to hash
     371             :  * @param[out] hc where to write the hash
     372             :  */
     373             : void
     374         410 : TALER_json_hash (const json_t *j,
     375             :                  struct GNUNET_HashCode *hc)
     376             : {
     377             :   char *cstr;
     378             :   size_t clen;
     379             : 
     380         410 :   cstr = json_dumps (j,
     381             :                      JSON_COMPACT | JSON_SORT_KEYS);
     382         410 :   GNUNET_assert (NULL != cstr);
     383         410 :   clen = TALER_rfc8785encode (&cstr);
     384         410 :   GNUNET_CRYPTO_hash (cstr,
     385             :                       clen,
     386             :                       hc);
     387         410 :   GNUNET_free (cstr);
     388         410 : }
     389             : 
     390             : 
     391             : #ifdef __APPLE__
     392             : char *
     393             : strchrnul (const char *s,
     394             :            int c)
     395             : {
     396             :   char *value;
     397             :   value = strchr (s,
     398             :                   c);
     399             :   if (NULL == value)
     400             :     value = &s[strlen (s)];
     401             :   return value;
     402             : }
     403             : 
     404             : 
     405             : #endif
     406             : 
     407             : 
     408             : /* end of util.c */

Generated by: LCOV version 1.16