LCOV - differential code coverage report
Current view: top level - src/common - base64.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 81.9 % 83 68 15 68
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 4 4 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 81.9 % 83 68 15 68
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 4 4 4

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * base64.c
                                  4                 :  *    Encoding and decoding routines for base64 without whitespace.
                                  5                 :  *
                                  6                 :  * Copyright (c) 2001-2023, PostgreSQL Global Development Group
                                  7                 :  *
                                  8                 :  *
                                  9                 :  * IDENTIFICATION
                                 10                 :  *    src/common/base64.c
                                 11                 :  *
                                 12                 :  *-------------------------------------------------------------------------
                                 13                 :  */
                                 14                 : 
                                 15                 : #ifndef FRONTEND
                                 16                 : #include "postgres.h"
                                 17                 : #else
                                 18                 : #include "postgres_fe.h"
                                 19                 : #endif
                                 20                 : 
                                 21                 : #include "common/base64.h"
                                 22                 : 
                                 23                 : /*
                                 24                 :  * BASE64
                                 25                 :  */
                                 26                 : 
                                 27                 : static const char _base64[] =
                                 28                 : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
                                 29                 : 
                                 30                 : static const int8 b64lookup[128] = {
                                 31                 :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                                 32                 :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                                 33                 :     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
                                 34                 :     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
                                 35                 :     -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                                 36                 :     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
                                 37                 :     -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
                                 38                 :     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
                                 39                 : };
                                 40                 : 
                                 41                 : /*
                                 42                 :  * pg_b64_encode
                                 43                 :  *
                                 44                 :  * Encode into base64 the given string.  Returns the length of the encoded
                                 45                 :  * string, and -1 in the event of an error with the result buffer zeroed
                                 46                 :  * for safety.
                                 47                 :  */
                                 48                 : int
 1375 michael                    49 CBC         267 : pg_b64_encode(const char *src, int len, char *dst, int dstlen)
                                 50                 : {
                                 51                 :     char       *p;
                                 52                 :     const char *s,
 2224 heikki.linnakangas         53             267 :                *end = src + len;
                                 54             267 :     int         pos = 2;
                                 55             267 :     uint32      buf = 0;
                                 56                 : 
                                 57             267 :     s = src;
                                 58             267 :     p = dst;
                                 59                 : 
                                 60            7385 :     while (s < end)
                                 61                 :     {
                                 62            7118 :         buf |= (unsigned char) *s << (pos << 3);
                                 63            7118 :         pos--;
                                 64            7118 :         s++;
                                 65                 : 
                                 66                 :         /* write it out */
                                 67            7118 :         if (pos < 0)
                                 68                 :         {
                                 69                 :             /*
                                 70                 :              * Leave if there is an overflow in the area allocated for the
                                 71                 :              * encoded string.
                                 72                 :              */
 1375 michael                    73            2254 :             if ((p - dst + 4) > dstlen)
 1375 michael                    74 UBC           0 :                 goto error;
                                 75                 : 
 2224 heikki.linnakangas         76 CBC        2254 :             *p++ = _base64[(buf >> 18) & 0x3f];
                                 77            2254 :             *p++ = _base64[(buf >> 12) & 0x3f];
                                 78            2254 :             *p++ = _base64[(buf >> 6) & 0x3f];
                                 79            2254 :             *p++ = _base64[buf & 0x3f];
                                 80                 : 
                                 81            2254 :             pos = 2;
                                 82            2254 :             buf = 0;
                                 83                 :         }
                                 84                 :     }
                                 85             267 :     if (pos != 2)
                                 86                 :     {
                                 87                 :         /*
                                 88                 :          * Leave if there is an overflow in the area allocated for the encoded
                                 89                 :          * string.
                                 90                 :          */
 1375 michael                    91             200 :         if ((p - dst + 4) > dstlen)
 1375 michael                    92 UBC           0 :             goto error;
                                 93                 : 
 2224 heikki.linnakangas         94 CBC         200 :         *p++ = _base64[(buf >> 18) & 0x3f];
                                 95             200 :         *p++ = _base64[(buf >> 12) & 0x3f];
                                 96             200 :         *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '=';
                                 97             200 :         *p++ = '=';
                                 98                 :     }
                                 99                 : 
 1375 michael                   100             267 :     Assert((p - dst) <= dstlen);
 2224 heikki.linnakangas        101             267 :     return p - dst;
                                102                 : 
 1375 michael                   103 UBC           0 : error:
                                104               0 :     memset(dst, 0, dstlen);
                                105               0 :     return -1;
                                106                 : }
                                107                 : 
                                108                 : /*
                                109                 :  * pg_b64_decode
                                110                 :  *
                                111                 :  * Decode the given base64 string.  Returns the length of the decoded
                                112                 :  * string on success, and -1 in the event of an error with the result
                                113                 :  * buffer zeroed for safety.
                                114                 :  */
                                115                 : int
 1375 michael                   116 CBC         557 : pg_b64_decode(const char *src, int len, char *dst, int dstlen)
                                117                 : {
 2224 heikki.linnakangas        118             557 :     const char *srcend = src + len,
                                119             557 :                *s = src;
                                120             557 :     char       *p = dst;
                                121                 :     char        c;
                                122             557 :     int         b = 0;
                                123             557 :     uint32      buf = 0;
                                124             557 :     int         pos = 0,
                                125             557 :                 end = 0;
                                126                 : 
                                127           21713 :     while (s < srcend)
                                128                 :     {
                                129           21156 :         c = *s++;
                                130                 : 
                                131                 :         /* Leave if a whitespace is found */
                                132           21156 :         if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
 1375 michael                   133 UBC           0 :             goto error;
                                134                 : 
 2224 heikki.linnakangas        135 CBC       21156 :         if (c == '=')
                                136                 :         {
                                137                 :             /* end sequence */
                                138             739 :             if (!end)
                                139                 :             {
                                140             548 :                 if (pos == 2)
                                141             191 :                     end = 1;
                                142             357 :                 else if (pos == 3)
                                143             357 :                     end = 2;
                                144                 :                 else
                                145                 :                 {
                                146                 :                     /*
                                147                 :                      * Unexpected "=" character found while decoding base64
                                148                 :                      * sequence.
                                149                 :                      */
 1375 michael                   150 UBC           0 :                     goto error;
                                151                 :                 }
                                152                 :             }
 2224 heikki.linnakangas        153 CBC         739 :             b = 0;
                                154                 :         }
                                155                 :         else
                                156                 :         {
                                157           20417 :             b = -1;
                                158           20417 :             if (c > 0 && c < 127)
                                159           20417 :                 b = b64lookup[(unsigned char) c];
                                160           20417 :             if (b < 0)
                                161                 :             {
                                162                 :                 /* invalid symbol found */
 1375 michael                   163 UBC           0 :                 goto error;
                                164                 :             }
                                165                 :         }
                                166                 :         /* add it to buffer */
 2224 heikki.linnakangas        167 CBC       21156 :         buf = (buf << 6) + b;
                                168           21156 :         pos++;
                                169           21156 :         if (pos == 4)
                                170                 :         {
                                171                 :             /*
                                172                 :              * Leave if there is an overflow in the area allocated for the
                                173                 :              * decoded string.
                                174                 :              */
 1375 michael                   175            5289 :             if ((p - dst + 1) > dstlen)
 1375 michael                   176 UBC           0 :                 goto error;
 2224 heikki.linnakangas        177 CBC        5289 :             *p++ = (buf >> 16) & 255;
                                178                 : 
                                179            5289 :             if (end == 0 || end > 1)
                                180                 :             {
                                181                 :                 /* overflow check */
 1375 michael                   182            5098 :                 if ((p - dst + 1) > dstlen)
 1375 michael                   183 UBC           0 :                     goto error;
 2224 heikki.linnakangas        184 CBC        5098 :                 *p++ = (buf >> 8) & 255;
                                185                 :             }
                                186            5289 :             if (end == 0 || end > 2)
                                187                 :             {
                                188                 :                 /* overflow check */
 1375 michael                   189            4741 :                 if ((p - dst + 1) > dstlen)
 1375 michael                   190 UBC           0 :                     goto error;
 2224 heikki.linnakangas        191 CBC        4741 :                 *p++ = buf & 255;
                                192                 :             }
                                193            5289 :             buf = 0;
                                194            5289 :             pos = 0;
                                195                 :         }
                                196                 :     }
                                197                 : 
                                198             557 :     if (pos != 0)
                                199                 :     {
                                200                 :         /*
                                201                 :          * base64 end sequence is invalid.  Input data is missing padding, is
                                202                 :          * truncated or is otherwise corrupted.
                                203                 :          */
 1375 michael                   204 UBC           0 :         goto error;
                                205                 :     }
                                206                 : 
 1375 michael                   207 CBC         557 :     Assert((p - dst) <= dstlen);
 2224 heikki.linnakangas        208             557 :     return p - dst;
                                209                 : 
 1375 michael                   210 UBC           0 : error:
                                211               0 :     memset(dst, 0, dstlen);
                                212               0 :     return -1;
                                213                 : }
                                214                 : 
                                215                 : /*
                                216                 :  * pg_b64_enc_len
                                217                 :  *
                                218                 :  * Returns to caller the length of the string if it were encoded with
                                219                 :  * base64 based on the length provided by caller.  This is useful to
                                220                 :  * estimate how large a buffer allocation needs to be done before doing
                                221                 :  * the actual encoding.
                                222                 :  */
                                223                 : int
 2224 heikki.linnakangas        224 CBC         267 : pg_b64_enc_len(int srclen)
                                225                 : {
                                226                 :     /* 3 bytes will be converted to 4 */
                                227             267 :     return (srclen + 2) * 4 / 3;
                                228                 : }
                                229                 : 
                                230                 : /*
                                231                 :  * pg_b64_dec_len
                                232                 :  *
                                233                 :  * Returns to caller the length of the string if it were to be decoded
                                234                 :  * with base64, based on the length given by caller.  This is useful to
                                235                 :  * estimate how large a buffer allocation needs to be done before doing
                                236                 :  * the actual decoding.
                                237                 :  */
                                238                 : int
                                239             557 : pg_b64_dec_len(int srclen)
                                240                 : {
                                241             557 :     return (srclen * 3) >> 2;
                                242                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a