root/ext/standard/uuencode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_uuencode
  2. php_uudecode
  3. PHP_FUNCTION
  4. PHP_FUNCTION

   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: Ilia Alshanetsky <ilia@php.net>                              |
  16    +----------------------------------------------------------------------+
  17  */
  18 
  19 /* $Id$ */
  20 
  21 /*
  22  * Portions of this code are based on Berkeley's uuencode/uudecode
  23  * implementation.
  24  *
  25  * Copyright (c) 1983, 1993
  26  *  The Regents of the University of California.  All rights reserved.
  27  *
  28  * Redistribution and use in source and binary forms, with or without
  29  * modification, are permitted provided that the following conditions
  30  * are met:
  31  * 1. Redistributions of source code must retain the above copyright
  32  *    notice, this list of conditions and the following disclaimer.
  33  * 2. Redistributions in binary form must reproduce the above copyright
  34  *    notice, this list of conditions and the following disclaimer in the
  35  *    documentation and/or other materials provided with the distribution.
  36  * 3. All advertising materials mentioning features or use of this software
  37  *    must display the following acknowledgement:
  38  *  This product includes software developed by the University of
  39  *  California, Berkeley and its contributors.
  40  * 4. Neither the name of the University nor the names of its contributors
  41  *    may be used to endorse or promote products derived from this software
  42  *    without specific prior written permission.
  43  *
  44  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  45  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  46  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  47  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  48  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  49  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  50  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  52  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  53  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  54  * SUCH DAMAGE.
  55  */
  56 
  57 #include <math.h>
  58 
  59 #include "php.h"
  60 #include "php_uuencode.h"
  61 
  62 #define PHP_UU_ENC(c) ((c) ? ((c) & 077) + ' ' : '`')
  63 #define PHP_UU_ENC_C2(c) PHP_UU_ENC(((*(c) << 4) & 060) | ((*((c) + 1) >> 4) & 017))
  64 #define PHP_UU_ENC_C3(c) PHP_UU_ENC(((*(c + 1) << 2) & 074) | ((*((c) + 2) >> 6) & 03))
  65 
  66 #define PHP_UU_DEC(c) (((c) - ' ') & 077)
  67 
  68 PHPAPI zend_string *php_uuencode(char *src, size_t src_len) /* {{{ */
  69 {
  70         size_t len = 45;
  71         char *p, *s, *e, *ee;
  72         zend_string *dest;
  73 
  74         /* encoded length is ~ 38% greater than the original */
  75         dest = zend_string_alloc((size_t)ceil(src_len * 1.38) + 46, 0);
  76         p = ZSTR_VAL(dest);
  77         s = src;
  78         e = src + src_len;
  79 
  80         while ((s + 3) < e) {
  81                 ee = s + len;
  82                 if (ee > e) {
  83                         ee = e;
  84                         len = ee - s;
  85                         if (len % 3) {
  86                                 ee = s + (int) (floor((double)len / 3) * 3);
  87                         }
  88                 }
  89                 *p++ = PHP_UU_ENC(len);
  90 
  91                 while (s < ee) {
  92                         *p++ = PHP_UU_ENC(*s >> 2);
  93                         *p++ = PHP_UU_ENC_C2(s);
  94                         *p++ = PHP_UU_ENC_C3(s);
  95                         *p++ = PHP_UU_ENC(*(s + 2) & 077);
  96 
  97                         s += 3;
  98                 }
  99 
 100                 if (len == 45) {
 101                         *p++ = '\n';
 102                 }
 103         }
 104 
 105         if (s < e) {
 106                 if (len == 45) {
 107                         *p++ = PHP_UU_ENC(e - s);
 108                         len = 0;
 109                 }
 110 
 111                 *p++ = PHP_UU_ENC(*s >> 2);
 112                 *p++ = PHP_UU_ENC_C2(s);
 113                 *p++ = ((e - s) > 1) ? PHP_UU_ENC_C3(s) : PHP_UU_ENC('\0');
 114                 *p++ = ((e - s) > 2) ? PHP_UU_ENC(*(s + 2) & 077) : PHP_UU_ENC('\0');
 115         }
 116 
 117         if (len < 45) {
 118                 *p++ = '\n';
 119         }
 120 
 121         *p++ = PHP_UU_ENC('\0');
 122         *p++ = '\n';
 123         *p = '\0';
 124 
 125         dest = zend_string_truncate(dest, p - ZSTR_VAL(dest), 0);
 126         return dest;
 127 }
 128 /* }}} */
 129 
 130 PHPAPI zend_string *php_uudecode(char *src, size_t src_len) /* {{{ */
 131 {
 132         size_t len, total_len=0;
 133         char *s, *e, *p, *ee;
 134         zend_string *dest;
 135 
 136         dest = zend_string_alloc((size_t) ceil(src_len * 0.75), 0);
 137         p = ZSTR_VAL(dest);
 138         s = src;
 139         e = src + src_len;
 140 
 141         while (s < e) {
 142                 if ((len = PHP_UU_DEC(*s++)) <= 0) {
 143                         break;
 144                 }
 145                 /* sanity check */
 146                 if (len > src_len) {
 147                         goto err;
 148                 }
 149 
 150                 total_len += len;
 151 
 152                 ee = s + (len == 45 ? 60 : (int) floor(len * 1.33));
 153                 /* sanity check */
 154                 if (ee > e) {
 155                         goto err;
 156                 }
 157 
 158                 while (s < ee) {
 159                         if(s+4 > e) {
 160                                 goto err;
 161                         }
 162                         *p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4;
 163                         *p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2;
 164                         *p++ = PHP_UU_DEC(*(s + 2)) << 6 | PHP_UU_DEC(*(s + 3));
 165                         s += 4;
 166                 }
 167 
 168                 if (len < 45) {
 169                         break;
 170                 }
 171 
 172                 /* skip \n */
 173                 s++;
 174         }
 175 
 176         assert(p >= ZSTR_VAL(dest));
 177         if ((len = total_len) > (size_t)(p - ZSTR_VAL(dest))) {
 178                 *p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4;
 179                 if (len > 1) {
 180                         *p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2;
 181                         if (len > 2) {
 182                                 *p++ = PHP_UU_DEC(*(s + 2)) << 6 | PHP_UU_DEC(*(s + 3));
 183                         }
 184                 }
 185         }
 186 
 187         ZSTR_LEN(dest) = total_len;
 188         ZSTR_VAL(dest)[ZSTR_LEN(dest)] = '\0';
 189 
 190         return dest;
 191 
 192 err:
 193         zend_string_free(dest);
 194 
 195         return NULL;
 196 }
 197 /* }}} */
 198 
 199 /* {{{ proto string convert_uuencode(string data)
 200    uuencode a string */
 201 PHP_FUNCTION(convert_uuencode)
 202 {
 203         zend_string *src;
 204 
 205         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &src) == FAILURE || ZSTR_LEN(src) < 1) {
 206                 RETURN_FALSE;
 207         }
 208 
 209         RETURN_STR(php_uuencode(ZSTR_VAL(src), ZSTR_LEN(src)));
 210 }
 211 /* }}} */
 212 
 213 /* {{{ proto string convert_uudecode(string data)
 214    decode a uuencoded string */
 215 PHP_FUNCTION(convert_uudecode)
 216 {
 217         zend_string *src;
 218         zend_string *dest;
 219 
 220         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &src) == FAILURE || ZSTR_LEN(src) < 1) {
 221                 RETURN_FALSE;
 222         }
 223 
 224         if ((dest = php_uudecode(ZSTR_VAL(src), ZSTR_LEN(src))) == NULL) {
 225                 php_error_docref(NULL, E_WARNING, "The given parameter is not a valid uuencoded string");
 226                 RETURN_FALSE;
 227         }
 228 
 229         RETURN_STR(dest);
 230 }
 231 /* }}} */
 232 
 233 /*
 234  * Local variables:
 235  * tab-width: 4
 236  * c-basic-offset: 4
 237  * End:
 238  * vim600: noet sw=4 ts=4 fdm=marker
 239  * vim<600: noet sw=4 ts=4
 240  */

/* [<][>][^][v][top][bottom][index][help] */