LCOV - code coverage report
Current view: top level - media/webrtc/signaling/src/sdp/sipcc - sdp_base64.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 103 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "sdp_base64.h"
       6             : 
       7             : /*
       8             :  * Local definitions for Base64 to Raw table entries.
       9             :  */
      10             : #define INVALID_CHAR 0xFF /* Character not in supported Base64 set */
      11             : #define WHITE_SPACE  0xFE /* Space, tab, newline, etc character */
      12             : #define PADDING      0xFD /* The character '=' */
      13             : 
      14             : #define PAD_CHAR     '=' /* The character '=' */
      15             : 
      16             : /* Maximum length of a base64 encoded line */
      17             : #define MAX_BASE64_LINE_LENGTH 76
      18             : 
      19             : /*
      20             :  * base64_result_table
      21             :  *  String table for translating base64 error codes into human
      22             :  *  understanable strings.
      23             :  */
      24             : char *base64_result_table[BASE64_RESULT_MAX] =
      25             : {
      26             :     "Base64 successful",
      27             :     "Base64 Buffer Overrun",
      28             :     "Base64 Bad Data",
      29             :     "Base64 Bad Padding",
      30             :     "Base64 Bad Block Size"
      31             : };
      32             : 
      33             : /*
      34             :  * base64_to_raw_table
      35             :  *  Heart of the Base64 decoding algorithm. Lookup table to convert
      36             :  *  the Base64 characters into their specified representative values.
      37             :  *  Invalid characters are marked with 0xFF, white space characters
      38             :  *  are marked with 0xFE, and the special pading character is marked
      39             :  *  with 0xFD.
      40             :  */
      41             : unsigned char base64_to_raw_table[128] =
      42             : {
      43             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, /* 0-9 */
      44             :     0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 10-19 */
      45             :     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 20-29 */
      46             :     0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 30-39 */
      47             :     0xFF, 0xFF, 0xFF,   62, 0xFF, 0xFF, 0xFF,   63,   52,   53, /* 40-49 */
      48             :       54,   55,   56,   57,   58,   59,   60,   61, 0xFF, 0xFF, /* 50-59 */
      49             :     0xFF, 0xFD, 0xFF, 0xFF, 0xFF,    0,    1,    2,    3,    4, /* 60-69 */
      50             :        5,    6,    7,    8,    9,   10,   11,   12,   13,   14, /* 70-79 */
      51             :       15,   16,   17,   18,   19,   20,   21,   22,   23,   24, /* 80-89 */
      52             :       25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   26,   27,   28, /* 90-99 */
      53             :       29,   30,   31,   32,   33,   34,   35,   36,   37,   38, /* 100-109 */
      54             :       39,   40,   41,   42,   43,   44,   45,   46,   47,   48, /* 110-119 */
      55             :       49,   50,   51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF              /* 120-127 */
      56             : };
      57             : 
      58             : unsigned char raw_to_base64_table[64] =
      59             : {
      60             :     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0-9 */
      61             :     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
      62             :     'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */
      63             :     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */
      64             :     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40-49 */
      65             :     'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50-59 */
      66             :     '8', '9', '+', '/'                                /* 60-63 */
      67             : };
      68             : 
      69             : /*
      70             :  * base64_encode_size_bytes
      71             :  *
      72             :  * DESCRIPTION
      73             :  *  Estimates the size of buffer required for holding the result of
      74             :  *  encoding data of size raw_size_bytes.
      75             :  *
      76             :  * PARAMETERS
      77             :  *  raw_size_bytes = Estimated size of the un-encoded data in bytes.
      78             :  *
      79             :  * RETURN VALUE
      80             :  *  The size of destination buffer to use for encoding in bytes.
      81             :  */
      82           0 : int base64_est_encode_size_bytes (int raw_size_bytes)
      83             : {
      84             :     int length;
      85             : 
      86             :     /*
      87             :      * Find the number of bytes needed to represent the data
      88             :      * using a 4/3 expansion ratio. That result must be
      89             :      * rounded to the next higher multiple of four to account
      90             :      * for padding. Then add in a term to account for any '\n's
      91             :      * added.
      92             :      */
      93           0 :     length = ((((raw_size_bytes * 4 + 2)/ 3) + 3) & ~(0x3)) +
      94           0 :         raw_size_bytes / MAX_BASE64_LINE_LENGTH;
      95             : 
      96           0 :     return length;
      97             : }
      98             : 
      99             : /*
     100             :  * base64_decode_size_bytes
     101             :  *
     102             :  * DESCRIPTION
     103             :  *  Estimates the size of buffer required for holding the result of
     104             :  *  decoding data of size base64_size_bytes.
     105             :  *
     106             :  * PARAMETERS
     107             :  *  base64_size_bytes = Estimated size of the Base64 data in bytes.
     108             :  *
     109             :  * RETURN VALUE
     110             :  *  The size of destination buffer to use for decoding in bytes.
     111             :  */
     112           0 : int base64_est_decode_size_bytes (int base64_size_bytes)
     113             : {
     114             :     int length;
     115             : 
     116           0 :     length = (base64_size_bytes * 3 + 3) / 4;
     117           0 :     return length;
     118             : }
     119             : 
     120             : /*
     121             :  * base64_encode
     122             :  *
     123             :  * DESCRIPTION
     124             :  *  Encode data pointed to by src into the buffer pointer to by dest
     125             :  *  using the Base64 algorithm.
     126             :  *
     127             :  *  NOTE: No trailing '\n' character will be added.
     128             :  *
     129             :  *  NOTE: As per specification, '\n' will be placed every 76 chars.
     130             :  *
     131             :  * PARAMETERS
     132             :  *  src = Pointer to the raw data to base64 encode.
     133             :  *  src_bytes = The number of bytes in the src buffer to encode.
     134             :  *  dest = Pointer to the destination buffer where the converted data
     135             :  *      will reside when complete.
     136             :  *  dest_bytes = Initially holds the size of the destination buffer
     137             :  *      but at completion holds the number of bytes converted.
     138             :  *
     139             :  * RETURN VALUE
     140             :  *  base64_success if the buffer was successfully converted, the
     141             :  *  appropriate error code otherwise.
     142             :  *
     143             :  *  The dest parameter holds the converted data.
     144             :  *
     145             :  *  The dest_bytes parameter holds the actual number of bytes converted.
     146             :  */
     147           0 : base64_result_t base64_encode(unsigned char *src, int src_bytes, unsigned char *dest, int *dest_bytes)
     148             : {
     149           0 :     int i, j=0;
     150           0 :     int line_count = 0;
     151             :     unsigned char index; /* index into base64 lookup table */
     152           0 :     int smax = src_bytes-2; /* only do full multiples of 3 */
     153           0 :     int dmax = *dest_bytes; /* destination maximum */
     154             : 
     155           0 :     *dest_bytes = 0;
     156             : 
     157             :     /* Do full groups. Base64 must be done in blocks of 3 src bytes */
     158           0 :     for (i=0; i<smax; i+=3) {
     159             :         /* Check to see if newline should be injected */
     160           0 :         if (line_count>=MAX_BASE64_LINE_LENGTH) {
     161           0 :             if (j<dmax){
     162           0 :                 dest[j++] = '\n';
     163             :             } else {
     164           0 :                 return BASE64_BUFFER_OVERRUN;
     165             :             }
     166           0 :             line_count = 0;
     167             :         }
     168             : 
     169           0 :         line_count += 4;
     170             : 
     171           0 :         if ((j+3) < dmax) {
     172             : 
     173             :             /* Find mapping of upper 6 bits */
     174           0 :             index = (src[i] >> 2) & 0x3F;
     175           0 :             dest[j++] = raw_to_base64_table[index];
     176             : 
     177             :             /* bottom 2 bits of first word, high 4 bits of second word */
     178           0 :             index = ((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0F);
     179           0 :             dest[j++] = raw_to_base64_table[index];
     180             : 
     181             :             /* bottom 4 bits of second word, high 2 bits of third word */
     182           0 :             index = ((src[i+1] << 2) & 0x3C) | ((src[i+2] >> 6) & 0x03);
     183           0 :             dest[j++] = raw_to_base64_table[index];
     184             : 
     185             :             /* bottom 6 bits of third word */
     186           0 :             index = src[i+2] & 0x3F;
     187           0 :             dest[j++] = raw_to_base64_table[index];
     188             :         } else {
     189           0 :             return BASE64_BUFFER_OVERRUN;
     190             :         }
     191             :     }
     192             : 
     193             :     /* Check to see if any more work must be done */
     194           0 :     if (i<src_bytes) {
     195             : 
     196             :         /* Check to see if a newline should be output */
     197           0 :         if (line_count>=MAX_BASE64_LINE_LENGTH) {
     198           0 :             if (j<dmax){
     199           0 :                 dest[j++] = '\n';
     200             :             } else {
     201           0 :                 return BASE64_BUFFER_OVERRUN;
     202             :             }
     203           0 :             line_count = 0;
     204             :         }
     205             : 
     206           0 :         line_count += 4;
     207             : 
     208             :         /* Must fill another quantum */
     209           0 :         if (j+4>dmax) {
     210             :             /* No room left in output buffer! */
     211           0 :             return BASE64_BUFFER_OVERRUN;
     212             :         }
     213             : 
     214             :         /* Find mapping of upper 6 bits */
     215           0 :         index = (src[i] >> 2) & 0x3F;
     216           0 :         dest[j++] = raw_to_base64_table[index];
     217             : 
     218             :         /* check for another stragler */
     219           0 :         if ((i+1)<src_bytes) {
     220             :             /* bottom 2 bits of first word, high 4 bits of second word */
     221           0 :             index = ((src[i] << 4) & 0x30) | ((src[i+1] >> 4) & 0x0F);
     222           0 :             dest[j++] = raw_to_base64_table[index];
     223             : 
     224             :             /* bottom 4 bits of second word */
     225           0 :             index = (src[i+1] << 2) & 0x3C;
     226           0 :             dest[j++] = raw_to_base64_table[index];
     227           0 :             dest[j++] = PAD_CHAR;
     228             :         } else {
     229             :             /* bottom 2 bits of first word */
     230           0 :             index = (src[i] << 4) & 0x30;
     231           0 :             dest[j++] = raw_to_base64_table[index];
     232           0 :             dest[j++] = PAD_CHAR;
     233           0 :             dest[j++] = PAD_CHAR;
     234             :         }
     235             :     }
     236             : 
     237           0 :     *dest_bytes = j;
     238             : 
     239           0 :     return BASE64_SUCCESS;
     240             : }
     241             : 
     242             : /*
     243             :  * base64_decode
     244             :  *
     245             :  * DESCRIPTION
     246             :  *  Decode data pointed to by src into the buffer pointer to by dest
     247             :  *  using the Base64 algorithm.
     248             :  *
     249             :  * PARAMETERS
     250             :  *  src = Pointer to the Base64 data to decode.
     251             :  *  src_bytes = The number of bytes in the src buffer to decode.
     252             :  *  dest = Pointer to the destination buffer where the converted data
     253             :  *      will reside when complete.
     254             :  *  dest_bytes = Initially holds the size of the destination buffer
     255             :  *      but at completion holds the number of bytes converted.
     256             :  *
     257             :  * RETURN VALUE
     258             :  *  base64_success if the buffer was successfully converted, the
     259             :  *  appropriate error code otherwise.
     260             :  *
     261             :  *  The dest parameter holds the converted data.
     262             :  *
     263             :  *  The dest_bytes parameter holds the actual number of bytes converted.
     264             :  */
     265           0 : base64_result_t base64_decode(unsigned char *src, int src_bytes, unsigned char *dest, int *dest_bytes)
     266             : {
     267           0 :     int i, j = 0;
     268           0 :     int sindex = 0;                     /* Current NON-whitespace source
     269             :                                          * index */
     270           0 :     int pad_count=0;                    /* Number of padding characters
     271             :                                          * encountered */
     272           0 :     int dest_size_bytes = *dest_bytes;  /* Save size of destination buffer */
     273             :     unsigned char cindex;               /* The current Base64 character to
     274             :                                          * process */
     275             :     unsigned char val;                  /* The value of the current Base64
     276             :                                          * character */
     277             : 
     278           0 :     *dest_bytes = 0;
     279             : 
     280           0 :     for (i=0; i<src_bytes; i++) {
     281           0 :         cindex = src[i];
     282             : 
     283           0 :         if ((cindex & 0x80) || /* only have 128 values, MSB must not be set! */
     284           0 :             ((val = base64_to_raw_table[cindex]) == INVALID_CHAR)) {
     285             :             /* Invalid base64 character */
     286           0 :             return BASE64_BAD_DATA;
     287             :         }
     288             : 
     289           0 :         if (val == WHITE_SPACE) {
     290             :             /* Ignore white space */
     291           0 :             continue;
     292             :         }
     293             : 
     294           0 :         if (val == PADDING) {
     295             :             /* we must be at the end-finish up */
     296           0 :             pad_count++;
     297           0 :             if (++i<src_bytes) {
     298             :                 /* can have up to 2 pad chars */
     299           0 :                 if (base64_to_raw_table[src[i]] != PADDING) {
     300           0 :                     return BASE64_BAD_PADDING;
     301             :                 }
     302             : 
     303           0 :                 if (++i<src_bytes) {
     304             :                     /* should not have any more padding! */
     305           0 :                     return BASE64_BAD_PADDING;
     306             :                 }
     307             : 
     308           0 :                 pad_count++;
     309             :             }
     310             : 
     311             :             /* DONE! */
     312           0 :             break;
     313             :         }
     314             : 
     315             :         /* Determine which portion of the 3 bytes this data will fill */
     316           0 :         switch (sindex & 0x3) {
     317             :         case 0:
     318             :             /* Fill upper 6 bits */
     319           0 :             if (j<dest_size_bytes) {
     320           0 :                 dest[j] = val << 2;
     321             :             } else {
     322           0 :                 return BASE64_BUFFER_OVERRUN;
     323             :             }
     324           0 :             break;
     325             :         case 1:
     326             :             /* Fill Bottom 2 bits */
     327           0 :             dest[j++] |= val >> 4;
     328             : 
     329           0 :             if (j<dest_size_bytes) {
     330             :                 /* Fill Top 4 bits */
     331           0 :                 dest[j] = (val << 4) & 0xF0;
     332             :             } else {
     333             :                 /*
     334             :                  * Check to see if there is any more data present.
     335             :                  * Next base64 character MUST be a pad character and
     336             :                  * the rest of this data MUST be zero.
     337             :                  *
     338             :                  * If this is not the end of data then a buffer overrun
     339             :                  * has occurred
     340             :                  */
     341           0 :                 if ((val & 0x0F) ||
     342           0 :                     (i+1>=src_bytes) ||
     343           0 :                     (base64_to_raw_table[src[i+1]] != PADDING)) {
     344           0 :                     return BASE64_BUFFER_OVERRUN;
     345             :                 }
     346             :             }
     347           0 :             break;
     348             :         case 2:
     349             :             /* Fill Bottom 4 bits */
     350           0 :             dest[j++] |= val >> 2;
     351             : 
     352           0 :             if (j<dest_size_bytes) {
     353             :                 /* Fill Top 2 bits */
     354           0 :                 dest[j] = (val << 6) & 0xC0;
     355             :             } else {
     356             :                 /*
     357             :                  * Check to see if there is any more data present.
     358             :                  * Next base64 character MUST be a pad character and
     359             :                  * the rest of this data MUST be zero.
     360             :                  *
     361             :                  * If this is not the end of data then a buffer overrun
     362             :                  * has occurred
     363             :                  */
     364           0 :                 if ((val & 0x03) ||
     365           0 :                     (i+1>=src_bytes) ||
     366           0 :                     (base64_to_raw_table[src[i+1]] != PADDING)) {
     367           0 :                     return BASE64_BUFFER_OVERRUN;
     368             :                 }
     369             :             }
     370           0 :             break;
     371             :         case 3:
     372             :             /*
     373             :              *  No need to check for overrun here since the
     374             :              *  previous case was already checked. If another
     375             :              *  group is present then case 0 will check again.
     376             :              */
     377             : 
     378             :             /* Fill Bottom 6 bits */
     379           0 :             dest[j++] |= val;
     380           0 :             break;
     381             :         }
     382           0 :         sindex++;
     383             :     }
     384             : 
     385             :     /* Check length for multiple of 3 bytes */
     386           0 :     if (((j + pad_count)% 3) != 0) {
     387           0 :         return BASE64_BAD_BLOCK_SIZE;
     388             :     }
     389             : 
     390             :     /* Save off the number of bytes converted */
     391           0 :     *dest_bytes = j;
     392             : 
     393           0 :     return BASE64_SUCCESS;
     394             : }

Generated by: LCOV version 1.13