LCOV - code coverage report
Current view: top level - port - cpl_base64.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 64 71 90.1 %
Date: 2024-04-28 21:03:45 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Common Portability Library
       4             :  * Purpose:  Encoding/Decoding Base64 strings
       5             :  * Author:   Paul Ramsey <pramsey@cleverelephant.ca>
       6             :  *           Dave Blasby <dblasby@gmail.com>
       7             :  *           René Nyffenegger
       8             :  *
       9             :  ******************************************************************************
      10             :  * Copyright (c) 2008 Paul Ramsey
      11             :  * Copyright (c) 2002 Refractions Research
      12             :  * Copyright (C) 2004-2008 René Nyffenegger
      13             :  * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
      14             :  *
      15             :  * (see also part way down the file for license terms for René's code)
      16             :  *
      17             :  * Permission is hereby granted, free of charge, to any person obtaining a
      18             :  * copy of this software and associated documentation files (the "Software"),
      19             :  * to deal in the Software without restriction, including without limitation
      20             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      21             :  * and/or sell copies of the Software, and to permit persons to whom the
      22             :  * Software is furnished to do so, subject to the following conditions:
      23             :  *
      24             :  * The above copyright notice and this permission notice shall be included in
      25             :  * all copies of this Software or works derived from this Software.
      26             :  *
      27             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      28             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      29             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      30             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      31             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      32             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      33             :  * DEALINGS IN THE SOFTWARE.
      34             :  ****************************************************************************/
      35             : 
      36             : #include "cpl_port.h"
      37             : #include "cpl_string.h"
      38             : 
      39             : #include <string>
      40             : 
      41             : #include "cpl_conv.h"
      42             : 
      43             : // Derived from MapServer's mappostgis.c.
      44             : 
      45             : /*
      46             : ** Decode a base64 character.
      47             : */
      48             : constexpr unsigned char CPLBase64DecodeChar[256] = {
      49             :     // Not Base64 characters.
      50             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      51             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      52             :     64, 64, 64, 64, 64,
      53             :     // +
      54             :     62,
      55             :     // Not Base64 characters.
      56             :     64, 64, 64,
      57             :     //  /
      58             :     63,
      59             :     // 0-9
      60             :     52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
      61             :     // Not Base64 characters.
      62             :     64, 64, 64, 64, 64, 64, 64,
      63             :     // A-Z
      64             :     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
      65             :     21, 22, 23, 24, 25,
      66             :     // Not Base64 characters.
      67             :     64, 64, 64, 64, 64, 64,
      68             :     // a-z
      69             :     26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
      70             :     45, 46, 47, 48, 49, 50, 51,
      71             :     // Not Base64 characters.
      72             :     64, 64, 64, 64, 64,
      73             :     // Not Base64 characters (upper 128 characters).
      74             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      75             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      76             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      77             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      78             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      79             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      80             :     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64};
      81             : 
      82             : /************************************************************************/
      83             : /*                       CPLBase64DecodeInPlace()                       */
      84             : /************************************************************************/
      85             : 
      86             : /** Decode base64 string "pszBase64" (null terminated) in place.
      87             :  *
      88             :  * Returns length of decoded array or 0 on failure.
      89             :  */
      90        1296 : int CPLBase64DecodeInPlace(GByte *pszBase64)
      91             : {
      92        1296 :     if (pszBase64 && *pszBase64)
      93             :     {
      94        1296 :         unsigned char *p = pszBase64;
      95        1296 :         int offset_1 = 0;
      96        1296 :         int offset_2 = 0;
      97             : 
      98             :         // Drop illegal chars first.
      99      850034 :         for (; pszBase64[offset_1]; ++offset_1)
     100             :         {
     101      848738 :             unsigned char c = pszBase64[offset_1];
     102      848738 :             if ((CPLBase64DecodeChar[c] != 64) || (c == '='))
     103             :             {
     104      848315 :                 pszBase64[offset_2++] = c;
     105             :             }
     106             :         }
     107             : 
     108      213377 :         for (int idx = 0; idx < offset_2; idx += 4)
     109             :         {
     110      212081 :             unsigned char b1 = CPLBase64DecodeChar[pszBase64[idx]];
     111      212081 :             unsigned char b2 = 0;
     112      212081 :             unsigned char c3 = 'A';
     113      212081 :             unsigned char c4 = 'A';
     114             : 
     115      212081 :             if (idx + 3 < offset_2)
     116             :             {
     117      212078 :                 b2 = CPLBase64DecodeChar[pszBase64[idx + 1]];
     118      212078 :                 c3 = pszBase64[idx + 2];
     119      212078 :                 c4 = pszBase64[idx + 3];
     120             :             }
     121           3 :             else if (idx + 2 < offset_2)
     122             :             {
     123           0 :                 b2 = CPLBase64DecodeChar[pszBase64[idx + 1]];
     124           0 :                 c3 = pszBase64[idx + 2];
     125             :             }
     126           3 :             else if (idx + 1 < offset_2)
     127             :             {
     128           0 :                 b2 = CPLBase64DecodeChar[pszBase64[idx + 1]];
     129             :                 // c3 = 'A';
     130             :             }  // Else: Use the default values.
     131             : 
     132      212081 :             const unsigned char b3 = CPLBase64DecodeChar[c3];
     133      212081 :             const unsigned char b4 = CPLBase64DecodeChar[c4];
     134             : 
     135      212081 :             *p++ = ((b1 << 2) | (b2 >> 4));
     136      212081 :             if (p - pszBase64 == offset_1)
     137           0 :                 break;
     138      212081 :             if (c3 != '=')
     139             :             {
     140      212066 :                 *p++ = (((b2 & 0xf) << 4) | (b3 >> 2));
     141      212066 :                 if (p - pszBase64 == offset_1)
     142           0 :                     break;
     143             :             }
     144      212081 :             if (c4 != '=')
     145             :             {
     146      212051 :                 *p++ = (((b3 & 0x3) << 6) | b4);
     147      212051 :                 if (p - pszBase64 == offset_1)
     148           0 :                     break;
     149             :             }
     150             :         }
     151        1296 :         return static_cast<int>(p - pszBase64);
     152             :     }
     153           0 :     return 0;
     154             : }
     155             : 
     156             : /*
     157             :  * This function was extracted from the base64 cpp utility published by
     158             :  * René Nyffenegger. The code was modified into a form suitable for use in
     159             :  * CPL.  The original code can be found at:
     160             :  *
     161             :  * http://www.adp-gmbh.ch/cpp/common/base64.html.
     162             :  *
     163             :  * The following is the original notice of this function.
     164             :  *
     165             :  * base64.cpp and base64.h
     166             :  *
     167             :  *  Copyright (C) 2004-2008 René Nyffenegger
     168             :  *
     169             :  *  This source code is provided 'as-is', without any express or implied
     170             :  *  warranty. In no event will the author be held liable for any damages
     171             :  *  arising from the use of this software.
     172             :  *
     173             :  *  Permission is granted to anyone to use this software for any purpose,
     174             :  *  including commercial applications, and to alter it and redistribute it
     175             :  *  freely, subject to the following restrictions:
     176             :  *
     177             :  *  1. The origin of this source code must not be misrepresented; you must not
     178             :  *     claim that you wrote the original source code. If you use this source
     179             :  *     code in a product, an acknowledgment in the product documentation would
     180             :  *     be appreciated but is not required.
     181             :  *
     182             :  *  2. Altered source versions must be plainly marked as such, and must not be
     183             :  *     misrepresented as being the original source code.
     184             :  *
     185             :  *  3. This notice may not be removed or altered from any source distribution.
     186             :  *
     187             :  *  René Nyffenegger rene.nyffenegger@adp-gmbh.ch
     188             :  */
     189             : 
     190             : /************************************************************************/
     191             : /*                          CPLBase64Encode()                           */
     192             : /************************************************************************/
     193             : 
     194             : /** Base64 encode a buffer. */
     195             : 
     196         415 : char *CPLBase64Encode(int nDataLen, const GByte *pabyBytesToEncode)
     197             : {
     198         415 :     constexpr char base64Chars[] =
     199             :         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     200             : 
     201         415 :     const int kCharArray3Size = 3;
     202         415 :     const int kCharArray4Size = 4;
     203         415 :     unsigned char charArray3[kCharArray3Size] = {};
     204             : 
     205         830 :     std::string result("");
     206         415 :     int array3_idx = 0;
     207     1241850 :     while (nDataLen--)
     208             :     {
     209     1241430 :         charArray3[array3_idx++] = *(pabyBytesToEncode++);
     210             : 
     211     1241430 :         if (array3_idx == kCharArray3Size)
     212             :         {
     213             :             const unsigned char charArray4[kCharArray4Size] = {
     214      413552 :                 static_cast<unsigned char>((charArray3[0] & 0xfc) >> 2),
     215      413552 :                 static_cast<unsigned char>(((charArray3[0] & 0x03) << 4) +
     216      413552 :                                            ((charArray3[1] & 0xf0) >> 4)),
     217      413552 :                 static_cast<unsigned char>(((charArray3[1] & 0x0f) << 2) +
     218      413552 :                                            ((charArray3[2] & 0xc0) >> 6)),
     219      413552 :                 static_cast<unsigned char>(charArray3[2] & 0x3f)};
     220             : 
     221     2067760 :             for (int idx = 0; idx < kCharArray4Size; ++idx)
     222             :             {
     223     1654210 :                 result += base64Chars[charArray4[idx]];
     224             :             }
     225             : 
     226      413552 :             array3_idx = 0;
     227             :         }
     228             :     }
     229             : 
     230         415 :     if (array3_idx)
     231             :     {
     232         841 :         for (int idx = array3_idx; idx < kCharArray3Size; ++idx)
     233             :         {
     234         437 :             charArray3[idx] = '\0';
     235             :         }
     236             : 
     237             :         const unsigned char charArray4[kCharArray4Size] = {
     238         404 :             static_cast<unsigned char>((charArray3[0] & 0xfc) >> 2),
     239         404 :             static_cast<unsigned char>(((charArray3[0] & 0x03) << 4) +
     240         404 :                                        ((charArray3[1] & 0xf0) >> 4)),
     241         404 :             static_cast<unsigned char>(((charArray3[1] & 0x0f) << 2) +
     242         404 :                                        ((charArray3[2] & 0xc0) >> 6)),
     243         404 :             static_cast<unsigned char>(charArray3[2] & 0x3f)};
     244             : 
     245        1583 :         for (int idx = 0; idx < (array3_idx + 1); ++idx)
     246             :         {
     247        1179 :             result += base64Chars[charArray4[idx]];
     248             :         }
     249             : 
     250         841 :         while (array3_idx++ < kCharArray3Size)
     251         437 :             result += '=';
     252             :     }
     253             : 
     254         830 :     return CPLStrdup(result.c_str());
     255             : }

Generated by: LCOV version 1.14