PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/standard/uuencode.c

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