summaryrefslogtreecommitdiff
path: root/ext/standard/filters.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/filters.c')
-rw-r--r--ext/standard/filters.c1907
1 files changed, 0 insertions, 1907 deletions
diff --git a/ext/standard/filters.c b/ext/standard/filters.c
deleted file mode 100644
index 918377a5e7..0000000000
--- a/ext/standard/filters.c
+++ /dev/null
@@ -1,1907 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 4 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2003 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 2.02 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available at through the world-wide-web at |
- | http://www.php.net/license/2_02.txt. |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: |
- | Wez Furlong (wez@thebrainroom.com) |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id$ */
-
-#include "php.h"
-#include "php_globals.h"
-#include "ext/standard/basic_functions.h"
-#include "ext/standard/file.h"
-#include "ext/standard/php_string.h"
-
-/* {{{ rot13 stream filter implementation */
-static char rot13_from[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-static char rot13_to[] = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
-
-static php_stream_filter_status_t strfilter_rot13_filter(
- php_stream *stream,
- php_stream_filter *thisfilter,
- php_stream_bucket_brigade *buckets_in,
- php_stream_bucket_brigade *buckets_out,
- size_t *bytes_consumed,
- int flags
- TSRMLS_DC)
-{
- php_stream_bucket *bucket;
- size_t consumed = 0;
-
- while (buckets_in->head) {
- bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC);
-
- php_strtr(bucket->buf, bucket->buflen, rot13_from, rot13_to, 52);
- consumed += bucket->buflen;
-
- php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);
- }
-
- if (bytes_consumed) {
- *bytes_consumed = consumed;
- }
-
- return PSFS_PASS_ON;
-}
-
-static php_stream_filter_ops strfilter_rot13_ops = {
- strfilter_rot13_filter,
- NULL,
- "string.rot13"
-};
-
-static php_stream_filter *strfilter_rot13_create(const char *filtername, const char *filterparams,
- int filterparamslen, int persistent TSRMLS_DC)
-{
- return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent);
-}
-
-static php_stream_filter_factory strfilter_rot13_factory = {
- strfilter_rot13_create
-};
-/* }}} */
-
-/* {{{ string.toupper / string.tolower stream filter implementation */
-static char lowercase[] = "abcdefghijklmnopqrstuvwxyz";
-static char uppercase[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-static php_stream_filter_status_t strfilter_toupper_filter(
- php_stream *stream,
- php_stream_filter *thisfilter,
- php_stream_bucket_brigade *buckets_in,
- php_stream_bucket_brigade *buckets_out,
- size_t *bytes_consumed,
- int flags
- TSRMLS_DC)
-{
- php_stream_bucket *bucket;
- size_t consumed = 0;
-
- while (buckets_in->head) {
- bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC);
-
- php_strtr(bucket->buf, bucket->buflen, lowercase, uppercase, 26);
- consumed += bucket->buflen;
-
- php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);
- }
-
- if (bytes_consumed) {
- *bytes_consumed = consumed;
- }
-
- return PSFS_PASS_ON;
-}
-
-static php_stream_filter_status_t strfilter_tolower_filter(
- php_stream *stream,
- php_stream_filter *thisfilter,
- php_stream_bucket_brigade *buckets_in,
- php_stream_bucket_brigade *buckets_out,
- size_t *bytes_consumed,
- int flags
- TSRMLS_DC)
-{
- php_stream_bucket *bucket;
- size_t consumed = 0;
-
- while (buckets_in->head) {
- bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC);
-
- php_strtr(bucket->buf, bucket->buflen, uppercase, lowercase, 26);
- consumed += bucket->buflen;
-
- php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);
- }
-
- if (bytes_consumed) {
- *bytes_consumed = consumed;
- }
-
- return PSFS_PASS_ON;
-}
-
-static php_stream_filter_ops strfilter_toupper_ops = {
- strfilter_toupper_filter,
- NULL,
- "string.toupper"
-};
-
-static php_stream_filter_ops strfilter_tolower_ops = {
- strfilter_tolower_filter,
- NULL,
- "string.tolower"
-};
-
-static php_stream_filter *strfilter_toupper_create(const char *filtername, const char *filterparams,
- int filterparamslen, int persistent TSRMLS_DC)
-{
- return php_stream_filter_alloc(&strfilter_toupper_ops, NULL, persistent);
-}
-
-static php_stream_filter *strfilter_tolower_create(const char *filtername, const char *filterparams,
- int filterparamslen, int persistent TSRMLS_DC)
-{
- return php_stream_filter_alloc(&strfilter_tolower_ops, NULL, persistent);
-}
-
-static php_stream_filter_factory strfilter_toupper_factory = {
- strfilter_toupper_create
-};
-
-static php_stream_filter_factory strfilter_tolower_factory = {
- strfilter_tolower_create
-};
-/* }}} */
-
-/* {{{ strip_tags filter implementation */
-typedef struct _php_strip_tags_filter {
- const char *allowed_tags;
- int allowed_tags_len;
- int state;
- int persistent;
-} php_strip_tags_filter;
-
-static int php_strip_tags_filter_ctor(php_strip_tags_filter *inst, const char *allowed_tags, int allowed_tags_len, int persistent)
-{
- if (allowed_tags != NULL) {
- inst->allowed_tags = pemalloc(allowed_tags_len, persistent);
- memcpy((char *)inst->allowed_tags, allowed_tags, allowed_tags_len);
- inst->allowed_tags_len = allowed_tags_len;
- } else {
- inst->allowed_tags = NULL;
- }
- inst->state = 0;
- inst->persistent = persistent;
-
- return SUCCESS;
-}
-
-static void php_strip_tags_filter_dtor(php_strip_tags_filter *inst)
-{
- if (inst->allowed_tags != NULL) {
- pefree((void *)inst->allowed_tags, inst->persistent);
- }
-}
-
-static php_stream_filter_status_t strfilter_strip_tags_filter(
- php_stream *stream,
- php_stream_filter *thisfilter,
- php_stream_bucket_brigade *buckets_in,
- php_stream_bucket_brigade *buckets_out,
- size_t *bytes_consumed,
- int flags
- TSRMLS_DC)
-{
- php_stream_bucket *bucket;
- size_t consumed = 0;
- php_strip_tags_filter *inst = (php_strip_tags_filter *) thisfilter->abstract;
-
- while (buckets_in->head) {
- bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC);
- consumed = bucket->buflen;
-
- bucket->buflen = php_strip_tags(bucket->buf, bucket->buflen, &(inst->state), (char *)inst->allowed_tags, inst->allowed_tags_len);
-
- php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);
- }
-
- if (bytes_consumed) {
- *bytes_consumed = consumed;
- }
-
- return PSFS_PASS_ON;
-}
-
-static void strfilter_strip_tags_dtor(php_stream_filter *thisfilter TSRMLS_DC)
-{
- assert(thisfilter->abstract != NULL);
-
- php_strip_tags_filter_dtor((php_strip_tags_filter *)thisfilter->abstract);
-
- pefree(thisfilter->abstract, ((php_strip_tags_filter *)thisfilter->abstract)->persistent);
-}
-
-static php_stream_filter_ops strfilter_strip_tags_ops = {
- strfilter_strip_tags_filter,
- strfilter_strip_tags_dtor,
- "string.strip_tags"
-};
-
-static php_stream_filter *strfilter_strip_tags_create(const char *filtername, const char *filterparams,
- int filterparamslen, int persistent TSRMLS_DC)
-{
- php_strip_tags_filter *inst;
- inst = pemalloc(sizeof(php_strip_tags_filter), persistent);
-
- if (php_strip_tags_filter_ctor(inst, filterparams, filterparamslen, persistent) != SUCCESS) {
- pefree(inst, persistent);
- return NULL;
- }
-
- return php_stream_filter_alloc(&strfilter_strip_tags_ops, inst, persistent);
-}
-
-static php_stream_filter_factory strfilter_strip_tags_factory = {
- strfilter_strip_tags_create
-};
-
-/* }}} */
-
-/* {{{ base64 / quoted_printable stream filter implementation */
-
-typedef enum _php_conv_err_t {
- PHP_CONV_ERR_SUCCESS = SUCCESS,
- PHP_CONV_ERR_UNKNOWN,
- PHP_CONV_ERR_TOO_BIG,
- PHP_CONV_ERR_INVALID_SEQ,
- PHP_CONV_ERR_UNEXPECTED_EOS,
- PHP_CONV_ERR_EXISTS,
- PHP_CONV_ERR_NOT_FOUND
-} php_conv_err_t;
-
-typedef struct _php_conv php_conv;
-
-typedef php_conv_err_t (*php_conv_convert_func)(php_conv *, const char **, size_t *, char **, size_t *);
-typedef void (*php_conv_dtor_func)(php_conv *);
-
-struct _php_conv {
- php_conv_convert_func convert_op;
- php_conv_dtor_func dtor;
-};
-
-#define php_conv_convert(a, b, c, d, e) ((php_conv *)(a))->convert_op((php_conv *)(a), (b), (c), (d), (e))
-#define php_conv_dtor(a) ((php_conv *)a)->dtor((a))
-
-/* {{{ php_conv_base64_encode */
-typedef struct _php_conv_base64_encode {
- php_conv _super;
-
- unsigned char erem[3];
- size_t erem_len;
- unsigned int line_ccnt;
- unsigned int line_len;
- const char *lbchars;
- int lbchars_dup;
- size_t lbchars_len;
- int persistent;
-} php_conv_base64_encode;
-
-static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *inst, const char **in_p, size_t *in_left, char **out_p, size_t *out_left);
-static void php_conv_base64_encode_dtor(php_conv_base64_encode *inst);
-
-static unsigned char b64_tbl_enc[256] = {
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
- 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
- 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
- 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
- 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
- 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
- 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
- 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
- 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
- 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/',
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
- 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
- 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
- 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
-};
-
-static php_conv_err_t php_conv_base64_encode_ctor(php_conv_base64_encode *inst, unsigned int line_len, const char *lbchars, size_t lbchars_len, int lbchars_dup, int persistent)
-{
- inst->_super.convert_op = (php_conv_convert_func) php_conv_base64_encode_convert;
- inst->_super.dtor = (php_conv_dtor_func) php_conv_base64_encode_dtor;
- inst->erem_len = 0;
- inst->line_ccnt = line_len;
- inst->line_len = line_len;
- if (lbchars != NULL) {
- inst->lbchars = (lbchars_dup ? pestrdup(lbchars, persistent) : lbchars);
- inst->lbchars_len = lbchars_len;
- } else {
- inst->lbchars = NULL;
- }
- inst->lbchars_dup = lbchars_dup;
- inst->persistent = persistent;
- return SUCCESS;
-}
-
-static void php_conv_base64_encode_dtor(php_conv_base64_encode *inst)
-{
- assert(inst != NULL);
- if (inst->lbchars_dup && inst->lbchars != NULL) {
- pefree((void *)inst->lbchars, inst->persistent);
- }
-}
-
-static php_conv_err_t php_conv_base64_encode_flush(php_conv_base64_encode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p)
-{
- volatile php_conv_err_t err = PHP_CONV_ERR_SUCCESS;
- register unsigned char *pd;
- register size_t ocnt;
- unsigned int line_ccnt;
-
- pd = (unsigned char *)(*out_pp);
- ocnt = *out_left_p;
- line_ccnt = inst->line_ccnt;
-
- switch (inst->erem_len) {
- case 0:
- /* do nothing */
- break;
-
- case 1:
- if (line_ccnt < 4 && inst->lbchars != NULL) {
- if (ocnt < inst->lbchars_len) {
- return PHP_CONV_ERR_TOO_BIG;
- }
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- }
- if (ocnt < 4) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = b64_tbl_enc[(inst->erem[0] >> 2)];
- *(pd++) = b64_tbl_enc[(unsigned char)(inst->erem[0] << 4)];
- *(pd++) = '=';
- *(pd++) = '=';
- inst->erem_len = 0;
- ocnt -= 4;
- line_ccnt -= 4;
- break;
-
- case 2:
- if (line_ccnt < 4 && inst->lbchars != NULL) {
- if (ocnt < inst->lbchars_len) {
- return PHP_CONV_ERR_TOO_BIG;
- }
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- }
- if (ocnt < 4) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = b64_tbl_enc[(inst->erem[0] >> 2)];
- *(pd++) = b64_tbl_enc[(unsigned char)(inst->erem[0] << 4) | (inst->erem[1] >> 4)];
- *(pd++) = b64_tbl_enc[(unsigned char)(inst->erem[1] << 2)];
- *(pd++) = '=';
- inst->erem_len = 0;
- ocnt -=4;
- line_ccnt -= 4;
- break;
-
- default:
- /* should not happen... */
- err = PHP_CONV_ERR_UNKNOWN;
- break;
- }
-out:
- *out_pp = (char *)pd;
- *out_left_p = ocnt;
- inst->line_ccnt = line_ccnt;
- return err;
-}
-
-static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p)
-{
- volatile php_conv_err_t err = PHP_CONV_ERR_SUCCESS;
- register size_t ocnt, icnt;
- register unsigned char *ps, *pd;
- register unsigned int line_ccnt;
- size_t nbytes_written;
-
- if (in_pp == NULL || in_left_p == NULL) {
- return php_conv_base64_encode_flush(inst, in_pp, in_left_p, out_pp, out_left_p);
- }
-
- pd = (unsigned char *)(*out_pp);
- ocnt = *out_left_p;
- ps = (unsigned char *)(*in_pp);
- icnt = *in_left_p;
- line_ccnt = inst->line_ccnt;
- nbytes_written = 0;
-
- /* consume the remainder first */
- switch (inst->erem_len) {
- case 1:
- if (icnt >= 2) {
- if (line_ccnt < 4 && inst->lbchars != NULL) {
- if (ocnt < inst->lbchars_len) {
- return PHP_CONV_ERR_TOO_BIG;
- }
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- }
- if (ocnt < 4) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = b64_tbl_enc[(inst->erem[0] >> 2)];
- *(pd++) = b64_tbl_enc[(unsigned char)(inst->erem[0] << 4) | (ps[0] >> 4)];
- *(pd++) = b64_tbl_enc[(unsigned char)(ps[0] << 2) | (ps[1] >> 6)];
- *(pd++) = b64_tbl_enc[ps[1]];
- ocnt -= 4;
- ps += 2;
- icnt -= 2;
- inst->erem_len = 0;
- line_ccnt -= 4;
- }
- break;
-
- case 2:
- if (icnt >= 1) {
- if (inst->line_ccnt < 4 && inst->lbchars != NULL) {
- if (ocnt < inst->lbchars_len) {
- return PHP_CONV_ERR_TOO_BIG;
- }
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- }
- if (ocnt < 4) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = b64_tbl_enc[(inst->erem[0] >> 2)];
- *(pd++) = b64_tbl_enc[(unsigned char)(inst->erem[0] << 4) | (inst->erem[1] >> 4)];
- *(pd++) = b64_tbl_enc[(unsigned char)(inst->erem[1] << 2) | (ps[0] >> 6)];
- *(pd++) = b64_tbl_enc[ps[0]];
- ocnt -= 4;
- ps += 1;
- icnt -= 1;
- inst->erem_len = 0;
- line_ccnt -= 4;
- }
- break;
- }
-
- while (icnt >= 3) {
- if (line_ccnt < 4 && inst->lbchars != NULL) {
- if (ocnt < inst->lbchars_len) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- }
- if (ocnt < 4) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = b64_tbl_enc[ps[0] >> 2];
- *(pd++) = b64_tbl_enc[(unsigned char)(ps[0] << 4) | (ps[1] >> 4)];
- *(pd++) = b64_tbl_enc[(unsigned char)(ps[1] << 2) | (ps[2] >> 6)];
- *(pd++) = b64_tbl_enc[ps[2]];
-
- ps += 3;
- icnt -=3;
- ocnt -= 4;
- line_ccnt -= 4;
- }
- for (;icnt > 0; icnt--) {
- inst->erem[inst->erem_len++] = *(ps++);
- }
-
-out:
- *in_pp = (const char *)ps;
- *in_left_p = icnt;
- *out_pp = (char *)pd;
- *out_left_p = ocnt;
- inst->line_ccnt = line_ccnt;
-
- return err;
-}
-
-/* }}} */
-
-/* {{{ php_conv_base64_decode */
-typedef struct _php_conv_base64_decode {
- php_conv _super;
-
- unsigned int urem;
- unsigned int urem_nbits;
- unsigned int ustat;
- int eos;
-} php_conv_base64_decode;
-
-static php_conv_err_t php_conv_base64_decode_convert(php_conv_base64_decode *inst, const char **in_p, size_t *in_left, char **out_p, size_t *out_left);
-static void php_conv_base64_decode_dtor(php_conv_base64_decode *inst);
-
-static unsigned int b64_tbl_dec[256] = {
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64,128, 64, 64,
- 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
- 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
-};
-
-static int php_conv_base64_decode_ctor(php_conv_base64_decode *inst)
-{
- inst->_super.convert_op = (php_conv_convert_func) php_conv_base64_decode_convert;
- inst->_super.dtor = (php_conv_dtor_func) php_conv_base64_decode_dtor;
-
- inst->urem = 0;
- inst->urem_nbits = 0;
- inst->ustat = 0;
- inst->eos = 0;
- return SUCCESS;
-}
-
-static void php_conv_base64_decode_dtor(php_conv_base64_decode *inst)
-{
- /* do nothing */
-}
-
-#define bmask(a) (0xffff >> (16 - a))
-static php_conv_err_t php_conv_base64_decode_convert(php_conv_base64_decode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p)
-{
- php_conv_err_t err;
-
- unsigned int urem, urem_nbits;
- unsigned int pack, pack_bcnt;
- unsigned char *ps, *pd;
- size_t icnt, ocnt;
- unsigned int ustat;
-
- const static unsigned int nbitsof_pack = 8;
-
- if (in_pp == NULL || in_left_p == NULL) {
- if (inst->eos || inst->urem_nbits == 0) {
- return SUCCESS;
- }
- return PHP_CONV_ERR_UNEXPECTED_EOS;
- }
-
- err = PHP_CONV_ERR_SUCCESS;
-
- ps = (unsigned char *)*in_pp;
- pd = (unsigned char *)*out_pp;
- icnt = *in_left_p;
- ocnt = *out_left_p;
-
- urem = inst->urem;
- urem_nbits = inst->urem_nbits;
- ustat = inst->ustat;
-
- pack = 0;
- pack_bcnt = nbitsof_pack;
-
- for (;;) {
- if (pack_bcnt >= urem_nbits) {
- pack_bcnt -= urem_nbits;
- pack |= (urem << pack_bcnt);
- urem_nbits = 0;
- } else {
- urem_nbits -= pack_bcnt;
- pack |= (urem >> urem_nbits);
- urem &= bmask(urem_nbits);
- pack_bcnt = 0;
- }
- if (pack_bcnt > 0) {
- unsigned int i;
-
- if (icnt < 1) {
- break;
- }
-
- i = b64_tbl_dec[(unsigned int)*(ps++)];
- icnt--;
- ustat |= i & 0x80;
-
- if (!(i & 0xc0)) {
- if (ustat) {
- err = PHP_CONV_ERR_INVALID_SEQ;
- break;
- }
- if (6 <= pack_bcnt) {
- pack_bcnt -= 6;
- pack |= (i << pack_bcnt);
- urem = 0;
- } else {
- urem_nbits = 6 - pack_bcnt;
- pack |= (i >> urem_nbits);
- urem = i & bmask(urem_nbits);
- pack_bcnt = 0;
- }
- } else if (ustat) {
- if (pack_bcnt == 8 || pack_bcnt == 2) {
- err = PHP_CONV_ERR_INVALID_SEQ;
- break;
- }
- inst->eos = 1;
- }
- }
- if ((pack_bcnt | ustat) == 0) {
- if (ocnt < 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
- *(pd++) = pack;
- ocnt--;
- pack = 0;
- pack_bcnt = nbitsof_pack;
- }
- }
-
- if (urem_nbits >= pack_bcnt) {
- urem |= (pack << (urem_nbits - pack_bcnt));
- urem_nbits += (nbitsof_pack - pack_bcnt);
- } else {
- urem |= (pack >> (pack_bcnt - urem_nbits));
- urem_nbits += (nbitsof_pack - pack_bcnt);
- }
-
- inst->urem = urem;
- inst->urem_nbits = urem_nbits;
- inst->ustat = ustat;
-
- *in_pp = (const char *)ps;
- *in_left_p = icnt;
- *out_pp = (char *)pd;
- *out_left_p = ocnt;
-
- return err;
-}
-#undef bmask
-/* }}} */
-
-/* {{{ php_conv_qprint_encode */
-typedef struct _php_conv_qprint_encode {
- php_conv _super;
-
- int opts;
- unsigned int line_ccnt;
- unsigned int line_len;
- const char *lbchars;
- int lbchars_dup;
- size_t lbchars_len;
- int persistent;
- unsigned int lb_ptr;
- unsigned int lb_cnt;
-} php_conv_qprint_encode;
-
-#define PHP_CONV_QPRINT_OPT_BINARY 0x00000001
-#define PHP_CONV_QPRINT_OPT_FORCE_ENCODE_FIRST 0x00000002
-
-static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst);
-static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p);
-
-static void php_conv_qprint_encode_dtor(php_conv_qprint_encode *inst)
-{
- assert(inst != NULL);
- if (inst->lbchars_dup && inst->lbchars != NULL) {
- pefree((void *)inst->lbchars, inst->persistent);
- }
-}
-
-#define NEXT_CHAR(ps, icnt, lb_ptr, lb_cnt, lbchars) \
- ((lb_ptr) < (lb_cnt) ? (lbchars)[(lb_ptr)] : *(ps))
-
-#define CONSUME_CHAR(ps, icnt, lb_ptr, lb_cnt) \
- if ((lb_ptr) < (lb_cnt)) { \
- (lb_ptr)++; \
- } else { \
- (lb_cnt) = (lb_ptr) = 0; \
- --(icnt); \
- (ps)++; \
- }
-
-static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p)
-{
- php_conv_err_t err = PHP_CONV_ERR_SUCCESS;
- unsigned char *ps, *pd;
- size_t icnt, ocnt;
- unsigned int c;
- unsigned int line_ccnt;
- unsigned int lb_ptr;
- unsigned int lb_cnt;
- int opts;
- static char qp_digits[] = "0123456789ABCDEF";
-
- line_ccnt = inst->line_ccnt;
- opts = inst->opts;
- lb_ptr = inst->lb_ptr;
- lb_cnt = inst->lb_cnt;
-
- if ((in_pp == NULL || in_left_p == NULL) && (lb_ptr >=lb_cnt)) {
- return PHP_CONV_ERR_SUCCESS;
- }
-
- ps = (unsigned char *)(*in_pp);
- icnt = *in_left_p;
- pd = (unsigned char *)(*out_pp);
- ocnt = *out_left_p;
-
- for (;;) {
- if (!(opts & PHP_CONV_QPRINT_OPT_BINARY) && inst->lbchars != NULL && inst->lbchars_len > 0) {
- /* look ahead for the line break chars to make a right decision
- * how to consume incoming characters */
-
- if (icnt > 0 && *ps == inst->lbchars[lb_cnt]) {
- lb_cnt++;
-
- if (lb_cnt >= inst->lbchars_len) {
- unsigned int i;
-
- if (ocnt < lb_cnt) {
- lb_cnt--;
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
-
- for (i = 0; i < lb_cnt; i++) {
- *(pd++) = inst->lbchars[i];
- ocnt--;
- }
- line_ccnt = inst->line_len;
- lb_ptr = lb_cnt = 0;
- }
- ps++, icnt--;
- continue;
- }
- }
-
- if (lb_ptr >= lb_cnt && icnt <= 0) {
- break;
- }
-
- c = NEXT_CHAR(ps, icnt, lb_ptr, lb_cnt, inst->lbchars);
-
- if (!(opts & PHP_CONV_QPRINT_OPT_BINARY) && (c == '\t' || c == ' ')) {
- if (line_ccnt < 2 && inst->lbchars != NULL) {
- if (ocnt < inst->lbchars_len + 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
-
- *(pd++) = '=';
- ocnt--;
- line_ccnt--;
-
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- } else {
- if (ocnt < 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
- *(pd++) = c;
- ocnt--;
- line_ccnt--;
- CONSUME_CHAR(ps, icnt, lb_ptr, lb_cnt);
- }
- } else if ((!(opts & PHP_CONV_QPRINT_OPT_FORCE_ENCODE_FIRST) || line_ccnt < inst->line_len) && ((c >= 33 && c <= 60) || (c >= 62 && c <= 126))) {
- if (line_ccnt < 2) {
- if (ocnt < inst->lbchars_len + 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
- *(pd++) = '=';
- ocnt--;
- line_ccnt--;
-
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- }
- if (ocnt < 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
- *(pd++) = c;
- ocnt--;
- line_ccnt--;
- CONSUME_CHAR(ps, icnt, lb_ptr, lb_cnt);
- } else {
- if (line_ccnt < 4) {
- if (ocnt < inst->lbchars_len + 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
- *(pd++) = '=';
- ocnt--;
- line_ccnt--;
-
- memcpy(pd, inst->lbchars, inst->lbchars_len);
- pd += inst->lbchars_len;
- ocnt -= inst->lbchars_len;
- line_ccnt = inst->line_len;
- }
- if (ocnt < 3) {
- err = PHP_CONV_ERR_TOO_BIG;
- break;
- }
- *(pd++) = '=';
- *(pd++) = qp_digits[(c >> 4)];
- *(pd++) = qp_digits[(c & 0x0f)];
- ocnt -= 3;
- line_ccnt -= 3;
- CONSUME_CHAR(ps, icnt, lb_ptr, lb_cnt);
- }
- }
-
- *in_pp = (const char *)ps;
- *in_left_p = icnt;
- *out_pp = (char *)pd;
- *out_left_p = ocnt;
- inst->line_ccnt = line_ccnt;
- inst->lb_ptr = lb_ptr;
- inst->lb_cnt = lb_cnt;
- return err;
-}
-#undef NEXT_CHAR
-#undef CONSUME_CHAR
-
-static php_conv_err_t php_conv_qprint_encode_ctor(php_conv_qprint_encode *inst, unsigned int line_len, const char *lbchars, size_t lbchars_len, int lbchars_dup, int opts, int persistent)
-{
- if (line_len < 4 && lbchars != NULL) {
- return PHP_CONV_ERR_TOO_BIG;
- }
- inst->_super.convert_op = (php_conv_convert_func) php_conv_qprint_encode_convert;
- inst->_super.dtor = (php_conv_dtor_func) php_conv_qprint_encode_dtor;
- inst->line_ccnt = line_len;
- inst->line_len = line_len;
- if (lbchars != NULL) {
- inst->lbchars = (lbchars_dup ? pestrdup(lbchars, persistent) : lbchars);
- inst->lbchars_len = lbchars_len;
- } else {
- inst->lbchars = NULL;
- }
- inst->lbchars_dup = lbchars_dup;
- inst->persistent = persistent;
- inst->opts = opts;
- inst->lb_cnt = inst->lb_ptr = 0;
- return PHP_CONV_ERR_SUCCESS;
-}
-/* }}} */
-
-/* {{{ php_conv_qprint_decode */
-typedef struct _php_conv_qprint_decode {
- php_conv _super;
-
- int scan_stat;
- unsigned int next_char;
- const char *lbchars;
- int lbchars_dup;
- size_t lbchars_len;
- int persistent;
- unsigned int lb_ptr;
- unsigned int lb_cnt;
-} php_conv_qprint_decode;
-
-static void php_conv_qprint_decode_dtor(php_conv_qprint_decode *inst)
-{
- assert(inst != NULL);
- if (inst->lbchars_dup && inst->lbchars != NULL) {
- pefree((void *)inst->lbchars, inst->persistent);
- }
-}
-
-static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p)
-{
- php_conv_err_t err = PHP_CONV_ERR_SUCCESS;
- size_t icnt, ocnt;
- unsigned char *ps, *pd;
- unsigned int scan_stat;
- unsigned int next_char;
- unsigned int lb_ptr, lb_cnt;
-
- lb_ptr = inst->lb_ptr;
- lb_cnt = inst->lb_cnt;
-
- if ((in_pp == NULL || in_left_p == NULL) && lb_cnt == lb_ptr) {
- if (inst->scan_stat != 0) {
- return PHP_CONV_ERR_UNEXPECTED_EOS;
- }
- return PHP_CONV_ERR_SUCCESS;
- }
-
- ps = (unsigned char *)(*in_pp);
- icnt = *in_left_p;
- pd = (unsigned char *)(*out_pp);
- ocnt = *out_left_p;
- scan_stat = inst->scan_stat;
- next_char = inst->next_char;
-
- for (;;) {
- switch (scan_stat) {
- case 0: {
- if (icnt <= 0) {
- goto out;
- }
- if (*ps == '=') {
- scan_stat = 1;
- } else {
- if (ocnt < 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = *ps;
- ocnt--;
- }
- ps++, icnt--;
- } break;
-
- case 1: {
- if (icnt <= 0) {
- goto out;
- }
- if (*ps == ' ' || *ps == '\t') {
- scan_stat = 4;
- ps++, icnt--;
- break;
- } else if (lb_cnt < inst->lbchars_len &&
- *ps == (unsigned char)inst->lbchars[lb_cnt]) {
- lb_cnt++;
- scan_stat = 5;
- ps++, icnt--;
- break;
- }
- } /* break is missing intentionally */
-
- case 2: {
- unsigned int nbl;
-
- if (icnt <= 0) {
- goto out;
- }
- nbl = (*ps >= 'A' ? *ps - 0x37 : *ps - 0x30);
-
- if (nbl > 15) {
- err = PHP_CONV_ERR_INVALID_SEQ;
- goto out;
- }
- next_char = (next_char << 4) | nbl;
-
- scan_stat++;
- ps++, icnt--;
- if (scan_stat != 3) {
- break;
- }
- } /* break is missing intentionally */
-
- case 3: {
- if (ocnt < 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = next_char;
- ocnt--;
- scan_stat = 0;
- } break;
-
- case 4: {
- if (icnt <= 0) {
- goto out;
- }
- if (lb_cnt < inst->lbchars_len &&
- *ps == (unsigned char)inst->lbchars[lb_cnt]) {
- lb_cnt++;
- scan_stat = 5;
- }
- if (*ps != '\t' && *ps != ' ') {
- err = PHP_CONV_ERR_INVALID_SEQ;
- goto out;
- }
- ps++, icnt--;
- } break;
-
- case 5: {
- if (lb_cnt >= inst->lbchars_len) {
- /* soft line break */
- lb_cnt = lb_ptr = 0;
- scan_stat = 0;
- } else if (icnt > 0) {
- if (*ps == (unsigned char)inst->lbchars[lb_cnt]) {
- lb_cnt++;
- ps++, icnt--;
- } else {
- scan_stat = 6; /* no break for short-cut */
- }
- } else {
- goto out;
- }
- } break;
-
- case 6: {
- if (lb_ptr < lb_cnt) {
- if (ocnt < 1) {
- err = PHP_CONV_ERR_TOO_BIG;
- goto out;
- }
- *(pd++) = inst->lbchars[lb_ptr++];
- ocnt--;
- } else {
- scan_stat = 0;
- lb_cnt = lb_ptr = 0;
- }
- } break;
- }
- }
-out:
- *in_pp = (const char *)ps;
- *in_left_p = icnt;
- *out_pp = (char *)pd;
- *out_left_p = ocnt;
- inst->scan_stat = scan_stat;
- inst->lb_ptr = lb_ptr;
- inst->lb_cnt = lb_cnt;
- inst->next_char = next_char;
-
- return err;
-}
-static php_conv_err_t php_conv_qprint_decode_ctor(php_conv_qprint_decode *inst, const char *lbchars, size_t lbchars_len, int lbchars_dup, int persistent)
-{
- inst->_super.convert_op = (php_conv_convert_func) php_conv_qprint_decode_convert;
- inst->_super.dtor = (php_conv_dtor_func) php_conv_qprint_decode_dtor;
- inst->scan_stat = 0;
- inst->next_char = 0;
- inst->lb_ptr = inst->lb_cnt = 0;
- if (lbchars != NULL) {
- inst->lbchars = (lbchars_dup ? pestrdup(lbchars, persistent) : lbchars);
- inst->lbchars_len = lbchars_len;
- } else {
- inst->lbchars = NULL;
- inst->lbchars_len = 0;
- }
- inst->lbchars_dup = lbchars_dup;
- inst->persistent = persistent;
- return PHP_CONV_ERR_SUCCESS;
-}
-/* }}} */
-
-typedef struct _php_convert_filter {
- php_conv *cd;
- int persistent;
- char *filtername;
-} php_convert_filter;
-
-#define PHP_CONV_BASE64_ENCODE 1
-#define PHP_CONV_BASE64_DECODE 2
-#define PHP_CONV_QPRINT_ENCODE 3
-#define PHP_CONV_QPRINT_DECODE 4
-
-static php_conv_err_t php_conv_get_string_prop_ex(const HashTable *ht, char **pretval, size_t *pretval_len, char *field_name, size_t field_name_len, int persistent)
-{
- zval **tmpval;
-
- *pretval = NULL;
- *pretval_len = 0;
-
- if (zend_hash_find((HashTable *)ht, field_name, field_name_len, (void **)&tmpval) == SUCCESS) {
- if (Z_TYPE_PP(tmpval) != IS_STRING) {
- zval zt = **tmpval;
- convert_to_string(&zt);
- *pretval = pemalloc(Z_STRLEN(zt) + 1, persistent);
- *pretval_len = Z_STRLEN(zt);
- memcpy(*pretval, Z_STRVAL(zt), Z_STRLEN(zt) + 1);
- zval_dtor(&zt);
- } else {
- *pretval = pemalloc(Z_STRLEN_PP(tmpval) + 1, persistent);
- *pretval_len = Z_STRLEN_PP(tmpval);
- memcpy(*pretval, Z_STRVAL_PP(tmpval), Z_STRLEN_PP(tmpval) + 1);
- }
- } else {
- return PHP_CONV_ERR_NOT_FOUND;
- }
- return PHP_CONV_ERR_SUCCESS;
-}
-
-static php_conv_err_t php_conv_get_long_prop_ex(const HashTable *ht, long *pretval, char *field_name, size_t field_name_len)
-{
- zval **tmpval;
-
- *pretval = 0;
-
- if (zend_hash_find((HashTable *)ht, field_name, field_name_len, (void **)&tmpval) == SUCCESS) {
- zval tmp, *ztval = *tmpval;
-
- if (Z_TYPE_PP(tmpval) != IS_LONG) {
- tmp = *ztval;
- zval_copy_ctor(&tmp);
- convert_to_long(&tmp);
- ztval = &tmp;
- }
- *pretval = Z_LVAL_P(ztval);
- } else {
- return PHP_CONV_ERR_NOT_FOUND;
- }
- return PHP_CONV_ERR_SUCCESS;
-}
-
-static php_conv_err_t php_conv_get_ulong_prop_ex(const HashTable *ht, unsigned long *pretval, char *field_name, size_t field_name_len)
-{
- zval **tmpval;
-
- *pretval = 0;
-
- if (zend_hash_find((HashTable *)ht, field_name, field_name_len, (void **)&tmpval) == SUCCESS) {
- zval tmp, *ztval = *tmpval;
-
- if (Z_TYPE_PP(tmpval) != IS_LONG) {
- tmp = *ztval;
- zval_copy_ctor(&tmp);
- convert_to_long(&tmp);
- ztval = &tmp;
- }
- if (Z_LVAL_P(ztval) < 0) {
- *pretval = 0;
- } else {
- *pretval = Z_LVAL_P(ztval);
- }
- } else {
- return PHP_CONV_ERR_NOT_FOUND;
- }
- return PHP_CONV_ERR_SUCCESS;
-}
-
-static php_conv_err_t php_conv_get_bool_prop_ex(const HashTable *ht, int *pretval, char *field_name, size_t field_name_len)
-{
- zval **tmpval;
-
- *pretval = 0;
-
- if (zend_hash_find((HashTable *)ht, field_name, field_name_len, (void **)&tmpval) == SUCCESS) {
- zval tmp, *ztval = *tmpval;
-
- if (Z_TYPE_PP(tmpval) != IS_BOOL) {
- tmp = *ztval;
- zval_copy_ctor(&tmp);
- convert_to_boolean(&tmp);
- ztval = &tmp;
- }
- *pretval = Z_BVAL_P(ztval);
- } else {
- return PHP_CONV_ERR_NOT_FOUND;
- }
- return PHP_CONV_ERR_SUCCESS;
-}
-
-
-static int php_conv_get_int_prop_ex(const HashTable *ht, int *pretval, char *field_name, size_t field_name_len)
-{
- long l;
- php_conv_err_t err;
-
- *pretval = 0;
-
- if ((err = php_conv_get_long_prop_ex(ht, &l, field_name, field_name_len)) == PHP_CONV_ERR_SUCCESS) {
- *pretval = l;
- }
- return err;
-}
-
-static int php_conv_get_uint_prop_ex(const HashTable *ht, unsigned int *pretval, char *field_name, size_t field_name_len)
-{
- long l;
- php_conv_err_t err;
-
- *pretval = 0;
-
- if ((err = php_conv_get_ulong_prop_ex(ht, &l, field_name, field_name_len)) == PHP_CONV_ERR_SUCCESS) {
- *pretval = l;
- }
- return err;
-}
-
-#define GET_STR_PROP(ht, var, var_len, fldname, persistent) \
- php_conv_get_string_prop_ex(ht, &var, &var_len, fldname, sizeof(fldname), persistent)
-
-#define GET_INT_PROP(ht, var, fldname) \
- php_conv_get_int_prop_ex(ht, &var, fldname, sizeof(fldname))
-
-#define GET_UINT_PROP(ht, var, fldname) \
- php_conv_get_uint_prop_ex(ht, &var, fldname, sizeof(fldname))
-
-#define GET_BOOL_PROP(ht, var, fldname) \
- php_conv_get_bool_prop_ex(ht, &var, fldname, sizeof(fldname))
-
-static php_conv *php_conv_open(int conv_mode, const HashTable *options, int persistent)
-{
- /* FIXME: I'll have to replace this ugly code by something neat
- (factories?) in the near future. */
- php_conv *retval = NULL;
-
- switch (conv_mode) {
- case PHP_CONV_BASE64_ENCODE: {
- unsigned int line_len = 0;
- char *lbchars = NULL;
- size_t lbchars_len;
-
- if (options != NULL) {
- GET_STR_PROP(options, lbchars, lbchars_len, "line-break-chars", 0);
- GET_UINT_PROP(options, line_len, "line-length");
- if (line_len < 4) {
- if (lbchars != NULL) {
- pefree(lbchars, 0);
- }
- lbchars = NULL;
- } else {
- if (lbchars == NULL) {
- lbchars = pestrdup("\r\n", 0);
- lbchars_len = 2;
- }
- }
- }
- retval = pemalloc(sizeof(php_conv_base64_encode), persistent);
- if (lbchars != NULL) {
- if (php_conv_base64_encode_ctor((php_conv_base64_encode *)retval, line_len, lbchars, lbchars_len, 1, persistent)) {
- if (lbchars != NULL) {
- pefree(lbchars, 0);
- }
- goto out_failure;
- }
- pefree(lbchars, 0);
- } else {
- if (php_conv_base64_encode_ctor((php_conv_base64_encode *)retval, 0, NULL, 0, 0, persistent)) {
- goto out_failure;
- }
- }
- } break;
-
- case PHP_CONV_BASE64_DECODE:
- retval = pemalloc(sizeof(php_conv_base64_decode), persistent);
- if (php_conv_base64_decode_ctor((php_conv_base64_decode *)retval)) {
- goto out_failure;
- }
- break;
-
- case PHP_CONV_QPRINT_ENCODE: {
- unsigned int line_len = 0;
- char *lbchars = NULL;
- size_t lbchars_len;
- int opts = 0;
-
- if (options != NULL) {
- int opt_binary = 0;
- int opt_force_encode_first = 0;
-
- GET_STR_PROP(options, lbchars, lbchars_len, "line-break-chars", 0);
- GET_UINT_PROP(options, line_len, "line-length");
- GET_BOOL_PROP(options, opt_binary, "binary");
- GET_BOOL_PROP(options, opt_force_encode_first, "force-encode-first");
-
- if (line_len < 4) {
- if (lbchars != NULL) {
- pefree(lbchars, 0);
- }
- lbchars = NULL;
- } else {
- if (lbchars == NULL) {
- lbchars = pestrdup("\r\n", 0);
- lbchars_len = 2;
- }
- }
- opts |= (opt_binary ? PHP_CONV_QPRINT_OPT_BINARY : 0);
- opts |= (opt_force_encode_first ? PHP_CONV_QPRINT_OPT_FORCE_ENCODE_FIRST : 0);
- }
- retval = pemalloc(sizeof(php_conv_qprint_encode), persistent);
- if (lbchars != NULL) {
- if (php_conv_qprint_encode_ctor((php_conv_qprint_encode *)retval, line_len, lbchars, lbchars_len, 1, opts, persistent)) {
- pefree(lbchars, 0);
- goto out_failure;
- }
- pefree(lbchars, 0);
- } else {
- if (php_conv_qprint_encode_ctor((php_conv_qprint_encode *)retval, 0, NULL, 0, 0, opts, persistent)) {
- goto out_failure;
- }
- }
- } break;
-
- case PHP_CONV_QPRINT_DECODE: {
- char *lbchars = NULL;
- size_t lbchars_len;
-
- if (options != NULL) {
- GET_STR_PROP(options, lbchars, lbchars_len, "line-break-chars", 0);
- if (lbchars == NULL) {
- lbchars = pestrdup("\r\n", 0);
- lbchars_len = 2;
- }
- }
- retval = pemalloc(sizeof(php_conv_qprint_decode), persistent);
- if (lbchars != NULL) {
- if (php_conv_qprint_decode_ctor((php_conv_qprint_decode *)retval, lbchars, lbchars_len, 1, persistent)) {
- pefree(lbchars, 0);
- goto out_failure;
- }
- pefree(lbchars, 0);
- } else {
- if (php_conv_qprint_decode_ctor((php_conv_qprint_decode *)retval, NULL, 0, 0, persistent)) {
- goto out_failure;
- }
- }
- } break;
-
- default:
- retval = NULL;
- break;
- }
- return retval;
-
-out_failure:
- if (retval != NULL) {
- pefree(retval, persistent);
- }
- return NULL;
-}
-
-#undef GET_STR_PROP
-#undef GET_INT_PROP
-#undef GET_UINT_PROP
-#undef GET_BOOL_PROP
-
-static int php_convert_filter_ctor(php_convert_filter *inst,
- int conv_mode, HashTable *conv_opts,
- const char *filtername, int persistent)
-{
- inst->persistent = persistent;
- inst->filtername = pestrdup(filtername, persistent);
-
- if ((inst->cd = php_conv_open(conv_mode, conv_opts, persistent)) == NULL) {
- goto out_failure;
- }
-
- return SUCCESS;
-
-out_failure:
- if (inst->cd != NULL) {
- php_conv_dtor(inst->cd);
- pefree(inst->cd, persistent);
- }
- if (inst->filtername != NULL) {
- pefree(inst->filtername, persistent);
- }
- return FAILURE;
-}
-
-static void php_convert_filter_dtor(php_convert_filter *inst)
-{
- if (inst->cd != NULL) {
- php_conv_dtor(inst->cd);
- pefree(inst->cd, inst->persistent);
- }
-
- if (inst->filtername != NULL) {
- pefree(inst->filtername, inst->persistent);
- }
-}
-
-static php_stream_filter_status_t strfilter_convert_filter(
- php_stream *stream,
- php_stream_filter *thisfilter,
- php_stream_bucket_brigade *buckets_in,
- php_stream_bucket_brigade *buckets_out,
- size_t *bytes_consumed,
- int flags
- TSRMLS_DC)
-{
- php_stream_bucket *bucket = NULL, *new_bucket;
- size_t consumed = 0;
- php_conv_err_t err;
- php_convert_filter *inst = (php_convert_filter *)thisfilter->abstract;
- char *out_buf = NULL;
- size_t out_buf_size;
- char *pd;
- size_t ocnt;
-
- if (buckets_in->head == NULL && buckets_in->tail == NULL) {
- /* flush operation */
-
- out_buf_size = 64;
- out_buf = pemalloc(out_buf_size, inst->persistent);
- ocnt = out_buf_size;
- pd = out_buf;
-
- /* trying hard to reduce the number of buckets to hand to the
- * next filter */
-
- for (;;) {
- err = php_conv_convert(inst->cd, NULL, NULL, &pd, &ocnt);
-
- switch (err) {
- case PHP_CONV_ERR_UNKNOWN:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unknown error", inst->filtername, err);
- goto out_failure;
-
- case PHP_CONV_ERR_INVALID_SEQ:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): invalid base64 sequence", inst->filtername, err);
- goto out_failure;
-
- case PHP_CONV_ERR_UNEXPECTED_EOS:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unexpected end of stream", inst->filtername, err);
- goto out_failure;
-
- default:
- break;
- }
-
- if (err != PHP_CONV_ERR_TOO_BIG) {
- break;
- } else {
- char *new_out_buf;
- size_t new_out_buf_size;
-
- new_out_buf_size = out_buf_size << 1;
-
- if (new_out_buf_size < out_buf_size) {
- /* whoa! no bigger buckets are sold anywhere... */
- new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC);
-
- php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC);
-
- out_buf_size = bucket->buflen;
- out_buf = pemalloc(out_buf_size, inst->persistent);
- ocnt = out_buf_size;
- pd = out_buf;
- } else {
- new_out_buf = perealloc(out_buf, new_out_buf_size, inst->persistent);
- pd = new_out_buf + (pd - out_buf);
- ocnt += (new_out_buf_size - out_buf_size);
- out_buf = new_out_buf;
- out_buf_size = new_out_buf_size;
- }
- }
- }
- /* give output bucket to next in chain */
- if (out_buf_size - ocnt > 0) {
- new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC);
- php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC);
- }
- } else {
- while (buckets_in->head != NULL) {
- const char *ps;
- size_t icnt;
-
- bucket = buckets_in->head;
-
- php_stream_bucket_unlink(bucket TSRMLS_CC);
- icnt = bucket->buflen;
- ps = bucket->buf;
-
- out_buf_size = bucket->buflen;
- out_buf = pemalloc(out_buf_size, inst->persistent);
- ocnt = out_buf_size;
- pd = out_buf;
-
- /* trying hard to reduce the number of buckets to hand to the
- * next filter */
-
- while (icnt > 0) {
- err = php_conv_convert(inst->cd, &ps, &icnt, &pd, &ocnt);
-
- switch (err) {
- case PHP_CONV_ERR_UNKNOWN:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unknown error", inst->filtername, err);
- goto out_failure;
-
- case PHP_CONV_ERR_INVALID_SEQ:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): invalid base64 sequence", inst->filtername, err);
- goto out_failure;
-
- case PHP_CONV_ERR_UNEXPECTED_EOS:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): unexpected end of stream", inst->filtername, err);
- goto out_failure;
-
- default:
- break;
- }
-
- if (err == PHP_CONV_ERR_TOO_BIG) {
- char *new_out_buf;
- size_t new_out_buf_size;
-
- new_out_buf_size = out_buf_size << 1;
-
- if (new_out_buf_size < out_buf_size) {
- /* whoa! no bigger buckets are sold anywhere... */
- new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC);
-
- php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC);
-
- out_buf_size = bucket->buflen;
- out_buf = pemalloc(out_buf_size, inst->persistent);
- ocnt = out_buf_size;
- pd = out_buf;
- } else {
- new_out_buf = perealloc(out_buf, new_out_buf_size, inst->persistent);
- pd = new_out_buf + (pd - out_buf);
- ocnt += (new_out_buf_size - out_buf_size);
- out_buf = new_out_buf;
- out_buf_size = new_out_buf_size;
- }
- }
- }
-
- /* update consumed by the number of bytes just used */
- consumed = bucket->buflen - icnt;
-
- /* give output bucket to next in chain */
- if (out_buf_size - ocnt > 0) {
- new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, inst->persistent TSRMLS_CC);
- php_stream_bucket_append(buckets_out, new_bucket TSRMLS_CC);
- }
-
- php_stream_bucket_delref(bucket TSRMLS_CC);
- }
- }
-
- if (bytes_consumed) {
- *bytes_consumed = consumed;
- }
-
- return PSFS_PASS_ON;
-
-out_failure:
- if (out_buf != NULL) {
- pefree(out_buf, inst->persistent);
- }
- if (bucket != NULL) {
- php_stream_bucket_delref(bucket TSRMLS_CC);
- }
- return PSFS_ERR_FATAL;
-}
-
-static void strfilter_convert_dtor(php_stream_filter *thisfilter TSRMLS_DC)
-{
- assert(thisfilter->abstract != NULL);
-
- php_convert_filter_dtor((php_convert_filter *)thisfilter->abstract);
- pefree(thisfilter->abstract, ((php_convert_filter *)thisfilter->abstract)->persistent);
-}
-
-static php_stream_filter_ops strfilter_convert_ops = {
- strfilter_convert_filter,
- strfilter_convert_dtor,
- "convert.*"
-};
-
-static zval *strfilter_convert_parse_parameters(const char *param_str)
-{
- zval *retval, *node;
- const unsigned char *p;
- char *node_name;
- char *value;
- size_t node_name_len, value_len;
- int scan_stat;
- char *buf;
- size_t buf_size;
-
- static int scancode_tbl[256] = {
- -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 3, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- };
-
-
- MAKE_STD_ZVAL(retval);
- array_init(retval);
-
- node = retval;
- node_name = NULL;
- node_name_len = 0;
- value = NULL;
- buf = NULL;
- buf_size = 0;
-
- scan_stat = 0;
- p = (const unsigned char *)param_str;
- for (;;) {
- int m = scancode_tbl[(unsigned int)*p];
- switch (m) {
- case 2: /* '=' */
- switch (scan_stat) {
- case 2:
- node_name_len = (size_t)((char *)p - node_name);
- scan_stat = 3;
- break;
-
- case 3:
- goto out_failure;
- }
- break;
-
- case 5: /* ',' */
- case -1: /* EOS */
- if (value == NULL) {
- value = empty_string;
- value_len = 0;
- } else {
- value_len = (size_t)((char *)p - value);
- }
- if (node_name != NULL) {
- zval *new_val;
-
- if (buf_size <= node_name_len) {
- char *new_buf;
-
- buf_size = node_name_len + 1;
- new_buf = erealloc(buf, buf_size);
- assert(new_buf != NULL);
- buf = new_buf;
- }
- memcpy(buf, node_name, node_name_len);
- buf[node_name_len] = '\0';
-
- MAKE_STD_ZVAL(new_val);
- ZVAL_STRINGL(new_val, value, (int)value_len, 1);
- zend_hash_update(Z_ARRVAL_P(node), buf, node_name_len + 1, &new_val, sizeof(zval *), NULL);
- node_name = NULL;
- }
- value = NULL;
- node = retval;
- scan_stat = 0;
- if (m == -1) {
- goto end_scan;
- }
- break;
-
- case 3: /* '.' */
- switch (scan_stat) {
- case 0: case 1:
- node_name = (char *)p;
- case 2: {
- zval **z_tmp;
-
- node_name_len = (size_t)((char *)p - node_name);
-
- if (buf_size <= node_name_len) {
- char *new_buf;
-
- buf_size = node_name_len + 1;
- new_buf = erealloc(buf, buf_size);
- assert(new_buf != NULL);
- buf = new_buf;
- }
- memcpy(buf, node_name, node_name_len);
- buf[node_name_len] = '\0';
-
- if (zend_hash_find(Z_ARRVAL_P(node), buf, node_name_len + 1, (void **)&z_tmp) != SUCCESS || Z_TYPE_PP(z_tmp) != IS_ARRAY) {
- zval *new_node;
-
- MAKE_STD_ZVAL(new_node);
- array_init(new_node);
- zend_hash_update(Z_ARRVAL_P(node), buf, node_name_len + 1, &new_node, sizeof(zval *), NULL);
- node = new_node;
- } else {
- node = *z_tmp;
- }
- scan_stat = 1;
- } break;
-
- case 3:
- value = (char *)p;
- scan_stat = 4;
- case 4:
- break;
- }
- break;
-
- case 4: /* ' ' */
- switch (scan_stat) {
- default:
- goto out_failure;
-
- case 0:
- scan_stat = 1;
- break;
-
- case 1:
- break;
-
- case 3:
- value = (char *)p;
- scan_stat = 4;
- case 4:
- break;
- }
- break;
-
- case 1:
- switch (scan_stat) {
- case 0: case 1:
- node_name = (char *)p;
- scan_stat = 2;
- break;
-
- case 3:
- value = (char *)p;
- scan_stat = 4;
- break;
- }
- break;
- }
- p++;
- }
-end_scan:
- if (buf != NULL) {
- efree(buf);
- }
- return retval;
-
-out_failure:
- if (buf != NULL) {
- efree(buf);
- }
- zval_dtor(retval);
- FREE_ZVAL(retval);
- return NULL;
-}
-
-static php_stream_filter *strfilter_convert_create(const char *filtername, const char *filterparams,
- int filterparamslen, int persistent TSRMLS_DC)
-{
- php_convert_filter *inst;
- php_stream_filter *retval = NULL;
- char *dot;
- zval *options = NULL;
- int conv_mode;
-
- if ((dot = strchr(filtername, '.')) == NULL) {
- return NULL;
- }
- ++dot;
-
- inst = pemalloc(sizeof(php_convert_filter), persistent);
-
- if (filterparams != NULL) {
- options = strfilter_convert_parse_parameters(filterparams);
- if (options == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream filter (%s): invalid filter parameter \"%s\"", filtername, filterparams);
- }
- }
-
- if (strcasecmp(dot, "base64-encode") == 0) {
- conv_mode = PHP_CONV_BASE64_ENCODE;
- } else if (strcasecmp(dot, "base64-decode") == 0) {
- conv_mode = PHP_CONV_BASE64_DECODE;
- } else if (strcasecmp(dot, "quoted-printable-encode") == 0) {
- conv_mode = PHP_CONV_QPRINT_ENCODE;
- } else if (strcasecmp(dot, "quoted-printable-decode") == 0) {
- conv_mode = PHP_CONV_QPRINT_DECODE;
- }
-
- if (php_convert_filter_ctor(inst, conv_mode,
- (options != NULL ? Z_ARRVAL_P(options) : NULL),
- filtername, persistent) != SUCCESS) {
- goto out;
- }
-
- retval = php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent);
-out:
- if (retval == NULL) {
- pefree(inst, persistent);
- }
-
- if (options != NULL) {
- zval_ptr_dtor(&options);
- }
- return retval;
-}
-
-static php_stream_filter_factory strfilter_convert_factory = {
- strfilter_convert_create
-};
-/* }}} */
-
-static const struct {
- php_stream_filter_ops *ops;
- php_stream_filter_factory *factory;
-} standard_filters[] = {
- { &strfilter_rot13_ops, &strfilter_rot13_factory },
- { &strfilter_toupper_ops, &strfilter_toupper_factory },
- { &strfilter_tolower_ops, &strfilter_tolower_factory },
- { &strfilter_strip_tags_ops, &strfilter_strip_tags_factory },
- { &strfilter_convert_ops, &strfilter_convert_factory },
- /* additional filters to go here */
- { NULL, NULL }
-};
-
-/* {{{ filter MINIT and MSHUTDOWN */
-PHP_MINIT_FUNCTION(standard_filters)
-{
- int i;
-
- for (i = 0; standard_filters[i].ops; i++) {
- if (FAILURE == php_stream_filter_register_factory(
- standard_filters[i].ops->label,
- standard_filters[i].factory
- TSRMLS_CC)) {
- return FAILURE;
- }
- }
- return SUCCESS;
-}
-
-PHP_MSHUTDOWN_FUNCTION(standard_filters)
-{
- int i;
-
- for (i = 0; standard_filters[i].ops; i++) {
- php_stream_filter_unregister_factory(standard_filters[i].ops->label TSRMLS_CC);
- }
- return SUCCESS;
-}
-/* }}} */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */