LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - pgp-armor.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 89.2 % 231 206 25 206
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 10 10 10
Baseline: 16@8cea358b128 Branches: 72.6 % 168 122 46 122
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 89.2 % 231 206 25 206
Function coverage date bins:
(240..) days: 100.0 % 10 10 10
Branch coverage date bins:
(240..) days: 72.6 % 168 122 46 122

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * pgp-armor.c
                                  3                 :                :  *      PGP ascii-armor.
                                  4                 :                :  *
                                  5                 :                :  * Copyright (c) 2005 Marko Kreen
                                  6                 :                :  * All rights reserved.
                                  7                 :                :  *
                                  8                 :                :  * Redistribution and use in source and binary forms, with or without
                                  9                 :                :  * modification, are permitted provided that the following conditions
                                 10                 :                :  * are met:
                                 11                 :                :  * 1. Redistributions of source code must retain the above copyright
                                 12                 :                :  *    notice, this list of conditions and the following disclaimer.
                                 13                 :                :  * 2. Redistributions in binary form must reproduce the above copyright
                                 14                 :                :  *    notice, this list of conditions and the following disclaimer in the
                                 15                 :                :  *    documentation and/or other materials provided with the distribution.
                                 16                 :                :  *
                                 17                 :                :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                                 18                 :                :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                                 19                 :                :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                                 20                 :                :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                                 21                 :                :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                                 22                 :                :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                                 23                 :                :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                                 24                 :                :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                                 25                 :                :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                                 26                 :                :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                                 27                 :                :  * SUCH DAMAGE.
                                 28                 :                :  *
                                 29                 :                :  * contrib/pgcrypto/pgp-armor.c
                                 30                 :                :  */
                                 31                 :                : 
                                 32                 :                : #include "postgres.h"
                                 33                 :                : 
                                 34                 :                : #include "pgp.h"
                                 35                 :                : #include "px.h"
                                 36                 :                : 
                                 37                 :                : /*
                                 38                 :                :  * BASE64 - duplicated :(
                                 39                 :                :  */
                                 40                 :                : 
                                 41                 :                : static const unsigned char _base64[] =
                                 42                 :                : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
                                 43                 :                : 
                                 44                 :                : static int
 2237 tgl@sss.pgh.pa.us          45                 :CBC          10 : pg_base64_encode(const uint8 *src, unsigned len, uint8 *dst)
                                 46                 :                : {
                                 47                 :                :     uint8      *p,
 6853 bruce@momjian.us           48                 :             10 :                *lend = dst + 76;
                                 49                 :                :     const uint8 *s,
                                 50                 :             10 :                *end = src + len;
                                 51                 :             10 :     int         pos = 2;
                                 52                 :             10 :     unsigned long buf = 0;
                                 53                 :                : 
                                 54                 :             10 :     s = src;
                                 55                 :             10 :     p = dst;
                                 56                 :                : 
                                 57         [ +  + ]:            131 :     while (s < end)
                                 58                 :                :     {
                                 59                 :            121 :         buf |= *s << (pos << 3);
                                 60                 :            121 :         pos--;
                                 61                 :            121 :         s++;
                                 62                 :                : 
                                 63                 :                :         /*
                                 64                 :                :          * write it out
                                 65                 :                :          */
                                 66         [ +  + ]:            121 :         if (pos < 0)
                                 67                 :                :         {
                                 68                 :             37 :             *p++ = _base64[(buf >> 18) & 0x3f];
                                 69                 :             37 :             *p++ = _base64[(buf >> 12) & 0x3f];
                                 70                 :             37 :             *p++ = _base64[(buf >> 6) & 0x3f];
                                 71                 :             37 :             *p++ = _base64[buf & 0x3f];
                                 72                 :                : 
                                 73                 :             37 :             pos = 2;
                                 74                 :             37 :             buf = 0;
                                 75                 :                :         }
                                 76         [ +  + ]:            121 :         if (p >= lend)
                                 77                 :                :         {
                                 78                 :              1 :             *p++ = '\n';
                                 79                 :              1 :             lend = p + 76;
                                 80                 :                :         }
                                 81                 :                :     }
                                 82         [ +  + ]:             10 :     if (pos != 2)
                                 83                 :                :     {
                                 84                 :              6 :         *p++ = _base64[(buf >> 18) & 0x3f];
                                 85                 :              6 :         *p++ = _base64[(buf >> 12) & 0x3f];
                                 86         [ +  + ]:              6 :         *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '=';
                                 87                 :              6 :         *p++ = '=';
                                 88                 :                :     }
                                 89                 :                : 
                                 90                 :             10 :     return p - dst;
                                 91                 :                : }
                                 92                 :                : 
                                 93                 :                : /* probably should use lookup table */
                                 94                 :                : static int
 2237 tgl@sss.pgh.pa.us          95                 :            178 : pg_base64_decode(const uint8 *src, unsigned len, uint8 *dst)
                                 96                 :                : {
 6853 bruce@momjian.us           97                 :            178 :     const uint8 *srcend = src + len,
 6756                            98                 :            178 :                *s = src;
 6853                            99                 :            178 :     uint8      *p = dst;
                                100                 :                :     char        c;
                                101                 :            178 :     unsigned    b = 0;
                                102                 :            178 :     unsigned long buf = 0;
                                103                 :            178 :     int         pos = 0,
 6756                           104                 :            178 :                 end = 0;
                                105                 :                : 
 6853                           106         [ +  + ]:          85130 :     while (s < srcend)
                                107                 :                :     {
                                108                 :          84952 :         c = *s++;
                                109   [ +  +  +  + ]:          84952 :         if (c >= 'A' && c <= 'Z')
                                110                 :          35636 :             b = c - 'A';
                                111   [ +  +  +  - ]:          49316 :         else if (c >= 'a' && c <= 'z')
                                112                 :          32762 :             b = c - 'a' + 26;
                                113   [ +  +  +  + ]:          16554 :         else if (c >= '0' && c <= '9')
                                114                 :          12460 :             b = c - '0' + 52;
                                115         [ +  + ]:           4094 :         else if (c == '+')
                                116                 :           1302 :             b = 62;
                                117         [ +  + ]:           2792 :         else if (c == '/')
                                118                 :           1344 :             b = 63;
                                119         [ +  + ]:           1448 :         else if (c == '=')
                                120                 :                :         {
                                121                 :                :             /*
                                122                 :                :              * end sequence
                                123                 :                :              */
                                124         [ +  + ]:            116 :             if (!end)
                                125                 :                :             {
                                126         [ +  + ]:             67 :                 if (pos == 2)
                                127                 :             49 :                     end = 1;
                                128         [ +  - ]:             18 :                 else if (pos == 3)
                                129                 :             18 :                     end = 2;
                                130                 :                :                 else
 6853 bruce@momjian.us          131                 :UBC           0 :                     return PXE_PGP_CORRUPT_ARMOR;
                                132                 :                :             }
 6853 bruce@momjian.us          133                 :CBC         116 :             b = 0;
                                134                 :                :         }
                                135   [ +  +  +  -  :           1332 :         else if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
                                        -  +  -  - ]
                                136                 :           1332 :             continue;
                                137                 :                :         else
 6853 bruce@momjian.us          138                 :UBC           0 :             return PXE_PGP_CORRUPT_ARMOR;
                                139                 :                : 
                                140                 :                :         /*
                                141                 :                :          * add it to buffer
                                142                 :                :          */
 6853 bruce@momjian.us          143                 :CBC       83620 :         buf = (buf << 6) + b;
                                144                 :          83620 :         pos++;
                                145         [ +  + ]:          83620 :         if (pos == 4)
                                146                 :                :         {
                                147                 :          20905 :             *p++ = (buf >> 16) & 255;
                                148   [ +  +  +  + ]:          20905 :             if (end == 0 || end > 1)
                                149                 :          20856 :                 *p++ = (buf >> 8) & 255;
                                150   [ +  +  -  + ]:          20905 :             if (end == 0 || end > 2)
                                151                 :          20838 :                 *p++ = buf & 255;
                                152                 :          20905 :             buf = 0;
                                153                 :          20905 :             pos = 0;
                                154                 :                :         }
                                155                 :                :     }
                                156                 :                : 
                                157         [ -  + ]:            178 :     if (pos != 0)
 6853 bruce@momjian.us          158                 :UBC           0 :         return PXE_PGP_CORRUPT_ARMOR;
 6853 bruce@momjian.us          159                 :CBC         178 :     return p - dst;
                                160                 :                : }
                                161                 :                : 
                                162                 :                : static unsigned
 2237 tgl@sss.pgh.pa.us         163                 :             10 : pg_base64_enc_len(unsigned srclen)
                                164                 :                : {
                                165                 :                :     /*
                                166                 :                :      * 3 bytes will be converted to 4, linefeed after 76 chars
                                167                 :                :      */
  311                           168                 :             10 :     return (srclen + 2) / 3 * 4 + srclen / (76 * 3 / 4);
                                169                 :                : }
                                170                 :                : 
                                171                 :                : static unsigned
 2237                           172                 :             89 : pg_base64_dec_len(unsigned srclen)
                                173                 :                : {
 6853 bruce@momjian.us          174                 :             89 :     return (srclen * 3) >> 2;
                                175                 :                : }
                                176                 :                : 
                                177                 :                : /*
                                178                 :                :  * PGP armor
                                179                 :                :  */
                                180                 :                : 
                                181                 :                : static const char *const armor_header = "-----BEGIN PGP MESSAGE-----\n";
                                182                 :                : static const char *const armor_footer = "\n-----END PGP MESSAGE-----\n";
                                183                 :                : 
                                184                 :                : /* CRC24 implementation from rfc2440 */
                                185                 :                : #define CRC24_INIT 0x00b704ceL
                                186                 :                : #define CRC24_POLY 0x01864cfbL
                                187                 :                : static long
                                188                 :             99 : crc24(const uint8 *data, unsigned len)
                                189                 :                : {
                                190                 :             99 :     unsigned    crc = CRC24_INIT;
                                191                 :                :     int         i;
                                192                 :                : 
                                193         [ +  + ]:          62552 :     while (len--)
                                194                 :                :     {
                                195                 :          62453 :         crc ^= (*data++) << 16;
                                196         [ +  + ]:         562077 :         for (i = 0; i < 8; i++)
                                197                 :                :         {
                                198                 :         499624 :             crc <<= 1;
                                199         [ +  + ]:         499624 :             if (crc & 0x1000000)
                                200                 :         250230 :                 crc ^= CRC24_POLY;
                                201                 :                :         }
                                202                 :                :     }
                                203                 :             99 :     return crc & 0xffffffL;
                                204                 :                : }
                                205                 :                : 
                                206                 :                : void
 3483 heikki.linnakangas@i      207                 :             10 : pgp_armor_encode(const uint8 *src, unsigned len, StringInfo dst,
                                208                 :                :                  int num_headers, char **keys, char **values)
                                209                 :                : {
                                210                 :                :     int         n;
                                211                 :                :     int         res;
                                212                 :                :     unsigned    b64len;
 6853 bruce@momjian.us          213                 :             10 :     unsigned    crc = crc24(src, len);
                                214                 :                : 
 3489 heikki.linnakangas@i      215                 :             10 :     appendStringInfoString(dst, armor_header);
                                216                 :                : 
 3483                           217         [ +  + ]:             17 :     for (n = 0; n < num_headers; n++)
                                218                 :              7 :         appendStringInfo(dst, "%s: %s\n", keys[n], values[n]);
                                219                 :             10 :     appendStringInfoChar(dst, '\n');
                                220                 :                : 
                                221                 :                :     /* make sure we have enough room to pg_base64_encode() */
 2237 tgl@sss.pgh.pa.us         222                 :             10 :     b64len = pg_base64_enc_len(len);
 3489 heikki.linnakangas@i      223                 :             10 :     enlargeStringInfo(dst, (int) b64len);
                                224                 :                : 
 2237 tgl@sss.pgh.pa.us         225                 :             10 :     res = pg_base64_encode(src, len, (uint8 *) dst->data + dst->len);
 3489 heikki.linnakangas@i      226         [ -  + ]:             10 :     if (res > b64len)
 3489 heikki.linnakangas@i      227         [ #  # ]:UBC           0 :         elog(FATAL, "overflow - encode estimate too small");
 3489 heikki.linnakangas@i      228                 :CBC          10 :     dst->len += res;
                                229                 :                : 
                                230         [ +  + ]:             10 :     if (*(dst->data + dst->len - 1) != '\n')
                                231                 :              6 :         appendStringInfoChar(dst, '\n');
                                232                 :                : 
                                233                 :             10 :     appendStringInfoChar(dst, '=');
                                234                 :             10 :     appendStringInfoChar(dst, _base64[(crc >> 18) & 0x3f]);
                                235                 :             10 :     appendStringInfoChar(dst, _base64[(crc >> 12) & 0x3f]);
                                236                 :             10 :     appendStringInfoChar(dst, _base64[(crc >> 6) & 0x3f]);
                                237                 :             10 :     appendStringInfoChar(dst, _base64[crc & 0x3f]);
                                238                 :                : 
                                239                 :             10 :     appendStringInfoString(dst, armor_footer);
 6853 bruce@momjian.us          240                 :             10 : }
                                241                 :                : 
                                242                 :                : static const uint8 *
                                243                 :            207 : find_str(const uint8 *data, const uint8 *data_end, const char *str, int strlen)
                                244                 :                : {
                                245                 :            207 :     const uint8 *p = data;
                                246                 :                : 
                                247         [ -  + ]:            207 :     if (!strlen)
 6853 bruce@momjian.us          248                 :UBC           0 :         return NULL;
 6853 bruce@momjian.us          249         [ -  + ]:CBC         207 :     if (data_end - data < strlen)
 6853 bruce@momjian.us          250                 :UBC           0 :         return NULL;
 6756 bruce@momjian.us          251         [ +  - ]:CBC         222 :     while (p < data_end)
                                252                 :                :     {
 6853                           253                 :            222 :         p = memchr(p, str[0], data_end - p);
                                254         [ -  + ]:            222 :         if (p == NULL)
 6853 bruce@momjian.us          255                 :UBC           0 :             return NULL;
 6853 bruce@momjian.us          256         [ -  + ]:CBC         222 :         if (p + strlen > data_end)
 6853 bruce@momjian.us          257                 :UBC           0 :             return NULL;
 6853 bruce@momjian.us          258         [ +  + ]:CBC         222 :         if (memcmp(p, str, strlen) == 0)
                                259                 :            207 :             return p;
                                260                 :             15 :         p++;
                                261                 :                :     }
 6853 bruce@momjian.us          262                 :UBC           0 :     return NULL;
                                263                 :                : }
                                264                 :                : 
                                265                 :                : static int
 6853 bruce@momjian.us          266                 :CBC         206 : find_header(const uint8 *data, const uint8 *datend,
                                267                 :                :             const uint8 **start_p, int is_end)
                                268                 :                : {
                                269                 :            206 :     const uint8 *p = data;
                                270                 :                :     static const char *start_sep = "-----BEGIN";
                                271                 :                :     static const char *end_sep = "-----END";
                                272         [ +  + ]:            206 :     const char *sep = is_end ? end_sep : start_sep;
                                273                 :                : 
                                274                 :                :     /* find header line */
                                275                 :                :     while (1)
                                276                 :                :     {
                                277                 :            207 :         p = find_str(p, datend, sep, strlen(sep));
                                278         [ -  + ]:            207 :         if (p == NULL)
 6853 bruce@momjian.us          279                 :UBC           0 :             return PXE_PGP_CORRUPT_ARMOR;
                                280                 :                :         /* it must start at beginning of line */
 6853 bruce@momjian.us          281   [ +  +  +  + ]:CBC         207 :         if (p == data || *(p - 1) == '\n')
                                282                 :                :             break;
                                283                 :              1 :         p += strlen(sep);
                                284                 :                :     }
                                285                 :            206 :     *start_p = p;
                                286                 :            206 :     p += strlen(sep);
                                287                 :                : 
                                288                 :                :     /* check if header text ok */
                                289   [ +  -  +  + ]:           3412 :     for (; p < datend && *p != '-'; p++)
                                290                 :                :     {
                                291                 :                :         /* various junk can be there, but definitely not line-feed  */
                                292         [ +  - ]:           3206 :         if (*p >= ' ')
                                293                 :           3206 :             continue;
 6853 bruce@momjian.us          294                 :UBC           0 :         return PXE_PGP_CORRUPT_ARMOR;
                                295                 :                :     }
 6853 bruce@momjian.us          296   [ +  -  -  + ]:CBC         206 :     if (datend - p < 5 || memcmp(p, sep, 5) != 0)
 6853 bruce@momjian.us          297                 :UBC           0 :         return PXE_PGP_CORRUPT_ARMOR;
 6853 bruce@momjian.us          298                 :CBC         206 :     p += 5;
                                299                 :                : 
                                300                 :                :     /* check if at end of line */
                                301         [ +  + ]:            206 :     if (p < datend)
                                302                 :                :     {
                                303   [ +  +  -  + ]:            205 :         if (*p != '\n' && *p != '\r')
 6853 bruce@momjian.us          304                 :UBC           0 :             return PXE_PGP_CORRUPT_ARMOR;
 6853 bruce@momjian.us          305         [ +  + ]:CBC         205 :         if (*p == '\r')
                                306                 :              2 :             p++;
                                307   [ +  -  +  - ]:            205 :         if (p < datend && *p == '\n')
                                308                 :            205 :             p++;
                                309                 :                :     }
                                310                 :            206 :     return p - *start_p;
                                311                 :                : }
                                312                 :                : 
                                313                 :                : int
 3489 heikki.linnakangas@i      314                 :             89 : pgp_armor_decode(const uint8 *src, int len, StringInfo dst)
                                315                 :                : {
 6853 bruce@momjian.us          316                 :             89 :     const uint8 *p = src;
                                317                 :             89 :     const uint8 *data_end = src + len;
                                318                 :                :     long        crc;
                                319                 :                :     const uint8 *base64_start,
                                320                 :                :                *armor_end;
                                321                 :             89 :     const uint8 *base64_end = NULL;
                                322                 :                :     uint8       buf[4];
                                323                 :                :     int         hlen;
                                324                 :                :     int         blen;
                                325                 :             89 :     int         res = PXE_PGP_CORRUPT_ARMOR;
                                326                 :                : 
                                327                 :                :     /* armor start */
                                328                 :             89 :     hlen = find_header(src, data_end, &p, 0);
                                329         [ -  + ]:             89 :     if (hlen <= 0)
 6853 bruce@momjian.us          330                 :UBC           0 :         goto out;
 6853 bruce@momjian.us          331                 :CBC          89 :     p += hlen;
                                332                 :                : 
                                333                 :                :     /* armor end */
                                334                 :             89 :     hlen = find_header(p, data_end, &armor_end, 1);
                                335         [ -  + ]:             89 :     if (hlen <= 0)
 6853 bruce@momjian.us          336                 :UBC           0 :         goto out;
                                337                 :                : 
                                338                 :                :     /* skip comments - find empty line */
 6853 bruce@momjian.us          339   [ +  -  +  +  :CBC         168 :     while (p < armor_end && *p != '\n' && *p != '\r')
                                              +  - ]
                                340                 :                :     {
                                341                 :             79 :         p = memchr(p, '\n', armor_end - p);
                                342         [ -  + ]:             79 :         if (!p)
 6853 bruce@momjian.us          343                 :UBC           0 :             goto out;
                                344                 :                : 
                                345                 :                :         /* step to start of next line */
 6853 bruce@momjian.us          346                 :CBC          79 :         p++;
                                347                 :                :     }
                                348                 :             89 :     base64_start = p;
                                349                 :                : 
                                350                 :                :     /* find crc pos */
                                351         [ +  - ]:            624 :     for (p = armor_end; p >= base64_start; p--)
                                352         [ +  + ]:            624 :         if (*p == '=')
                                353                 :                :         {
                                354                 :             89 :             base64_end = p - 1;
                                355                 :             89 :             break;
                                356                 :                :         }
                                357         [ -  + ]:             89 :     if (base64_end == NULL)
 6853 bruce@momjian.us          358                 :UBC           0 :         goto out;
                                359                 :                : 
                                360                 :                :     /* decode crc */
 2237 tgl@sss.pgh.pa.us         361         [ -  + ]:CBC          89 :     if (pg_base64_decode(p + 1, 4, buf) != 3)
 6853 bruce@momjian.us          362                 :UBC           0 :         goto out;
 6756 bruce@momjian.us          363                 :CBC          89 :     crc = (((long) buf[0]) << 16) + (((long) buf[1]) << 8) + (long) buf[2];
                                364                 :                : 
                                365                 :                :     /* decode data */
 2237 tgl@sss.pgh.pa.us         366                 :             89 :     blen = (int) pg_base64_dec_len(len);
 3489 heikki.linnakangas@i      367                 :             89 :     enlargeStringInfo(dst, blen);
 2237 tgl@sss.pgh.pa.us         368                 :             89 :     res = pg_base64_decode(base64_start, base64_end - base64_start, (uint8 *) dst->data);
 3489 heikki.linnakangas@i      369         [ -  + ]:             89 :     if (res > blen)
 3489 heikki.linnakangas@i      370         [ #  # ]:UBC           0 :         elog(FATAL, "overflow - decode estimate too small");
 3489 heikki.linnakangas@i      371         [ -  + ]:CBC          89 :     if (res >= 0)
                                372                 :                :     {
                                373         [ +  + ]:             89 :         if (crc24((uint8 *) dst->data, res) == crc)
                                374                 :             88 :             dst->len += res;
                                375                 :                :         else
                                376                 :              1 :             res = PXE_PGP_CORRUPT_ARMOR;
                                377                 :                :     }
 6853 bruce@momjian.us          378                 :UBC           0 : out:
 6853 bruce@momjian.us          379                 :CBC          89 :     return res;
                                380                 :                : }
                                381                 :                : 
                                382                 :                : /*
                                383                 :                :  * Extracts all armor headers from an ASCII-armored input.
                                384                 :                :  *
                                385                 :                :  * Returns 0 on success, or PXE_* error code on error. On success, the
                                386                 :                :  * number of headers and their keys and values are returned in *nheaders,
                                387                 :                :  * *nkeys and *nvalues.
                                388                 :                :  */
                                389                 :                : int
 3483 heikki.linnakangas@i      390                 :             14 : pgp_extract_armor_headers(const uint8 *src, unsigned len,
                                391                 :                :                           int *nheaders, char ***keys, char ***values)
                                392                 :                : {
                                393                 :             14 :     const uint8 *data_end = src + len;
                                394                 :                :     const uint8 *p;
                                395                 :                :     const uint8 *base64_start;
                                396                 :                :     const uint8 *armor_start;
                                397                 :                :     const uint8 *armor_end;
                                398                 :                :     Size        armor_len;
                                399                 :                :     char       *line;
                                400                 :                :     char       *nextline;
                                401                 :                :     char       *eol,
                                402                 :                :                *colon;
                                403                 :                :     int         hlen;
                                404                 :                :     char       *buf;
                                405                 :                :     int         hdrlines;
                                406                 :                :     int         n;
                                407                 :                : 
                                408                 :                :     /* armor start */
                                409                 :             14 :     hlen = find_header(src, data_end, &armor_start, 0);
                                410         [ -  + ]:             14 :     if (hlen <= 0)
 3483 heikki.linnakangas@i      411                 :UBC           0 :         return PXE_PGP_CORRUPT_ARMOR;
 3483 heikki.linnakangas@i      412                 :CBC          14 :     armor_start += hlen;
                                413                 :                : 
                                414                 :                :     /* armor end */
                                415                 :             14 :     hlen = find_header(armor_start, data_end, &armor_end, 1);
                                416         [ -  + ]:             14 :     if (hlen <= 0)
 3483 heikki.linnakangas@i      417                 :UBC           0 :         return PXE_PGP_CORRUPT_ARMOR;
                                418                 :                : 
                                419                 :                :     /* Count the number of armor header lines. */
 3483 heikki.linnakangas@i      420                 :CBC          14 :     hdrlines = 0;
                                421                 :             14 :     p = armor_start;
                                422   [ +  +  +  +  :             40 :     while (p < armor_end && *p != '\n' && *p != '\r')
                                              +  + ]
                                423                 :                :     {
                                424                 :             26 :         p = memchr(p, '\n', armor_end - p);
                                425         [ -  + ]:             26 :         if (!p)
 3483 heikki.linnakangas@i      426                 :UBC           0 :             return PXE_PGP_CORRUPT_ARMOR;
                                427                 :                : 
                                428                 :                :         /* step to start of next line */
 3483 heikki.linnakangas@i      429                 :CBC          26 :         p++;
                                430                 :             26 :         hdrlines++;
                                431                 :                :     }
                                432                 :             14 :     base64_start = p;
                                433                 :                : 
                                434                 :                :     /*
                                435                 :                :      * Make a modifiable copy of the part of the input that contains the
                                436                 :                :      * headers. The returned key/value pointers will point inside the buffer.
                                437                 :                :      */
                                438                 :             14 :     armor_len = base64_start - armor_start;
                                439                 :             14 :     buf = palloc(armor_len + 1);
                                440                 :             14 :     memcpy(buf, armor_start, armor_len);
                                441                 :             14 :     buf[armor_len] = '\0';
                                442                 :                : 
                                443                 :                :     /* Allocate return arrays */
                                444                 :             14 :     *keys = (char **) palloc(hdrlines * sizeof(char *));
                                445                 :             14 :     *values = (char **) palloc(hdrlines * sizeof(char *));
                                446                 :                : 
                                447                 :                :     /*
                                448                 :                :      * Split the header lines at newlines and ": " separators, and collect
                                449                 :                :      * pointers to the keys and values in the return arrays.
                                450                 :                :      */
                                451                 :             14 :     n = 0;
                                452                 :             14 :     line = buf;
                                453                 :                :     for (;;)
                                454                 :                :     {
                                455                 :                :         /* find end of line */
                                456                 :             60 :         eol = strchr(line, '\n');
                                457         [ +  + ]:             37 :         if (!eol)
                                458                 :             12 :             break;
                                459                 :             25 :         nextline = eol + 1;
                                460                 :                :         /* if the line ends in CR + LF, strip the CR */
                                461   [ +  -  +  + ]:             25 :         if (eol > line && *(eol - 1) == '\r')
                                462                 :              2 :             eol--;
                                463                 :             25 :         *eol = '\0';
                                464                 :                : 
                                465                 :                :         /* find colon+space separating the key and value */
                                466                 :             25 :         colon = strstr(line, ": ");
                                467         [ +  + ]:             25 :         if (!colon)
                                468                 :              2 :             return PXE_PGP_CORRUPT_ARMOR;
                                469                 :             23 :         *colon = '\0';
                                470                 :                : 
                                471                 :                :         /* shouldn't happen, we counted the number of lines beforehand */
                                472         [ -  + ]:             23 :         if (n >= hdrlines)
 3483 heikki.linnakangas@i      473         [ #  # ]:UBC           0 :             elog(ERROR, "unexpected number of armor header lines");
                                474                 :                : 
 3483 heikki.linnakangas@i      475                 :CBC          23 :         (*keys)[n] = line;
                                476                 :             23 :         (*values)[n] = colon + 2;
                                477                 :             23 :         n++;
                                478                 :                : 
                                479                 :                :         /* step to start of next line */
                                480                 :             23 :         line = nextline;
                                481                 :                :     }
                                482                 :                : 
                                483         [ -  + ]:             12 :     if (n != hdrlines)
 3483 heikki.linnakangas@i      484         [ #  # ]:UBC           0 :         elog(ERROR, "unexpected number of armor header lines");
                                485                 :                : 
 3483 heikki.linnakangas@i      486                 :CBC          12 :     *nheaders = n;
                                487                 :             12 :     return 0;
                                488                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622