Return to uuencode.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 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: uuencode.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 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 then 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: *p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4; ! 155: *p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2; ! 156: *p++ = PHP_UU_DEC(*(s + 2)) << 6 | PHP_UU_DEC(*(s + 3)); ! 157: s += 4; ! 158: } ! 159: ! 160: if (len < 45) { ! 161: break; ! 162: } ! 163: ! 164: /* skip \n */ ! 165: s++; ! 166: } ! 167: ! 168: if ((len = total_len > (p - *dest))) { ! 169: *p++ = PHP_UU_DEC(*s) << 2 | PHP_UU_DEC(*(s + 1)) >> 4; ! 170: if (len > 1) { ! 171: *p++ = PHP_UU_DEC(*(s + 1)) << 4 | PHP_UU_DEC(*(s + 2)) >> 2; ! 172: if (len > 2) { ! 173: *p++ = PHP_UU_DEC(*(s + 2)) << 6 | PHP_UU_DEC(*(s + 3)); ! 174: } ! 175: } ! 176: } ! 177: ! 178: *(*dest + total_len) = '\0'; ! 179: ! 180: return total_len; ! 181: ! 182: err: ! 183: efree(*dest); ! 184: return -1; ! 185: } ! 186: /* }}} */ ! 187: ! 188: /* {{{ proto string convert_uuencode(string data) ! 189: uuencode a string */ ! 190: PHP_FUNCTION(convert_uuencode) ! 191: { ! 192: char *src, *dst; ! 193: int src_len, dst_len; ! 194: ! 195: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &src, &src_len) == FAILURE || src_len < 1) { ! 196: RETURN_FALSE; ! 197: } ! 198: ! 199: dst_len = php_uuencode(src, src_len, &dst); ! 200: ! 201: RETURN_STRINGL(dst, dst_len, 0); ! 202: } ! 203: /* }}} */ ! 204: ! 205: /* {{{ proto string convert_uudecode(string data) ! 206: decode a uuencoded string */ ! 207: PHP_FUNCTION(convert_uudecode) ! 208: { ! 209: char *src, *dst; ! 210: int src_len, dst_len; ! 211: ! 212: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &src, &src_len) == FAILURE || src_len < 1) { ! 213: RETURN_FALSE; ! 214: } ! 215: ! 216: dst_len = php_uudecode(src, src_len, &dst); ! 217: if (dst_len < 0) { ! 218: php_error_docref(NULL TSRMLS_CC, E_WARNING, "The given parameter is not a valid uuencoded string"); ! 219: RETURN_FALSE; ! 220: } ! 221: ! 222: RETURN_STRINGL(dst, dst_len, 0); ! 223: } ! 224: /* }}} */ ! 225: ! 226: /* ! 227: * Local variables: ! 228: * tab-width: 4 ! 229: * c-basic-offset: 4 ! 230: * End: ! 231: * vim600: noet sw=4 ts=4 fdm=marker ! 232: * vim<600: noet sw=4 ts=4 ! 233: */