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-01-09 13:26:54 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 "taler/taler_attributes.h"
      27              : #include <gnunet/gnunet_json_lib.h>
      28              : #include <unistr.h>
      29              : 
      30              : 
      31              : const char *
      32       173189 : 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       173189 :   GNUNET_CRYPTO_hash (buf,
      40              :                       buf_size,
      41              :                       &hc);
      42       173189 :   tmp = GNUNET_STRINGS_data_to_string_alloc (&hc,
      43              :                                              sizeof (hc));
      44       173189 :   GNUNET_memcpy (ret,
      45              :                  tmp,
      46              :                  8);
      47       173189 :   GNUNET_free (tmp);
      48       173189 :   ret[8] = '\0';
      49       173189 :   return ret;
      50              : }
      51              : 
      52              : 
      53              : void
      54        47101 : TALER_denom_fee_set_hton (struct TALER_DenomFeeSetNBOP *nbo,
      55              :                           const struct TALER_DenomFeeSet *fees)
      56              : {
      57        47101 :   TALER_amount_hton (&nbo->withdraw,
      58              :                      &fees->withdraw);
      59        47101 :   TALER_amount_hton (&nbo->deposit,
      60              :                      &fees->deposit);
      61        47101 :   TALER_amount_hton (&nbo->refresh,
      62              :                      &fees->refresh);
      63        47101 :   TALER_amount_hton (&nbo->refund,
      64              :                      &fees->refund);
      65        47101 : }
      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          193 : TALER_global_fee_set_hton (struct TALER_GlobalFeeSetNBOP *nbo,
      85              :                            const struct TALER_GlobalFeeSet *fees)
      86              : {
      87          193 :   TALER_amount_hton (&nbo->history,
      88              :                      &fees->history);
      89          193 :   TALER_amount_hton (&nbo->account,
      90              :                      &fees->account);
      91          193 :   TALER_amount_hton (&nbo->purse,
      92              :                      &fees->purse);
      93          193 : }
      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          208 : TALER_wire_fee_set_hton (struct TALER_WireFeeSetNBOP *nbo,
     111              :                          const struct TALER_WireFeeSet *fees)
     112              : {
     113          208 :   TALER_amount_hton (&nbo->wire,
     114              :                      &fees->wire);
     115          208 :   TALER_amount_hton (&nbo->closing,
     116              :                      &fees->closing);
     117          208 : }
     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        16150 : TALER_denom_fee_check_currency (
     173              :   const char *currency,
     174              :   const struct TALER_DenomFeeSet *fees)
     175              : {
     176        16150 :   if (GNUNET_YES !=
     177        16150 :       TALER_amount_is_currency (&fees->withdraw,
     178              :                                 currency))
     179              :   {
     180            0 :     GNUNET_break (0);
     181            0 :     return GNUNET_NO;
     182              :   }
     183        16150 :   if (GNUNET_YES !=
     184        16150 :       TALER_amount_is_currency (&fees->deposit,
     185              :                                 currency))
     186              :   {
     187            0 :     GNUNET_break (0);
     188            0 :     return GNUNET_NO;
     189              :   }
     190        16150 :   if (GNUNET_YES !=
     191        16150 :       TALER_amount_is_currency (&fees->refresh,
     192              :                                 currency))
     193              :   {
     194            0 :     GNUNET_break (0);
     195            0 :     return GNUNET_NO;
     196              :   }
     197        16150 :   if (GNUNET_YES !=
     198        16150 :       TALER_amount_is_currency (&fees->refund,
     199              :                                 currency))
     200              :   {
     201            0 :     GNUNET_break (0);
     202            0 :     return GNUNET_NO;
     203              :   }
     204        16150 :   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          527 : TALER_rfc8785encode (char **inp)
     263              : {
     264          527 :   struct GNUNET_Buffer buf = { 0 };
     265          527 :   size_t left = strlen (*inp) + 1;
     266              :   size_t olen;
     267          527 :   char *in = *inp;
     268          527 :   const char *pos = in;
     269              : 
     270          527 :   GNUNET_buffer_prealloc (&buf,
     271              :                           left + 40);
     272          527 :   buf.warn_grow = 0; /* disable, + 40 is just a wild guess */
     273              :   while (1)
     274        17354 :   {
     275        17881 :     int mbl = u8_mblen ((unsigned char *) pos,
     276              :                         left);
     277              :     unsigned char val;
     278              : 
     279        17881 :     if (0 == mbl)
     280          527 :       break;
     281        17354 :     val = (unsigned char) *pos;
     282        17354 :     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        17354 :     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        17346 :       GNUNET_buffer_write (&buf,
     348              :                            pos,
     349              :                            mbl);
     350              :     }
     351        17354 :     left -= mbl;
     352        17354 :     pos += mbl;
     353              :   }
     354              : 
     355              :   /* 0-terminate buffer */
     356          527 :   GNUNET_buffer_write (&buf,
     357              :                        "",
     358              :                        1);
     359          527 :   GNUNET_free (in);
     360          527 :   *inp = GNUNET_buffer_reap (&buf,
     361              :                              &olen);
     362          527 :   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          346 : TALER_json_hash (const json_t *j,
     375              :                  struct GNUNET_HashCode *hc)
     376              : {
     377              :   char *cstr;
     378              :   size_t clen;
     379              : 
     380          346 :   cstr = json_dumps (j,
     381              :                      JSON_COMPACT | JSON_SORT_KEYS);
     382          346 :   GNUNET_assert (NULL != cstr);
     383          346 :   clen = TALER_rfc8785encode (&cstr);
     384          346 :   GNUNET_CRYPTO_hash (cstr,
     385              :                       clen,
     386              :                       hc);
     387          346 :   GNUNET_free (cstr);
     388          346 : }
     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 2.0-1