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: 73 74 98.6 %
Date: 2016-09-27 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2016 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         705 : PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length) /* {{{ */
      57             : {
      58         705 :         const unsigned char *current = str;
      59             :         unsigned char *p;
      60             :         zend_string *result;
      61             : 
      62        1410 :         result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
      63         705 :         p = (unsigned char *)ZSTR_VAL(result);
      64             : 
      65        5541 :         while (length > 2) { /* keep going until we have less than 24 bits */
      66        4131 :                 *p++ = base64_table[current[0] >> 2];
      67        4131 :                 *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
      68        4131 :                 *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
      69        4131 :                 *p++ = base64_table[current[2] & 0x3f];
      70             : 
      71        4131 :                 current += 3;
      72        4131 :                 length -= 3; /* we just handle 3 octets of data */
      73             :         }
      74             : 
      75             :         /* now deal with the tail end of things */
      76         705 :         if (length != 0) {
      77         626 :                 *p++ = base64_table[current[0] >> 2];
      78         626 :                 if (length > 1) {
      79         145 :                         *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
      80         145 :                         *p++ = base64_table[(current[1] & 0x0f) << 2];
      81         145 :                         *p++ = base64_pad;
      82             :                 } else {
      83         481 :                         *p++ = base64_table[(current[0] & 0x03) << 4];
      84         481 :                         *p++ = base64_pad;
      85         481 :                         *p++ = base64_pad;
      86             :                 }
      87             :         }
      88         705 :         *p = '\0';
      89             : 
      90         705 :         ZSTR_LEN(result) = (p - (unsigned char *)ZSTR_VAL(result));
      91             : 
      92         705 :         return result;
      93             : }
      94             : /* }}} */
      95             : 
      96             : /* {{{ */
      97             : /* generate reverse table (do not set index 0 to 64)
      98             : static unsigned short base64_reverse_table[256];
      99             : #define rt base64_reverse_table
     100             : void php_base64_init(void)
     101             : {
     102             :         char *s = emalloc(10240), *sp;
     103             :         char *chp;
     104             :         short idx;
     105             : 
     106             :         for(ch = 0; ch < 256; ch++) {
     107             :                 chp = strchr(base64_table, ch);
     108             :                 if(ch && chp) {
     109             :                         idx = chp - base64_table;
     110             :                         if (idx >= 64) idx = -1;
     111             :                         rt[ch] = idx;
     112             :                 } else {
     113             :                         rt[ch] = -1;
     114             :                 }
     115             :         }
     116             :         sp = s;
     117             :         sprintf(sp, "static const short base64_reverse_table[256] = {\n");
     118             :         for(ch =0; ch < 256;) {
     119             :                 sp = s+strlen(s);
     120             :                 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]);
     121             :                 ch += 16;
     122             :         }
     123             :         sprintf(sp, "};");
     124             :         php_error_docref(NULL, E_NOTICE, "Reverse_table:\n%s", s);
     125             :         efree(s);
     126             : }
     127             : */
     128             : /* }}} */
     129             : 
     130          64 : PHPAPI zend_string *php_base64_decode(const unsigned char *str, size_t length) /* {{{ */
     131             : {
     132          64 :         return php_base64_decode_ex(str, length, 0);
     133             : }
     134             : /* }}} */
     135             : 
     136         563 : PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length, zend_bool strict) /* {{{ */
     137             : {
     138         563 :         const unsigned char *current = str;
     139         563 :         int ch, i = 0, j = 0, padding = 0;
     140             :         zend_string *result;
     141             : 
     142         563 :         result = zend_string_alloc(length, 0);
     143             : 
     144             :         /* run through the whole string, converting as we go */
     145       31074 :         while (length-- > 0) {
     146       30015 :                 ch = *current++;
     147       30015 :                 if (ch == base64_pad) {
     148         697 :                         padding++;
     149         697 :                         continue;
     150             :                 }
     151             : 
     152       29318 :                 ch = base64_reverse_table[ch];
     153       29318 :                 if (!strict) {
     154             :                         /* skip unknown characters and whitespace */
     155       13800 :                         if (ch < 0) {
     156         292 :                                 continue;
     157             :                         }
     158             :                 } else {
     159             :                         /* skip whitespace */
     160       15518 :                         if (ch == -1) {
     161          34 :                                 continue;
     162             :                         }
     163             :                         /* fail on bad characters or if any data follows padding */
     164       15484 :                         if (ch == -2 || padding) {
     165             :                                 goto fail;
     166             :                         }
     167             :                 }
     168             : 
     169       28925 :                 switch(i % 4) {
     170             :                 case 0:
     171        7396 :                         ZSTR_VAL(result)[j] = ch << 2;
     172        7396 :                         break;
     173             :                 case 1:
     174        7366 :                         ZSTR_VAL(result)[j++] |= ch >> 4;
     175        7366 :                         ZSTR_VAL(result)[j] = (ch & 0x0f) << 4;
     176        7366 :                         break;
     177             :                 case 2:
     178        7150 :                         ZSTR_VAL(result)[j++] |= ch >>2;
     179        7150 :                         ZSTR_VAL(result)[j] = (ch & 0x03) << 6;
     180        7150 :                         break;
     181             :                 case 3:
     182        7013 :                         ZSTR_VAL(result)[j++] |= ch;
     183             :                         break;
     184             :                 }
     185       28925 :                 i++;
     186             :         }
     187             :         /* fail if the input is truncated (only one char in last group) */
     188         496 :         if (strict && i % 4 == 1) {
     189          11 :                 goto fail;
     190             :         }
     191             :         /* fail if the padding length is wrong (not VV==, VVV=), but accept zero padding
     192             :          * RFC 4648: "In some circumstances, the use of padding [--] is not required" */
     193         485 :         if (strict && padding && (padding > 2 || (i + padding) % 4 != 0)) {
     194             :                 goto fail;
     195             :         }
     196             : 
     197         469 :         ZSTR_LEN(result) = j;
     198         469 :         ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';
     199             : 
     200         469 :         return result;
     201             : 
     202             : fail:
     203             :         zend_string_free(result);
     204          94 :         return NULL;
     205             : }
     206             : /* }}} */
     207             : 
     208             : /* {{{ proto string base64_encode(string str)
     209             :    Encodes string using MIME base64 algorithm */
     210         508 : PHP_FUNCTION(base64_encode)
     211             : {
     212             :         char *str;
     213             :         size_t str_len;
     214             :         zend_string *result;
     215             : 
     216         508 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &str_len) == FAILURE) {
     217           8 :                 return;
     218             :         }
     219         500 :         result = php_base64_encode((unsigned char*)str, str_len);
     220         500 :         if (result != NULL) {
     221         500 :                 RETURN_STR(result);
     222             :         } else {
     223           0 :                 RETURN_FALSE;
     224             :         }
     225             : }
     226             : /* }}} */
     227             : 
     228             : /* {{{ proto string base64_decode(string str[, bool strict])
     229             :    Decodes string using MIME base64 algorithm */
     230         495 : PHP_FUNCTION(base64_decode)
     231             : {
     232             :         char *str;
     233         495 :         zend_bool strict = 0;
     234             :         size_t str_len;
     235             :         zend_string *result;
     236             : 
     237         495 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &str, &str_len, &strict) == FAILURE) {
     238          16 :                 return;
     239             :         }
     240         479 :         result = php_base64_decode_ex((unsigned char*)str, str_len, strict);
     241         479 :         if (result != NULL) {
     242         388 :                 RETURN_STR(result);
     243             :         } else {
     244          91 :                 RETURN_FALSE;
     245             :         }
     246             : }
     247             : /* }}} */
     248             : 
     249             : /*
     250             :  * Local variables:
     251             :  * tab-width: 4
     252             :  * c-basic-offset: 4
     253             :  * End:
     254             :  * vim600: sw=4 ts=4 fdm=marker
     255             :  * vim<600: sw=4 ts=4
     256             :  */

Generated by: LCOV version 1.10

Generated at Tue, 27 Sep 2016 10:26:09 +0000 (4 days ago)

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