differential code coverage report with master
Current view: top level - source/detail/cryptography - base64.cpp (source / functions) Coverage Total Hit UBC CBC
Current: coverage.info Lines: 100.0 % 87 87 87
Current Date: 2025-12-15 23:01:28 Functions: 100.0 % 3 3 3
Baseline: coverage_master.info Branches: 90.6 % 53 48 10 96
Baseline Date: 2025-12-15 23:01:27

             Branch data    TLA  Line data    Source code
       1                 :                : // Copyright (C) 2017-2022 Thomas Fussell
       2                 :                : // Copyright (C) 2013 Tomas Kislan
       3                 :                : // Copyright (C) 2013 Adam Rudd
       4                 :                : // Copyright (c) 2024-2025 xlnt-community
       5                 :                : //
       6                 :                : // Permission is hereby granted, free of charge, to any person obtaining a copy
       7                 :                : // of this software and associated documentation files (the "Software"), to deal
       8                 :                : // in the Software without restriction, including without limitation the rights
       9                 :                : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      10                 :                : // copies of the Software, and to permit persons to whom the Software is
      11                 :                : // furnished to do so, subject to the following conditions:
      12                 :                : //
      13                 :                : // The above copyright notice and this permission notice shall be included in
      14                 :                : // all copies or substantial portions of the Software.
      15                 :                : //
      16                 :                : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      17                 :                : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      18                 :                : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      19                 :                : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      20                 :                : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      21                 :                : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      22                 :                : // THE SOFTWARE.
      23                 :                : 
      24                 :                : #include <detail/cryptography/base64.hpp>
      25                 :                : #include <array>
      26                 :                : 
      27                 :                : namespace xlnt {
      28                 :                : namespace detail {
      29                 :                : 
      30                 :CBC          28 : std::string encode_base64(const std::vector<std::uint8_t> &input)
      31                 :                : {
      32                 :             28 :     auto encoded_length = (input.size() + 2 - ((input.size() + 2) % 3)) / 3 * 4;
      33            [ + ]:             28 :     auto output = std::string(encoded_length, '\0');
      34                 :             28 :     auto input_iterator = input.begin();
      35                 :             28 :     auto output_iterator = output.begin();
      36                 :             28 :     auto i = std::size_t(0);
      37                 :             28 :     auto j = std::size_t(0);
      38                 :             28 :     std::array<std::uint8_t, 3> a3{{0}};
      39                 :             28 :     std::array<std::uint8_t, 4> a4{{0}};
      40                 :                : 
      41                 :                :     const std::string alphabet(
      42                 :                :         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      43                 :                :         "abcdefghijklmnopqrstuvwxyz"
      44            [ + ]:             28 :         "0123456789+/");
      45                 :                : 
      46         [ +  + ]:           1144 :     while (input_iterator != input.end())
      47                 :                :     {
      48                 :           1088 :         a3[i++] = *input_iterator++;
      49                 :                : 
      50         [ +  + ]:           1088 :         if (i == 3)
      51                 :                :         {
      52                 :            352 :             a4[0] = (a3[0] & 0xfc) >> 2;
      53                 :            352 :             a4[1] = static_cast<std::uint8_t>(((a3[0] & 0x03) << 4)
      54                 :            352 :                 + ((a3[1] & 0xf0) >> 4));
      55                 :            352 :             a4[2] = static_cast<std::uint8_t>(((a3[1] & 0x0f) << 2)
      56                 :            352 :                 + ((a3[2] & 0xc0) >> 6));
      57                 :            352 :             a4[3] = (a3[2] & 0x3f);
      58                 :                : 
      59         [ +  + ]:           1760 :             for (i = 0; i < 4; i++)
      60                 :                :             {
      61                 :           1408 :                 *output_iterator++ = alphabet[a4[i]];
      62                 :                :             }
      63                 :                : 
      64                 :            352 :             i = 0;
      65                 :                :         }
      66                 :                :     }
      67                 :                : 
      68         [ +  - ]:             28 :     if (i != 0)
      69                 :                :     {
      70         [ +  + ]:             80 :         for (j = i; j < 3; j++)
      71                 :                :         {
      72                 :             52 :             a3[j] = 0;
      73                 :                :         }
      74                 :                : 
      75                 :             28 :         a4[0] = (a3[0] & 0xfc) >> 2;
      76                 :             28 :         a4[1] = static_cast<std::uint8_t>(((a3[0] & 0x03) << 4)
      77                 :             28 :             + ((a3[1] & 0xf0) >> 4));
      78                 :             28 :         a4[2] = static_cast<std::uint8_t>(((a3[1] & 0x0f) << 2)
      79                 :             28 :             + ((a3[2] & 0xc0) >> 6));
      80                 :             28 :         a4[3] = (a3[2] & 0x3f);
      81                 :                : 
      82         [ +  + ]:             88 :         for (j = 0; j < i + 1; j++)
      83                 :                :         {
      84                 :             60 :             *output_iterator++ = alphabet[a4[j]];
      85                 :                :         }
      86                 :                : 
      87         [ +  + ]:             80 :         while (i++ < 3)
      88                 :                :         {
      89                 :             52 :             *output_iterator++ = '=';
      90                 :                :         }
      91                 :                :     }
      92                 :                : 
      93                 :             28 :     return output;
      94                 :             28 : }
      95                 :                : 
      96                 :             42 : std::vector<std::uint8_t> decode_base64(const std::string &input)
      97                 :                : {
      98                 :             42 :     std::size_t padding_count = 0;
      99                 :             42 :     auto in_end = input.data() + input.size();
     100                 :                : 
     101         [ +  + ]:            114 :     while (*--in_end == '=')
     102                 :                :     {
     103                 :             72 :         ++padding_count;
     104                 :                :     }
     105                 :                : 
     106                 :             42 :     auto decoded_length = ((6 * input.size()) / 8) - padding_count;
     107            [ + ]:             42 :     auto output = std::vector<std::uint8_t>(decoded_length);
     108                 :             42 :     auto input_iterator = input.begin();
     109                 :             42 :     auto output_iterator = output.begin();
     110                 :             42 :     auto i = std::size_t(0);
     111                 :             42 :     auto j = std::size_t(0);
     112                 :             42 :     std::array<std::uint8_t, 3> a3{{0}};
     113                 :             42 :     std::array<std::uint8_t, 4> a4{{0}};
     114                 :                : 
     115                 :           1824 :     auto b64_lookup = [](std::uint8_t c) -> std::uint8_t {
     116   [ +  +  +  + ]:           1824 :         if (c >= 'A' && c <= 'Z') return c - 'A';
     117   [ +  +  +  - ]:           1134 :         if (c >= 'a' && c <= 'z') return c - 71;
     118   [ +  +  +  - ]:            396 :         if (c >= '0' && c <= '9') return c + 4;
     119         [ +  + ]:            111 :         if (c == '+') return 62;
     120         [ +  + ]:             93 :         if (c == '/') return 63;
     121                 :             72 :         return 255;
     122                 :                :     };
     123                 :                : 
     124         [ +  - ]:           1836 :     while (input_iterator != input.end())
     125                 :                :     {
     126         [ +  + ]:           1794 :         if (*input_iterator == '=')
     127                 :                :         {
     128                 :             42 :             break;
     129                 :                :         }
     130                 :                : 
     131                 :           1752 :         a4[i++] = static_cast<std::uint8_t>(*(input_iterator++));
     132                 :                : 
     133         [ +  + ]:           1752 :         if (i == 4)
     134                 :                :         {
     135         [ +  + ]:           2070 :             for (i = 0; i < 4; i++)
     136                 :                :             {
     137                 :           1656 :                 a4[i] = b64_lookup(a4[i]);
     138                 :                :             }
     139                 :                : 
     140                 :            414 :             a3[0] = static_cast<std::uint8_t>(a4[0] << 2)
     141                 :            414 :                 + static_cast<std::uint8_t>((a4[1] & 0x30) >> 4);
     142                 :            414 :             a3[1] = static_cast<std::uint8_t>((a4[1] & 0xf) << 4)
     143                 :            414 :                 + static_cast<std::uint8_t>((a4[2] & 0x3c) >> 2);
     144                 :            414 :             a3[2] = static_cast<std::uint8_t>((a4[2] & 0x3) << 6)
     145                 :            414 :                 + static_cast<std::uint8_t>(a4[3]);
     146                 :                : 
     147         [ +  + ]:           1656 :             for (i = 0; i < 3; i++)
     148                 :                :             {
     149                 :           1242 :                 *output_iterator++ = a3[i];
     150                 :                :             }
     151                 :                : 
     152                 :            414 :             i = 0;
     153                 :                :         }
     154                 :                :     }
     155                 :                : 
     156         [ +  - ]:             42 :     if (i != 0)
     157                 :                :     {
     158         [ +  + ]:            114 :         for (j = i; j < 4; j++)
     159                 :                :         {
     160                 :             72 :             a4[j] = 0;
     161                 :                :         }
     162                 :                : 
     163         [ +  + ]:            210 :         for (j = 0; j < 4; j++)
     164                 :                :         {
     165                 :            168 :             a4[j] = b64_lookup(a4[j]);
     166                 :                :         }
     167                 :                : 
     168                 :             42 :         a3[0] = static_cast<std::uint8_t>(a4[0] << 2)
     169                 :             42 :             + static_cast<std::uint8_t>((a4[1] & 0x30) >> 4);
     170                 :             42 :         a3[1] = static_cast<std::uint8_t>((a4[1] & 0xf) << 4)
     171                 :             42 :             + static_cast<std::uint8_t>((a4[2] & 0x3c) >> 2);
     172                 :             42 :         a3[2] = static_cast<std::uint8_t>((a4[2] & 0x3) << 6)
     173                 :             42 :             + static_cast<std::uint8_t>(a4[3]);
     174                 :                : 
     175         [ +  + ]:             96 :         for (j = 0; j < i - 1; j++)
     176                 :                :         {
     177                 :             54 :             *output_iterator++ = a3[j];
     178                 :                :         }
     179                 :                :     }
     180                 :                : 
     181                 :             42 :     return output;
     182                 :                : }
     183                 :                : 
     184                 :                : } // namespace detail
     185                 :                : } // namespace xlnt
        

Generated by: LCOV version 2.3.1-beta