Annotation of embedaddon/php/ext/standard/quot_print.c, revision 1.1
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: Kirill Maximov <kir@actimind.com> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: quot_print.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #include <stdlib.h>
! 22:
! 23: #ifdef HAVE_UNISTD_H
! 24: #include <unistd.h>
! 25: #endif
! 26: #include <string.h>
! 27: #include <errno.h>
! 28:
! 29: #include "php.h"
! 30: #include "quot_print.h"
! 31:
! 32: #include <stdio.h>
! 33:
! 34: /*
! 35: * Converting HEX char to INT value
! 36: */
! 37: static char php_hex2int(int c) /* {{{ */
! 38: {
! 39: if (isdigit(c)) {
! 40: return c - '0';
! 41: }
! 42: else if (c >= 'A' && c <= 'F') {
! 43: return c - 'A' + 10;
! 44: }
! 45: else if (c >= 'a' && c <= 'f') {
! 46: return c - 'a' + 10;
! 47: }
! 48: else {
! 49: return -1;
! 50: }
! 51: }
! 52: /* }}} */
! 53:
! 54: PHPAPI unsigned char *php_quot_print_decode(const unsigned char *str, size_t length, size_t *ret_length, int replace_us_by_ws) /* {{{ */
! 55: {
! 56: register unsigned int i;
! 57: register unsigned const char *p1;
! 58: register unsigned char *p2;
! 59: register unsigned int h_nbl, l_nbl;
! 60:
! 61: size_t decoded_len, buf_size;
! 62: unsigned char *retval;
! 63:
! 64: static unsigned int hexval_tbl[256] = {
! 65: 64, 64, 64, 64, 64, 64, 64, 64, 64, 32, 16, 64, 64, 16, 64, 64,
! 66: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 67: 32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 68: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 64, 64, 64, 64, 64,
! 69: 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 70: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 71: 64, 10, 11, 12, 13, 14, 15, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 72: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 73: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 74: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 75: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 76: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 77: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 78: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 79: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
! 80: 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
! 81: };
! 82:
! 83: if (replace_us_by_ws) {
! 84: replace_us_by_ws = '_';
! 85: }
! 86:
! 87: i = length, p1 = str; buf_size = length;
! 88:
! 89: while (i > 1 && *p1 != '\0') {
! 90: if (*p1 == '=') {
! 91: buf_size -= 2;
! 92: p1++;
! 93: i--;
! 94: }
! 95: p1++;
! 96: i--;
! 97: }
! 98:
! 99: retval = emalloc(buf_size + 1);
! 100: i = length; p1 = str; p2 = retval;
! 101: decoded_len = 0;
! 102:
! 103: while (i > 0 && *p1 != '\0') {
! 104: if (*p1 == '=') {
! 105: i--, p1++;
! 106: if (i == 0 || *p1 == '\0') {
! 107: break;
! 108: }
! 109: h_nbl = hexval_tbl[*p1];
! 110: if (h_nbl < 16) {
! 111: /* next char should be a hexadecimal digit */
! 112: if ((--i) == 0 || (l_nbl = hexval_tbl[*(++p1)]) >= 16) {
! 113: efree(retval);
! 114: return NULL;
! 115: }
! 116: *(p2++) = (h_nbl << 4) | l_nbl, decoded_len++;
! 117: i--, p1++;
! 118: } else if (h_nbl < 64) {
! 119: /* soft line break */
! 120: while (h_nbl == 32) {
! 121: if (--i == 0 || (h_nbl = hexval_tbl[*(++p1)]) == 64) {
! 122: efree(retval);
! 123: return NULL;
! 124: }
! 125: }
! 126: if (p1[0] == '\r' && i >= 2 && p1[1] == '\n') {
! 127: i--, p1++;
! 128: }
! 129: i--, p1++;
! 130: } else {
! 131: efree(retval);
! 132: return NULL;
! 133: }
! 134: } else {
! 135: *(p2++) = (replace_us_by_ws == *p1 ? '\x20': *p1);
! 136: i--, p1++, decoded_len++;
! 137: }
! 138: }
! 139:
! 140: *p2 = '\0';
! 141: *ret_length = decoded_len;
! 142: return retval;
! 143: }
! 144: /* }}} */
! 145:
! 146: #define PHP_QPRINT_MAXL 75
! 147:
! 148: PHPAPI unsigned char *php_quot_print_encode(const unsigned char *str, size_t length, size_t *ret_length) /* {{{ */
! 149: {
! 150: unsigned long lp = 0;
! 151: unsigned char c, *ret, *d;
! 152: char *hex = "0123456789ABCDEF";
! 153:
! 154: ret = safe_emalloc(1, 3 * length + 3 * (((3 * length)/PHP_QPRINT_MAXL) + 1), 0);
! 155: d = ret;
! 156:
! 157: while (length--) {
! 158: if (((c = *str++) == '\015') && (*str == '\012') && length > 0) {
! 159: *d++ = '\015';
! 160: *d++ = *str++;
! 161: length--;
! 162: lp = 0;
! 163: } else {
! 164: if (iscntrl (c) || (c == 0x7f) || (c & 0x80) || (c == '=') || ((c == ' ') && (*str == '\015'))) {
! 165: if ((lp += 3) > PHP_QPRINT_MAXL) {
! 166: *d++ = '=';
! 167: *d++ = '\015';
! 168: *d++ = '\012';
! 169: lp = 3;
! 170: }
! 171: *d++ = '=';
! 172: *d++ = hex[c >> 4];
! 173: *d++ = hex[c & 0xf];
! 174: } else {
! 175: if ((++lp) > PHP_QPRINT_MAXL) {
! 176: *d++ = '=';
! 177: *d++ = '\015';
! 178: *d++ = '\012';
! 179: lp = 1;
! 180: }
! 181: *d++ = c;
! 182: }
! 183: }
! 184: }
! 185: *d = '\0';
! 186: *ret_length = d - ret;
! 187:
! 188: ret = erealloc(ret, *ret_length + 1);
! 189: return ret;
! 190: }
! 191: /* }}} */
! 192:
! 193: /*
! 194: *
! 195: * Decoding Quoted-printable string.
! 196: *
! 197: */
! 198: /* {{{ proto string quoted_printable_decode(string str)
! 199: Convert a quoted-printable string to an 8 bit string */
! 200: PHP_FUNCTION(quoted_printable_decode)
! 201: {
! 202: char *arg1, *str_in, *str_out;
! 203: int arg1_len, i = 0, j = 0, k;
! 204:
! 205: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg1, &arg1_len) == FAILURE) {
! 206: return;
! 207: }
! 208:
! 209: if (arg1_len == 0) {
! 210: /* shortcut */
! 211: RETURN_EMPTY_STRING();
! 212: }
! 213:
! 214: str_in = arg1;
! 215: str_out = emalloc(arg1_len + 1);
! 216: while (str_in[i]) {
! 217: switch (str_in[i]) {
! 218: case '=':
! 219: if (str_in[i + 1] && str_in[i + 2] &&
! 220: isxdigit((int) str_in[i + 1]) &&
! 221: isxdigit((int) str_in[i + 2]))
! 222: {
! 223: str_out[j++] = (php_hex2int((int) str_in[i + 1]) << 4)
! 224: + php_hex2int((int) str_in[i + 2]);
! 225: i += 3;
! 226: } else /* check for soft line break according to RFC 2045*/ {
! 227: k = 1;
! 228: while (str_in[i + k] && ((str_in[i + k] == 32) || (str_in[i + k] == 9))) {
! 229: /* Possibly, skip spaces/tabs at the end of line */
! 230: k++;
! 231: }
! 232: if (!str_in[i + k]) {
! 233: /* End of line reached */
! 234: i += k;
! 235: }
! 236: else if ((str_in[i + k] == 13) && (str_in[i + k + 1] == 10)) {
! 237: /* CRLF */
! 238: i += k + 2;
! 239: }
! 240: else if ((str_in[i + k] == 13) || (str_in[i + k] == 10)) {
! 241: /* CR or LF */
! 242: i += k + 1;
! 243: }
! 244: else {
! 245: str_out[j++] = str_in[i++];
! 246: }
! 247: }
! 248: break;
! 249: default:
! 250: str_out[j++] = str_in[i++];
! 251: }
! 252: }
! 253: str_out[j] = '\0';
! 254:
! 255: RETVAL_STRINGL(str_out, j, 0);
! 256: }
! 257: /* }}} */
! 258:
! 259: /* {{{ proto string quoted_printable_encode(string str) */
! 260: PHP_FUNCTION(quoted_printable_encode)
! 261: {
! 262: char *str, *new_str;
! 263: int str_len;
! 264: size_t new_str_len;
! 265:
! 266: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) != SUCCESS) {
! 267: return;
! 268: }
! 269:
! 270: if (!str_len) {
! 271: RETURN_EMPTY_STRING();
! 272: }
! 273:
! 274: new_str = (char *)php_quot_print_encode((unsigned char *)str, (size_t)str_len, &new_str_len);
! 275: RETURN_STRINGL(new_str, new_str_len, 0);
! 276: }
! 277: /* }}} */
! 278:
! 279: /*
! 280: * Local variables:
! 281: * tab-width: 4
! 282: * c-basic-offset: 4
! 283: * End:
! 284: * vim600: sw=4 ts=4 fdm=marker
! 285: * vim<600: sw=4 ts=4
! 286: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>