LCOV - code coverage report
Current view: top level - util - util.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 63.9 % 147 94
Test Date: 2026-04-14 15:39:31 Functions: 69.2 % 13 9

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

Generated by: LCOV version 2.0-1