PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/standard - base64.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 75 80 93.8 %
Date: 2014-09-19 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Author: Jim Winstead <jimw@php.net>                                  |
      16             :    +----------------------------------------------------------------------+
      17             :  */
      18             : /* $Id$ */
      19             : 
      20             : #include <string.h>
      21             : 
      22             : #include "php.h"
      23             : #include "base64.h"
      24             : 
      25             : /* {{{ base64 tables */
      26             : static const char base64_table[] = {
      27             :         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
      28             :         'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
      29             :         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
      30             :         'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
      31             :         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
      32             : };
      33             : 
      34             : static const char base64_pad = '=';
      35             : 
      36             : static const short base64_reverse_table[256] = {
      37             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2,
      38             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      39             :         -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
      40             :         52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
      41             :         -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
      42             :         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
      43             :         -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
      44             :         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
      45             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      46             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      47             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      48             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      49             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      50             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      51             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
      52             :         -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
      53             : };
      54             : /* }}} */
      55             : 
      56         664 : PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length) /* {{{ */
      57             : {
      58         664 :         const unsigned char *current = str;
      59             :         unsigned char *p;
      60             :         zend_string *result;
      61             : 
      62         664 :         if (length < 0) {
      63             :                 return NULL;
      64             :         }
      65             : 
      66        1328 :         result = zend_string_alloc(((length + 2) / 3) * 4 * sizeof(char), 0);
      67         664 :         p = (unsigned char *)result->val;
      68             : 
      69        7520 :         while (length > 2) { /* keep going until we have less than 24 bits */
      70        6192 :                 *p++ = base64_table[current[0] >> 2];
      71        6192 :                 *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
      72        6192 :                 *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
      73        6192 :                 *p++ = base64_table[current[2] & 0x3f];
      74             : 
      75        6192 :                 current += 3;
      76        6192 :                 length -= 3; /* we just handle 3 octets of data */
      77             :         }
      78             : 
      79             :         /* now deal with the tail end of things */
      80         664 :         if (length != 0) {
      81         577 :                 *p++ = base64_table[current[0] >> 2];
      82         577 :                 if (length > 1) {
      83         141 :                         *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
      84         141 :                         *p++ = base64_table[(current[1] & 0x0f) << 2];
      85         141 :                         *p++ = base64_pad;
      86             :                 } else {
      87         436 :                         *p++ = base64_table[(current[0] & 0x03) << 4];
      88         436 :                         *p++ = base64_pad;
      89         436 :                         *p++ = base64_pad;
      90             :                 }
      91             :         }
      92         664 :         *p = '\0';
      93             : 
      94         664 :         result->len = (p - (unsigned char *)result->val);
      95             : 
      96         664 :         return result;
      97             : }
      98             : /* }}} */
      99             : 
     100             : /* {{{ */
     101             : /* generate reverse table (do not set index 0 to 64)
     102             : static unsigned short base64_reverse_table[256];
     103             : #define rt base64_reverse_table
     104             : void php_base64_init(void)
     105             : {
     106             :         char *s = emalloc(10240), *sp;
     107             :         char *chp;
     108             :         short idx;
     109             : 
     110             :         for(ch = 0; ch < 256; ch++) {
     111             :                 chp = strchr(base64_table, ch);
     112             :                 if(ch && chp) {
     113             :                         idx = chp - base64_table;
     114             :                         if (idx >= 64) idx = -1;
     115             :                         rt[ch] = idx;
     116             :                 } else {
     117             :                         rt[ch] = -1;
     118             :                 }
     119             :         }
     120             :         sp = s;
     121             :         sprintf(sp, "static const short base64_reverse_table[256] = {\n");
     122             :         for(ch =0; ch < 256;) {
     123             :                 sp = s+strlen(s);
     124             :                 sprintf(sp, "\t% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,% 3d,\n", rt[ch+0], rt[ch+1], rt[ch+2], rt[ch+3], rt[ch+4], rt[ch+5], rt[ch+6], rt[ch+7], rt[ch+8], rt[ch+9], rt[ch+10], rt[ch+11], rt[ch+12], rt[ch+13], rt[ch+14], rt[ch+15]);
     125             :                 ch += 16;
     126             :         }
     127             :         sprintf(sp, "};");
     128             :         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Reverse_table:\n%s", s);
     129             :         efree(s);
     130             : }
     131             : */
     132             : /* }}} */
     133             : 
     134         128 : PHPAPI zend_string *php_base64_decode(const unsigned char *str, size_t length) /* {{{ */
     135             : {
     136         128 :         return php_base64_decode_ex(str, length, 0);
     137             : }
     138             : /* }}} */
     139             : 
     140         434 : PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length, zend_bool strict) /* {{{ */
     141             : {
     142         434 :         const unsigned char *current = str;
     143         434 :         int ch, i = 0, j = 0, k;
     144             :         /* this sucks for threaded environments */
     145             :         zend_string *result;
     146             : 
     147         434 :         result = zend_string_alloc(length, 0);
     148             : 
     149             :         /* run through the whole string, converting as we go */
     150       29799 :         while ((ch = *current++) != '\0' && length-- > 0) {
     151       28951 :                 if (ch == base64_pad) {
     152         501 :                         if (*current != '=' && ((i % 4) == 1 || (strict && length > 0))) {
     153           5 :                                 if ((i % 4) != 1) {
     154           8 :                                         while (isspace(*(++current))) {
     155           2 :                                                 continue;
     156             :                                         }
     157           3 :                                         if (*current == '\0') {
     158           2 :                                                 continue;
     159             :                                         }
     160             :                                 }
     161             :                                 zend_string_free(result);
     162           3 :                                 return NULL;
     163             :                         }
     164         496 :                         continue;
     165             :                 }
     166             : 
     167       28450 :                 ch = base64_reverse_table[ch];
     168       28450 :                 if ((!strict && ch < 0) || ch == -1) { /* a space or some other separator character, we simply skip over */
     169         287 :                         continue;
     170       28163 :                 } else if (ch == -2) {
     171             :                         zend_string_free(result);
     172          17 :                         return NULL;
     173             :                 }
     174             : 
     175       28146 :                 switch(i % 4) {
     176             :                 case 0:
     177        7164 :                         result->val[j] = ch << 2;
     178        7164 :                         break;
     179             :                 case 1:
     180        7154 :                         result->val[j++] |= ch >> 4;
     181        7154 :                         result->val[j] = (ch & 0x0f) << 4;
     182        7154 :                         break;
     183             :                 case 2:
     184        6968 :                         result->val[j++] |= ch >>2;
     185        6968 :                         result->val[j] = (ch & 0x03) << 6;
     186        6968 :                         break;
     187             :                 case 3:
     188        6860 :                         result->val[j++] |= ch;
     189             :                         break;
     190             :                 }
     191       28146 :                 i++;
     192             :         }
     193             : 
     194         414 :         k = j;
     195             :         /* mop things up if we ended on a boundary */
     196         414 :         if (ch == base64_pad) {
     197           0 :                 switch(i % 4) {
     198             :                 case 1:
     199             :                         zend_string_free(result);
     200           0 :                         return NULL;
     201             :                 case 2:
     202           0 :                         k++;
     203             :                 case 3:
     204           0 :                         result->val[k] = 0;
     205             :                 }
     206             :         }
     207         414 :         result->len = j;
     208         414 :         result->val[result->len] = '\0';
     209             : 
     210         414 :         return result;
     211             : }
     212             : /* }}} */
     213             : 
     214             : /* {{{ proto string base64_encode(string str)
     215             :    Encodes string using MIME base64 algorithm */
     216         493 : PHP_FUNCTION(base64_encode)
     217             : {
     218             :         char *str;
     219             :         size_t str_len;
     220             :         zend_string *result;
     221             : 
     222         493 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
     223           8 :                 return;
     224             :         }
     225         485 :         result = php_base64_encode((unsigned char*)str, str_len);
     226         485 :         if (result != NULL) {
     227         485 :                 RETURN_STR(result);
     228             :         } else {
     229           0 :                 RETURN_FALSE;
     230             :         }
     231             : }
     232             : /* }}} */
     233             : 
     234             : /* {{{ proto string base64_decode(string str[, bool strict])
     235             :    Decodes string using MIME base64 algorithm */
     236         322 : PHP_FUNCTION(base64_decode)
     237             : {
     238             :         char *str;
     239         322 :         zend_bool strict = 0;
     240             :         size_t str_len;
     241             :         zend_string *result;
     242             : 
     243         322 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &str, &str_len, &strict) == FAILURE) {
     244          16 :                 return;
     245             :         }
     246         306 :         result = php_base64_decode_ex((unsigned char*)str, str_len, strict);
     247         306 :         if (result != NULL) {
     248         288 :                 RETURN_STR(result);
     249             :         } else {
     250          18 :                 RETURN_FALSE;
     251             :         }
     252             : }
     253             : /* }}} */
     254             : 
     255             : /*
     256             :  * Local variables:
     257             :  * tab-width: 4
     258             :  * c-basic-offset: 4
     259             :  * End:
     260             :  * vim600: sw=4 ts=4 fdm=marker
     261             :  * vim<600: sw=4 ts=4
     262             :  */

Generated by: LCOV version 1.10

Generated at Fri, 19 Sep 2014 17:11:18 +0000 (4 hours ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.