LCOV - code coverage report
Current view: top level - src - base64.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 91.8 % 49 45
Test Date: 2026-06-18 09:49:19 Functions: 100.0 % 2 2

            Line data    Source code
       1              : // base64 encodig and decoding.
       2              : //
       3              : // Based on the implementations by
       4              : // Jouni Malinen <j@w1.fi> and contributors from wpa_supplicant and hostapd in
       5              : // http://web.mit.edu/freebsd/head/contrib/wpa/ and
       6              : // http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c and
       7              : // http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.h
       8              : //
       9              : // Published under a 3-clause BSD license
      10              : //
      11              : 
      12              : #include <string>
      13              : #include <cstring>
      14              : #include <stdexcept>
      15              : 
      16              : #include "crpropa/base64.h"
      17              : 
      18              : namespace crpropa
      19              : {
      20              : 
      21              : //Alphabet used
      22              : static const unsigned char encode_alphabet[65] =
      23              : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      24              : static int decode_alphabet[256] = {-1};
      25              : 
      26              : /// Encodes data
      27           99 : std::string Base64::encode(const unsigned char *src, size_t len)
      28              : {
      29           99 :                 size_t olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */
      30              : 
      31           99 :                 if (olen < len)
      32            0 :                         throw std::runtime_error("Integer overflow in Base64::encoding, data to large!");
      33              : 
      34              :                 std::string outStr;
      35              :                 outStr.resize(olen);
      36              : 
      37              :                 unsigned char *out = (unsigned char*) outStr.c_str();
      38              :                 unsigned char *pos = out;
      39              :                 const unsigned char *end, *in;
      40              : 
      41           99 :                 end = src + len;
      42              :                 in = src;
      43         6666 :                 while (end - in >= 3) {
      44         6567 :                                 *pos++ = encode_alphabet[in[0] >> 2];
      45         6567 :                                 *pos++ = encode_alphabet[((in[0] & 0x03) << 4) | (in[1] >> 4)];
      46         6567 :                                 *pos++ = encode_alphabet[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
      47         6567 :                                 *pos++ = encode_alphabet[in[2] & 0x3f];
      48         6567 :                                 in += 3;
      49              :                 }
      50              : 
      51           99 :                 if (end - in) {
      52           66 :                                 *pos++ = encode_alphabet[in[0] >> 2];
      53           66 :                                 if (end - in == 1) {
      54           33 :                                                 *pos++ = encode_alphabet[(in[0] & 0x03) << 4];
      55           33 :                                                 *pos++ = '=';
      56              :                                 }
      57              :                                 else {
      58           33 :                                                 *pos++ = encode_alphabet[((in[0] & 0x03) << 4) |
      59           33 :                                                                 (in[1] >> 4)];
      60           33 :                                                 *pos++ = encode_alphabet[(in[1] & 0x0f) << 2];
      61              :                                 }
      62           66 :                                 *pos++ = '=';
      63              :                 }
      64              : 
      65           99 :                 return outStr;
      66              : }
      67              : 
      68              : 
      69          100 : std::string Base64::decode(const std::string &data)
      70              : {
      71              : const unsigned char *src = (unsigned char*) data.c_str();
      72              : size_t len = data.size();
      73              : 
      74          100 : if (decode_alphabet[0] == -1)
      75              : { // build decode alphabet
      76              :         std::memset(decode_alphabet, 0x80, 256);
      77           65 :         for (size_t i = 0; i < sizeof(encode_alphabet) - 1; i++)
      78           64 :                 decode_alphabet[encode_alphabet[i]] = (unsigned char) i;
      79            1 :         decode_alphabet['='] = 0;
      80              : }
      81              : 
      82              : size_t olen = 0;
      83        26656 : for (size_t i = 0; i < len; i++) {
      84        26556 :         if (decode_alphabet[src[i]] != 0x80)
      85        26556 :                 olen++;
      86              : }
      87              : 
      88          100 : if (olen == 0 || olen % 4)
      89            0 :                         throw std::runtime_error("Base64 decode, invalid input size");
      90              : 
      91          100 : olen = olen / 4 * 3;
      92              : std::string str;
      93              : str.resize(olen);
      94              : 
      95              : unsigned char *out = (unsigned char*) str.c_str();
      96              : unsigned char *pos = out;
      97              : 
      98              : size_t count = 0;
      99              : int pad = 0;
     100              : unsigned char block[4];
     101        26589 : for (size_t i = 0; i < len; i++) {
     102        26556 :         unsigned char tmp = decode_alphabet[src[i]];
     103        26556 :         if (tmp == 0x80)
     104            0 :                 continue;
     105              : 
     106        26556 :         if (src[i] == '=')
     107          101 :                 pad++;
     108        26556 :         block[count] = tmp;
     109        26556 :         count++;
     110        26556 :         if (count == 4) {
     111         6639 :                 *pos++ = (block[0] << 2) | (block[1] >> 4);
     112         6639 :                 *pos++ = (block[1] << 4) | (block[2] >> 2);
     113         6639 :                 *pos++ = (block[2] << 6) | block[3];
     114              :                 count = 0;
     115         6639 :                 if (pad) {
     116           67 :                         if (pad == 1)
     117              :                                 pos--;
     118           34 :                         else if (pad == 2)
     119              :                                 pos -= 2;
     120              :                         else {
     121            0 :                                 throw std::runtime_error("Base64 decode, invalid padding");
     122              :                         }
     123              :                         break;
     124              :                 }
     125              :         }
     126              : }
     127          100 : return str;
     128              : }
     129              : };
        

Generated by: LCOV version 2.0-1