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 5                                                        |
   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 int php_uuencode(char *src, int src_len, char **dest) /* {{{ */
  69 {
  70         int len = 45;
  71         char *p, *s, *e, *ee;
  72 
  73         /* encoded length is ~ 38% greater than the original */
  74         p = *dest = safe_emalloc((size_t) ceil(src_len * 1.38), 1, 46);
  75         s = src;
  76         e = src + src_len;
  77 
  78         while ((s + 3) < e) {
  79                 ee = s + len;
  80                 if (ee > e) {
  81                         ee = e;
  82                         len = ee - s;
  83                         if (len % 3) {
  84                                 ee = s + (int) (floor(len / 3) * 3);
  85                         }
  86                 }
  87                 *p++ = PHP_UU_ENC(len);
  88 
  89                 while (s < ee) {
  90                         *p++ = PHP_UU_ENC(*s >> 2);
  91                         *p++ = PHP_UU_ENC_C2(s);
  92                         *p++ = PHP_UU_ENC_C3(s);
  93                         *p++ = PHP_UU_ENC(*(s + 2) & 077);
  94 
  95                         s += 3;
  96                 }
  97 
  98                 if (len == 45) {
  99                         *p++ = '\n';
 100                 }
 101         }
 102 
 103         if (s < e) {
 104                 if (len == 45) {
 105                         *p++ = PHP_UU_ENC(e - s);
 106                         len = 0;
 107                 }
 108 
 109                 *p++ = PHP_UU_ENC(*s >> 2);
 110                 *p++ = PHP_UU_ENC_C2(s);
 111                 *p++ = ((e - s) > 1) ? PHP_UU_ENC_C3(s) : PHP_UU_ENC('\0');
 112                 *p++ = ((e - s) > 2) ? PHP_UU_ENC(*(s + 2) & 077) : PHP_UU_ENC('\0');
 113         }
 114 
 115         if (len < 45) {
 116                 *p++ = '\n';
 117         }
 118 
 119         *p++ = PHP_UU_ENC('\0');
 120         *p++ = '\n';
 121         *p = '\0';
 122 
 123         return (p - *dest);
 124 }
 125 /* }}} */
 126 
 127 PHPAPI int php_uudecode(char *src, int src_len, char **dest) /* {{{ */
 128 {
 129         int len, total_len=0;
 130         char *s, *e, *p, *ee;
 131 
 132         p = *dest = safe_emalloc((size_t) ceil(src_len * 0.75), 1, 1);
 133         s = src;
 134         e = src + src_len;
 135 
 136         while (s < e) {
 137                 if ((len = PHP_UU_DEC(*s++)) <= 0) {
 138                         break;
 139                 }
 140                 /* sanity check */
 141                 if (len > src_len) {
 142                         goto err;
 143                 }
 144 
 145                 total_len += len;
 146 
 147                 ee = s + (len == 45 ? 60 : (int) floor(len * 1.33));
 148                 /* sanity check */
 149                 if (ee > e) {
 150                         goto err;
 151                 }
 152 
 153                 while (s < ee) {
 154                         if(s+4 > e) {
 155                                 goto err;
 156                         } 
 157                         *p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4;
 158                         *p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2;
 159                         *p++ = PHP_UU_DEC(*(s + 2)) << 6 | PHP_UU_DEC(*(s + 3));
 160                         s += 4;
 161                 }
 162 
 163                 if (len < 45) {
 164                         break;
 165                 }
 166 
 167                 /* skip \n */
 168                 s++;
 169         }
 170 
 171         if ((len = total_len) > (p - *dest)) {
 172                 *p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4;
 173                 if (len > 1) {
 174                         *p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2;
 175                         if (len > 2) {
 176                                 *p++ = PHP_UU_DEC(*(s + 2)) << 6 | PHP_UU_DEC(*(s + 3));
 177                         }
 178                 }
 179         }
 180 
 181         *(*dest + total_len) = '\0';
 182 
 183         return total_len;
 184 
 185 err:
 186         efree(*dest);
 187         return -1;
 188 }
 189 /* }}} */
 190 
 191 /* {{{ proto string convert_uuencode(string data) 
 192    uuencode a string */
 193 PHP_FUNCTION(convert_uuencode)
 194 {
 195         char *src, *dst;
 196         int src_len, dst_len;
 197 
 198         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &src, &src_len) == FAILURE || src_len < 1) {
 199                 RETURN_FALSE;
 200         }
 201 
 202         dst_len = php_uuencode(src, src_len, &dst);
 203 
 204         RETURN_STRINGL(dst, dst_len, 0);
 205 }
 206 /* }}} */
 207 
 208 /* {{{ proto string convert_uudecode(string data)
 209    decode a uuencoded string */
 210 PHP_FUNCTION(convert_uudecode)
 211 {
 212         char *src, *dst;
 213         int src_len, dst_len;
 214 
 215         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &src, &src_len) == FAILURE || src_len < 1) {
 216                 RETURN_FALSE;
 217         }
 218 
 219         dst_len = php_uudecode(src, src_len, &dst);
 220         if (dst_len < 0) {
 221                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The given parameter is not a valid uuencoded string");
 222                 RETURN_FALSE;
 223         }
 224 
 225         RETURN_STRINGL(dst, dst_len, 0);
 226 }
 227 /* }}} */
 228 
 229 /*
 230  * Local variables:
 231  * tab-width: 4
 232  * c-basic-offset: 4
 233  * End:
 234  * vim600: noet sw=4 ts=4 fdm=marker
 235  * vim<600: noet sw=4 ts=4
 236  */

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