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: 79 88 89.8 %
Date: 2014-04-10 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         662 : PHPAPI unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length) /* {{{ */
      57             : {
      58         662 :         const unsigned char *current = str;
      59             :         unsigned char *p;
      60             :         unsigned char *result;
      61             : 
      62         662 :         if (length < 0) {
      63           0 :                 if (ret_length != NULL) {
      64           0 :                         *ret_length = 0;
      65             :                 }
      66           0 :                 return NULL;
      67             :         }
      68             : 
      69         662 :         result = (unsigned char *) safe_emalloc((length + 2) / 3, 4 * sizeof(char), 1);
      70         662 :         p = result;
      71             : 
      72        7498 :         while (length > 2) { /* keep going until we have less than 24 bits */
      73        6174 :                 *p++ = base64_table[current[0] >> 2];
      74        6174 :                 *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
      75        6174 :                 *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
      76        6174 :                 *p++ = base64_table[current[2] & 0x3f];
      77             : 
      78        6174 :                 current += 3;
      79        6174 :                 length -= 3; /* we just handle 3 octets of data */
      80             :         }
      81             : 
      82             :         /* now deal with the tail end of things */
      83         662 :         if (length != 0) {
      84         576 :                 *p++ = base64_table[current[0] >> 2];
      85         576 :                 if (length > 1) {
      86         140 :                         *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
      87         140 :                         *p++ = base64_table[(current[1] & 0x0f) << 2];
      88         140 :                         *p++ = base64_pad;
      89             :                 } else {
      90         436 :                         *p++ = base64_table[(current[0] & 0x03) << 4];
      91         436 :                         *p++ = base64_pad;
      92         436 :                         *p++ = base64_pad;
      93             :                 }
      94             :         }
      95         662 :         if (ret_length != NULL) {
      96         662 :                 *ret_length = (int)(p - result);
      97             :         }
      98         662 :         *p = '\0';
      99         662 :         return result;
     100             : }
     101             : /* }}} */
     102             : 
     103             : /* {{{ */
     104             : /* generate reverse table (do not set index 0 to 64)
     105             : static unsigned short base64_reverse_table[256];
     106             : #define rt base64_reverse_table
     107             : void php_base64_init(void)
     108             : {
     109             :         char *s = emalloc(10240), *sp;
     110             :         char *chp;
     111             :         short idx;
     112             : 
     113             :         for(ch = 0; ch < 256; ch++) {
     114             :                 chp = strchr(base64_table, ch);
     115             :                 if(ch && chp) {
     116             :                         idx = chp - base64_table;
     117             :                         if (idx >= 64) idx = -1;
     118             :                         rt[ch] = idx;
     119             :                 } else {
     120             :                         rt[ch] = -1;
     121             :                 }
     122             :         }
     123             :         sp = s;
     124             :         sprintf(sp, "static const short base64_reverse_table[256] = {\n");
     125             :         for(ch =0; ch < 256;) {
     126             :                 sp = s+strlen(s);
     127             :                 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]);
     128             :                 ch += 16;
     129             :         }
     130             :         sprintf(sp, "};");
     131             :         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Reverse_table:\n%s", s);
     132             :         efree(s);
     133             : }
     134             : */
     135             : /* }}} */
     136             : 
     137         128 : PHPAPI unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length) /* {{{ */
     138             : {
     139         128 :         return php_base64_decode_ex(str, length, ret_length, 0);
     140             : }
     141             : /* }}} */
     142             : 
     143         433 : PHPAPI unsigned char *php_base64_decode_ex(const unsigned char *str, int length, int *ret_length, zend_bool strict) /* {{{ */
     144             : {
     145         433 :         const unsigned char *current = str;
     146         433 :         int ch, i = 0, j = 0, k;
     147             :         /* this sucks for threaded environments */
     148             :         unsigned char *result;
     149             : 
     150         433 :         result = (unsigned char *)safe_emalloc(length, 1, 1);
     151             : 
     152             :         /* run through the whole string, converting as we go */
     153       29777 :         while ((ch = *current++) != '\0' && length-- > 0) {
     154       28931 :                 if (ch == base64_pad) {
     155         500 :                         if (*current != '=' && ((i % 4) == 1 || (strict && length > 0))) {
     156           5 :                                 if ((i % 4) != 1) {
     157           8 :                                         while (isspace(*(++current))) {
     158           2 :                                                 continue;
     159             :                                         }
     160           3 :                                         if (*current == '\0') {
     161           2 :                                                 continue;
     162             :                                         }
     163             :                                 }
     164           3 :                                 efree(result);
     165           3 :                                 return NULL;
     166             :                         }
     167         495 :                         continue;
     168             :                 }
     169             : 
     170       28431 :                 ch = base64_reverse_table[ch];
     171       28431 :                 if ((!strict && ch < 0) || ch == -1) { /* a space or some other separator character, we simply skip over */
     172         287 :                         continue;
     173       28144 :                 } else if (ch == -2) {
     174          17 :                         efree(result);
     175          17 :                         return NULL;
     176             :                 }
     177             : 
     178       28127 :                 switch(i % 4) {
     179             :                 case 0:
     180        7159 :                         result[j] = ch << 2;
     181        7159 :                         break;
     182             :                 case 1:
     183        7149 :                         result[j++] |= ch >> 4;
     184        7149 :                         result[j] = (ch & 0x0f) << 4;
     185        7149 :                         break;
     186             :                 case 2:
     187        6963 :                         result[j++] |= ch >>2;
     188        6963 :                         result[j] = (ch & 0x03) << 6;
     189        6963 :                         break;
     190             :                 case 3:
     191        6856 :                         result[j++] |= ch;
     192             :                         break;
     193             :                 }
     194       28127 :                 i++;
     195             :         }
     196             : 
     197         413 :         k = j;
     198             :         /* mop things up if we ended on a boundary */
     199         413 :         if (ch == base64_pad) {
     200           0 :                 switch(i % 4) {
     201             :                 case 1:
     202           0 :                         efree(result);
     203           0 :                         return NULL;
     204             :                 case 2:
     205           0 :                         k++;
     206             :                 case 3:
     207           0 :                         result[k] = 0;
     208             :                 }
     209             :         }
     210         413 :         if(ret_length) {
     211         413 :                 *ret_length = j;
     212             :         }
     213         413 :         result[j] = '\0';
     214         413 :         return result;
     215             : }
     216             : /* }}} */
     217             : 
     218             : /* {{{ proto string base64_encode(string str)
     219             :    Encodes string using MIME base64 algorithm */
     220         494 : PHP_FUNCTION(base64_encode)
     221             : {
     222             :         char *str;
     223             :         unsigned char *result;
     224             :         int str_len, ret_length;
     225             : 
     226         494 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
     227           8 :                 return;
     228             :         }
     229         486 :         result = php_base64_encode((unsigned char*)str, str_len, &ret_length);
     230         486 :         if (result != NULL) {
     231         486 :                 RETVAL_STRINGL((char*)result, ret_length, 0);
     232             :         } else {
     233           0 :                 RETURN_FALSE;
     234             :         }
     235             : }
     236             : /* }}} */
     237             : 
     238             : /* {{{ proto string base64_decode(string str[, bool strict])
     239             :    Decodes string using MIME base64 algorithm */
     240         321 : PHP_FUNCTION(base64_decode)
     241             : {
     242             :         char *str;
     243             :         unsigned char *result;
     244         321 :         zend_bool strict = 0;
     245             :         int str_len, ret_length;
     246             : 
     247         321 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &str, &str_len, &strict) == FAILURE) {
     248          16 :                 return;
     249             :         }
     250         305 :         result = php_base64_decode_ex((unsigned char*)str, str_len, &ret_length, strict);
     251         305 :         if (result != NULL) {
     252         287 :                 RETVAL_STRINGL((char*)result, ret_length, 0);
     253             :         } else {
     254          18 :                 RETURN_FALSE;
     255             :         }
     256             : }
     257             : /* }}} */
     258             : 
     259             : /*
     260             :  * Local variables:
     261             :  * tab-width: 4
     262             :  * c-basic-offset: 4
     263             :  * End:
     264             :  * vim600: sw=4 ts=4 fdm=marker
     265             :  * vim<600: sw=4 ts=4
     266             :  */

Generated by: LCOV version 1.10

Generated at Thu, 10 Apr 2014 08:53:59 +0000 (6 days ago)

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