Linux ip-172-26-2-223 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64
Apache
: 172.26.2.223 | : 18.188.59.124
Cant Read [ /etc/named.conf ]
8.1.13
www
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
www /
server /
php /
80 /
src /
ext /
standard /
[ HOME SHELL ]
Name
Size
Permission
Action
html_tables
[ DIR ]
drwxr-xr-x
tests
[ DIR ]
drwxr-xr-x
Makefile.frag
518
B
-rw-r--r--
Makefile.frag.w32
484
B
-rw-r--r--
array.c
173.39
KB
-rw-r--r--
assert.c
8.25
KB
-rw-r--r--
base64.c
30.63
KB
-rw-r--r--
base64.h
3.59
KB
-rw-r--r--
basic_functions.c
67.72
KB
-rw-r--r--
basic_functions.h
5.03
KB
-rw-r--r--
basic_functions.stub.php
41.8
KB
-rw-r--r--
basic_functions_arginfo.h
123.78
KB
-rw-r--r--
browscap.c
20.65
KB
-rw-r--r--
config.m4
11.12
KB
-rw-r--r--
config.w32
1.79
KB
-rw-r--r--
crc32.c
3.11
KB
-rw-r--r--
crc32.h
4.5
KB
-rw-r--r--
crc32_x86.c
11.99
KB
-rw-r--r--
crc32_x86.h
1.82
KB
-rw-r--r--
credits.c
5.71
KB
-rw-r--r--
credits.h
1.53
KB
-rw-r--r--
credits_ext.h
5.24
KB
-rw-r--r--
credits_sapi.h
835
B
-rw-r--r--
crypt.c
6.73
KB
-rw-r--r--
crypt_blowfish.c
30.75
KB
-rw-r--r--
crypt_blowfish.h
790
B
-rw-r--r--
crypt_freesec.c
21.52
KB
-rw-r--r--
crypt_freesec.h
662
B
-rw-r--r--
crypt_sha256.c
21.6
KB
-rw-r--r--
crypt_sha512.c
26.25
KB
-rw-r--r--
css.c
2.24
KB
-rw-r--r--
css.h
1.04
KB
-rw-r--r--
datetime.c
3.28
KB
-rw-r--r--
datetime.h
1.14
KB
-rw-r--r--
dir.c
13.95
KB
-rw-r--r--
dir.stub.php
387
B
-rw-r--r--
dir_arginfo.h
746
B
-rw-r--r--
dl.c
8.21
KB
-rw-r--r--
dl.h
1.46
KB
-rw-r--r--
dl.stub.php
56
B
-rw-r--r--
dl_arginfo.h
269
B
-rw-r--r--
dns.c
28.31
KB
-rw-r--r--
dns_win32.c
14.9
KB
-rw-r--r--
exec.c
12.78
KB
-rw-r--r--
exec.h
1.27
KB
-rw-r--r--
file.c
64.34
KB
-rw-r--r--
file.h
3.91
KB
-rw-r--r--
filestat.c
26.73
KB
-rw-r--r--
filters.c
50.04
KB
-rw-r--r--
flock_compat.c
6.44
KB
-rw-r--r--
flock_compat.h
2.06
KB
-rw-r--r--
formatted_print.c
23.37
KB
-rw-r--r--
fsock.c
3.67
KB
-rw-r--r--
fsock.h
1.22
KB
-rw-r--r--
ftok.c
1.84
KB
-rw-r--r--
ftp_fopen_wrapper.c
31.59
KB
-rw-r--r--
head.c
10.66
KB
-rw-r--r--
head.h
1.53
KB
-rw-r--r--
hrtime.c
4.86
KB
-rw-r--r--
hrtime.h
2.31
KB
-rw-r--r--
html.c
44.87
KB
-rw-r--r--
html.h
2.35
KB
-rw-r--r--
html_tables.h
472.26
KB
-rw-r--r--
http.c
6.99
KB
-rw-r--r--
http_fopen_wrapper.c
32.39
KB
-rw-r--r--
image.c
41.83
KB
-rw-r--r--
incomplete_class.c
5.16
KB
-rw-r--r--
info.c
39.87
KB
-rw-r--r--
info.h
22.94
KB
-rw-r--r--
iptc.c
9.18
KB
-rw-r--r--
lcg.c
2.8
KB
-rw-r--r--
levenshtein.c
2.57
KB
-rw-r--r--
link.c
5.45
KB
-rw-r--r--
mail.c
16.25
KB
-rw-r--r--
math.c
27.2
KB
-rw-r--r--
md5.c
10.62
KB
-rw-r--r--
md5.h
1.92
KB
-rw-r--r--
metaphone.c
11.53
KB
-rw-r--r--
microtime.c
4.01
KB
-rw-r--r--
mt_rand.c
10.53
KB
-rw-r--r--
net.c
8.97
KB
-rw-r--r--
pack.c
31.01
KB
-rw-r--r--
pack.h
1.05
KB
-rw-r--r--
pageinfo.c
3.23
KB
-rw-r--r--
pageinfo.h
1.15
KB
-rw-r--r--
password.c
19.21
KB
-rw-r--r--
php_array.h
2.25
KB
-rw-r--r--
php_assert.h
1.18
KB
-rw-r--r--
php_browscap.h
1.11
KB
-rw-r--r--
php_crypt.h
1.37
KB
-rw-r--r--
php_crypt_r.c
5.74
KB
-rw-r--r--
php_crypt_r.h
1.63
KB
-rw-r--r--
php_dir.h
1.28
KB
-rw-r--r--
php_dns.h
2.58
KB
-rw-r--r--
php_ext_syslog.h
1.25
KB
-rw-r--r--
php_filestat.h
2.11
KB
-rw-r--r--
php_fopen_wrapper.c
11.47
KB
-rw-r--r--
php_fopen_wrappers.h
1.79
KB
-rw-r--r--
php_http.h
1.44
KB
-rw-r--r--
php_image.h
2.1
KB
-rw-r--r--
php_incomplete_class.h
2.15
KB
-rw-r--r--
php_lcg.h
1.31
KB
-rw-r--r--
php_mail.h
2.16
KB
-rw-r--r--
php_math.h
3.55
KB
-rw-r--r--
php_mt_rand.h
1.81
KB
-rw-r--r--
php_net.h
1.14
KB
-rw-r--r--
php_password.h
2.77
KB
-rw-r--r--
php_rand.h
3
KB
-rw-r--r--
php_random.h
1.87
KB
-rw-r--r--
php_smart_string.h
1.13
KB
-rw-r--r--
php_smart_string_public.h
1.14
KB
-rw-r--r--
php_standard.h
1.91
KB
-rw-r--r--
php_string.h
3.96
KB
-rw-r--r--
php_uuencode.h
1.18
KB
-rw-r--r--
php_var.h
3.41
KB
-rw-r--r--
php_versioning.h
1.18
KB
-rw-r--r--
proc_open.c
35.27
KB
-rw-r--r--
proc_open.h
1.66
KB
-rw-r--r--
quot_print.c
7.05
KB
-rw-r--r--
quot_print.h
1.23
KB
-rw-r--r--
rand.c
2.22
KB
-rw-r--r--
random.c
7.22
KB
-rw-r--r--
scanf.c
28.23
KB
-rw-r--r--
scanf.h
1.95
KB
-rw-r--r--
sha1.c
11.18
KB
-rw-r--r--
sha1.h
1.53
KB
-rw-r--r--
soundex.c
2.94
KB
-rw-r--r--
streamsfuncs.c
43.24
KB
-rw-r--r--
streamsfuncs.h
1.11
KB
-rw-r--r--
string.c
142.27
KB
-rw-r--r--
strnatcmp.c
4.34
KB
-rw-r--r--
syslog.c
6.05
KB
-rw-r--r--
type.c
10.49
KB
-rw-r--r--
uniqid.c
2.43
KB
-rw-r--r--
url.c
18.11
KB
-rw-r--r--
url.h
2.09
KB
-rw-r--r--
url_scanner_ex.c
38.41
KB
-rw-r--r--
url_scanner_ex.h
2.32
KB
-rw-r--r--
url_scanner_ex.re
27.63
KB
-rw-r--r--
user_filters.c
16.53
KB
-rw-r--r--
user_filters.stub.php
371
B
-rw-r--r--
user_filters_arginfo.h
987
B
-rw-r--r--
uuencode.c
6.35
KB
-rw-r--r--
var.c
37.2
KB
-rw-r--r--
var_unserializer.c
37.95
KB
-rw-r--r--
var_unserializer.re
30.26
KB
-rw-r--r--
versioning.c
5.61
KB
-rw-r--r--
winver.h
6.23
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : filters.c
/* +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.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) | | Sara Golemon (pollita@php.net) | | Moriyoshi Koizumi (moriyoshi@php.net) | | Marcus Boerger (helly@php.net) | +----------------------------------------------------------------------+ */ #include "php.h" #include "php_globals.h" #include "ext/standard/basic_functions.h" #include "ext/standard/file.h" #include "ext/standard/php_string.h" #include "zend_smart_str.h" /* {{{ rot13 stream filter implementation */ static const char rot13_from[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const 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 ) { php_stream_bucket *bucket; size_t consumed = 0; while (buckets_in->head) { bucket = php_stream_bucket_make_writeable(buckets_in->head); php_strtr(bucket->buf, bucket->buflen, rot13_from, rot13_to, 52); consumed += bucket->buflen; php_stream_bucket_append(buckets_out, bucket); } if (bytes_consumed) { *bytes_consumed = consumed; } return PSFS_PASS_ON; } static const php_stream_filter_ops strfilter_rot13_ops = { strfilter_rot13_filter, NULL, "string.rot13" }; static php_stream_filter *strfilter_rot13_create(const char *filtername, zval *filterparams, uint8_t persistent) { return php_stream_filter_alloc(&strfilter_rot13_ops, NULL, persistent); } static const php_stream_filter_factory strfilter_rot13_factory = { strfilter_rot13_create }; /* }}} */ /* {{{ string.toupper / string.tolower stream filter implementation */ static const char lowercase[] = "abcdefghijklmnopqrstuvwxyz"; static const 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 ) { php_stream_bucket *bucket; size_t consumed = 0; while (buckets_in->head) { bucket = php_stream_bucket_make_writeable(buckets_in->head); php_strtr(bucket->buf, bucket->buflen, lowercase, uppercase, 26); consumed += bucket->buflen; php_stream_bucket_append(buckets_out, bucket); } 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 ) { php_stream_bucket *bucket; size_t consumed = 0; while (buckets_in->head) { bucket = php_stream_bucket_make_writeable(buckets_in->head); php_strtr(bucket->buf, bucket->buflen, uppercase, lowercase, 26); consumed += bucket->buflen; php_stream_bucket_append(buckets_out, bucket); } if (bytes_consumed) { *bytes_consumed = consumed; } return PSFS_PASS_ON; } static const php_stream_filter_ops strfilter_toupper_ops = { strfilter_toupper_filter, NULL, "string.toupper" }; static const php_stream_filter_ops strfilter_tolower_ops = { strfilter_tolower_filter, NULL, "string.tolower" }; static php_stream_filter *strfilter_toupper_create(const char *filtername, zval *filterparams, uint8_t persistent) { return php_stream_filter_alloc(&strfilter_toupper_ops, NULL, persistent); } static php_stream_filter *strfilter_tolower_create(const char *filtername, zval *filterparams, uint8_t persistent) { return php_stream_filter_alloc(&strfilter_tolower_ops, NULL, persistent); } static const php_stream_filter_factory strfilter_toupper_factory = { strfilter_toupper_create }; static const php_stream_filter_factory strfilter_tolower_factory = { strfilter_tolower_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_MORE, PHP_CONV_ERR_ALLOC, 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; const char *lbchars; size_t lbchars_len; size_t erem_len; unsigned int line_ccnt; unsigned int line_len; int lbchars_dup; int persistent; unsigned char erem[3]; } 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 const 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 PHP_CONV_ERR_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; 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; /* 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; static const unsigned int nbitsof_pack = 8; if (in_pp == NULL || in_left_p == NULL) { if (inst->eos || inst->urem_nbits == 0) { return PHP_CONV_ERR_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; const char *lbchars; size_t lbchars_len; int opts; unsigned int line_ccnt; unsigned int line_len; int lbchars_dup; 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; unsigned int trail_ws; int opts; static const 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) { return PHP_CONV_ERR_SUCCESS; } ps = (unsigned char *)(*in_pp); icnt = *in_left_p; pd = (unsigned char *)(*out_pp); ocnt = *out_left_p; trail_ws = 0; 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) && (trail_ws == 0) && (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; } /* Check to see if this is EOL whitespace. */ if (inst->lbchars != NULL) { unsigned char *ps2; unsigned int lb_cnt2; size_t j; lb_cnt2 = 0; ps2 = ps; trail_ws = 1; for (j = icnt - 1; j > 0; j--, ps2++) { if (*ps2 == inst->lbchars[lb_cnt2]) { lb_cnt2++; if (lb_cnt2 >= inst->lbchars_len) { /* Found trailing ws. Reset to top of main * for loop to allow for code to do necessary * wrapping/encoding. */ break; } } else if (lb_cnt2 != 0 || (*ps2 != '\t' && *ps2 != ' ')) { /* At least one non-EOL character following, so * don't need to encode ws. */ trail_ws = 0; break; } else { trail_ws++; } } } if (trail_ws == 0) { *(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 && 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; } 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 && 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; } 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; if (trail_ws > 0) { trail_ws--; } 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; const char *lbchars; size_t lbchars_len; int scan_stat; unsigned int next_char; int lbchars_dup; 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) { 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 (!inst->lbchars && lb_cnt == 0 && *ps == '\r') { /* auto-detect line endings, looks like network line ending \r\n (could be mac \r) */ lb_cnt++; scan_stat = 5; ps++, icnt--; break; } else if (!inst->lbchars && lb_cnt == 0 && *ps == '\n') { /* auto-detect line endings, looks like unix-lineendings, not to spec, but it is seem in the wild, a lot */ lb_cnt = lb_ptr = 0; scan_stat = 0; 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: { if (icnt == 0) { goto out; } if (!isxdigit((int) *ps)) { err = PHP_CONV_ERR_INVALID_SEQ; goto out; } next_char = (next_char << 4) | (*ps >= 'A' ? *ps - 0x37 : *ps - 0x30); 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; } else if (*ps != '\t' && *ps != ' ') { err = PHP_CONV_ERR_INVALID_SEQ; goto out; } ps++, icnt--; } break; case 5: { if (!inst->lbchars && lb_cnt == 1 && *ps == '\n') { /* auto-detect soft line breaks, found network line break */ lb_cnt = lb_ptr = 0; scan_stat = 0; ps++, icnt--; /* consume \n */ } else if (!inst->lbchars && lb_cnt > 0) { /* auto-detect soft line breaks, found mac line break */ lb_cnt = lb_ptr = 0; scan_stat = 0; } else 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; char stub[128]; size_t stub_len; } 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 ((tmpval = zend_hash_str_find((HashTable *)ht, field_name, field_name_len-1)) != NULL) { zend_string *tmp; zend_string *str = zval_get_tmp_string(tmpval, &tmp); *pretval = pemalloc(ZSTR_LEN(str) + 1, persistent); *pretval_len = ZSTR_LEN(str); memcpy(*pretval, ZSTR_VAL(str), ZSTR_LEN(str) + 1); zend_tmp_string_release(tmp); } 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, zend_ulong *pretval, char *field_name, size_t field_name_len) { zval *tmpval = zend_hash_str_find((HashTable *)ht, field_name, field_name_len-1); if (tmpval != NULL) { zend_long lval = zval_get_long(tmpval); if (lval < 0) { *pretval = 0; } else { *pretval = lval; } return PHP_CONV_ERR_SUCCESS; } else { *pretval = 0; return PHP_CONV_ERR_NOT_FOUND; } } 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 = zend_hash_str_find((HashTable *)ht, field_name, field_name_len-1); if (tmpval != NULL) { *pretval = zend_is_true(tmpval); return PHP_CONV_ERR_SUCCESS; } else { *pretval = 0; return PHP_CONV_ERR_NOT_FOUND; } } /* XXX this might need an additional fix so it uses size_t, whereby unsigned is quite big so leaving as is for now */ static int php_conv_get_uint_prop_ex(const HashTable *ht, unsigned int *pretval, char *field_name, size_t field_name_len) { zend_ulong 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 = (unsigned int)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) { /* If line-break-chars are not specified, filter will attempt to detect line endings (\r, \n, or \r\n) */ GET_STR_PROP(options, lbchars, lbchars_len, "line-break-chars", 0); } 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); inst->stub_len = 0; 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); } } /* {{{ strfilter_convert_append_bucket */ static int strfilter_convert_append_bucket( php_convert_filter *inst, php_stream *stream, php_stream_filter *filter, php_stream_bucket_brigade *buckets_out, const char *ps, size_t buf_len, size_t *consumed, int persistent) { php_conv_err_t err; php_stream_bucket *new_bucket; char *out_buf = NULL; size_t out_buf_size; char *pd; const char *pt; size_t ocnt, icnt, tcnt; size_t initial_out_buf_size; if (ps == NULL) { initial_out_buf_size = 64; icnt = 1; } else { initial_out_buf_size = buf_len; icnt = buf_len; } out_buf_size = ocnt = initial_out_buf_size; out_buf = pemalloc(out_buf_size, persistent); pd = out_buf; if (inst->stub_len > 0) { pt = inst->stub; tcnt = inst->stub_len; while (tcnt > 0) { err = php_conv_convert(inst->cd, &pt, &tcnt, &pd, &ocnt); switch (err) { case PHP_CONV_ERR_INVALID_SEQ: php_error_docref(NULL, E_WARNING, "Stream filter (%s): invalid byte sequence", inst->filtername); goto out_failure; case PHP_CONV_ERR_MORE: if (ps != NULL) { if (icnt > 0) { if (inst->stub_len >= sizeof(inst->stub)) { php_error_docref(NULL, E_WARNING, "Stream filter (%s): insufficient buffer", inst->filtername); goto out_failure; } inst->stub[inst->stub_len++] = *(ps++); icnt--; pt = inst->stub; tcnt = inst->stub_len; } else { tcnt = 0; break; } } break; case PHP_CONV_ERR_UNEXPECTED_EOS: php_error_docref(NULL, E_WARNING, "Stream filter (%s): unexpected end of stream", inst->filtername); goto out_failure; case 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... */ if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent))) { goto out_failure; } php_stream_bucket_append(buckets_out, new_bucket); out_buf_size = ocnt = initial_out_buf_size; out_buf = pemalloc(out_buf_size, persistent); pd = out_buf; } else { new_out_buf = perealloc(out_buf, new_out_buf_size, 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; } } break; case PHP_CONV_ERR_UNKNOWN: php_error_docref(NULL, E_WARNING, "Stream filter (%s): unknown error", inst->filtername); goto out_failure; default: break; } } memmove(inst->stub, pt, tcnt); inst->stub_len = tcnt; } while (icnt > 0) { err = ((ps == NULL ? php_conv_convert(inst->cd, NULL, NULL, &pd, &ocnt): php_conv_convert(inst->cd, &ps, &icnt, &pd, &ocnt))); switch (err) { case PHP_CONV_ERR_INVALID_SEQ: php_error_docref(NULL, E_WARNING, "Stream filter (%s): invalid byte sequence", inst->filtername); goto out_failure; case PHP_CONV_ERR_MORE: if (ps != NULL) { if (icnt > sizeof(inst->stub)) { php_error_docref(NULL, E_WARNING, "Stream filter (%s): insufficient buffer", inst->filtername); goto out_failure; } memcpy(inst->stub, ps, icnt); inst->stub_len = icnt; ps += icnt; icnt = 0; } else { php_error_docref(NULL, E_WARNING, "Stream filter (%s): unexpected octet values", inst->filtername); goto out_failure; } break; case 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... */ if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent))) { goto out_failure; } php_stream_bucket_append(buckets_out, new_bucket); out_buf_size = ocnt = initial_out_buf_size; out_buf = pemalloc(out_buf_size, persistent); pd = out_buf; } else { new_out_buf = perealloc(out_buf, new_out_buf_size, 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; } } break; case PHP_CONV_ERR_UNKNOWN: php_error_docref(NULL, E_WARNING, "Stream filter (%s): unknown error", inst->filtername); goto out_failure; default: if (ps == NULL) { icnt = 0; } break; } } if (out_buf_size > ocnt) { if (NULL == (new_bucket = php_stream_bucket_new(stream, out_buf, (out_buf_size - ocnt), 1, persistent))) { goto out_failure; } php_stream_bucket_append(buckets_out, new_bucket); } else { pefree(out_buf, persistent); } *consumed += buf_len - icnt; return SUCCESS; out_failure: pefree(out_buf, persistent); return FAILURE; } /* }}} */ 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 ) { php_stream_bucket *bucket = NULL; size_t consumed = 0; php_convert_filter *inst = (php_convert_filter *)Z_PTR(thisfilter->abstract); while (buckets_in->head != NULL) { bucket = buckets_in->head; php_stream_bucket_unlink(bucket); if (strfilter_convert_append_bucket(inst, stream, thisfilter, buckets_out, bucket->buf, bucket->buflen, &consumed, php_stream_is_persistent(stream)) != SUCCESS) { goto out_failure; } php_stream_bucket_delref(bucket); } if (flags != PSFS_FLAG_NORMAL) { if (strfilter_convert_append_bucket(inst, stream, thisfilter, buckets_out, NULL, 0, &consumed, php_stream_is_persistent(stream)) != SUCCESS) { goto out_failure; } } if (bytes_consumed) { *bytes_consumed = consumed; } return PSFS_PASS_ON; out_failure: if (bucket != NULL) { php_stream_bucket_delref(bucket); } return PSFS_ERR_FATAL; } static void strfilter_convert_dtor(php_stream_filter *thisfilter) { assert(Z_PTR(thisfilter->abstract) != NULL); php_convert_filter_dtor((php_convert_filter *)Z_PTR(thisfilter->abstract)); pefree(Z_PTR(thisfilter->abstract), ((php_convert_filter *)Z_PTR(thisfilter->abstract))->persistent); } static const php_stream_filter_ops strfilter_convert_ops = { strfilter_convert_filter, strfilter_convert_dtor, "convert.*" }; static php_stream_filter *strfilter_convert_create(const char *filtername, zval *filterparams, uint8_t persistent) { php_convert_filter *inst; php_stream_filter *retval = NULL; char *dot; int conv_mode = 0; if (filterparams != NULL && Z_TYPE_P(filterparams) != IS_ARRAY) { php_error_docref(NULL, E_WARNING, "Stream filter (%s): invalid filter parameter", filtername); return NULL; } if ((dot = strchr(filtername, '.')) == NULL) { return NULL; } ++dot; inst = pemalloc(sizeof(php_convert_filter), persistent); 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, (filterparams != NULL ? Z_ARRVAL_P(filterparams) : NULL), filtername, persistent) != SUCCESS) { goto out; } retval = php_stream_filter_alloc(&strfilter_convert_ops, inst, persistent); out: if (retval == NULL) { pefree(inst, persistent); } return retval; } static const php_stream_filter_factory strfilter_convert_factory = { strfilter_convert_create }; /* }}} */ /* {{{ consumed filter implementation */ typedef struct _php_consumed_filter_data { size_t consumed; zend_off_t offset; uint8_t persistent; } php_consumed_filter_data; static php_stream_filter_status_t consumed_filter_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 ) { php_consumed_filter_data *data = (php_consumed_filter_data *)Z_PTR(thisfilter->abstract); php_stream_bucket *bucket; size_t consumed = 0; if (data->offset == ~0) { data->offset = php_stream_tell(stream); } while ((bucket = buckets_in->head) != NULL) { php_stream_bucket_unlink(bucket); consumed += bucket->buflen; php_stream_bucket_append(buckets_out, bucket); } if (bytes_consumed) { *bytes_consumed = consumed; } if (flags & PSFS_FLAG_FLUSH_CLOSE) { php_stream_seek(stream, data->offset + data->consumed, SEEK_SET); } data->consumed += consumed; return PSFS_PASS_ON; } static void consumed_filter_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { php_consumed_filter_data *data = (php_consumed_filter_data*)Z_PTR(thisfilter->abstract); pefree(data, data->persistent); } } static const php_stream_filter_ops consumed_filter_ops = { consumed_filter_filter, consumed_filter_dtor, "consumed" }; static php_stream_filter *consumed_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { const php_stream_filter_ops *fops = NULL; php_consumed_filter_data *data; if (strcasecmp(filtername, "consumed")) { return NULL; } /* Create this filter */ data = pecalloc(1, sizeof(php_consumed_filter_data), persistent); data->persistent = persistent; data->consumed = 0; data->offset = ~0; fops = &consumed_filter_ops; return php_stream_filter_alloc(fops, data, persistent); } static const php_stream_filter_factory consumed_filter_factory = { consumed_filter_create }; /* }}} */ /* {{{ chunked filter implementation */ typedef enum _php_chunked_filter_state { CHUNK_SIZE_START, CHUNK_SIZE, CHUNK_SIZE_EXT, CHUNK_SIZE_CR, CHUNK_SIZE_LF, CHUNK_BODY, CHUNK_BODY_CR, CHUNK_BODY_LF, CHUNK_TRAILER, CHUNK_ERROR } php_chunked_filter_state; typedef struct _php_chunked_filter_data { size_t chunk_size; php_chunked_filter_state state; int persistent; } php_chunked_filter_data; static size_t php_dechunk(char *buf, size_t len, php_chunked_filter_data *data) { char *p = buf; char *end = p + len; char *out = buf; size_t out_len = 0; while (p < end) { switch (data->state) { case CHUNK_SIZE_START: data->chunk_size = 0; case CHUNK_SIZE: while (p < end) { if (*p >= '0' && *p <= '9') { data->chunk_size = (data->chunk_size * 16) + (*p - '0'); } else if (*p >= 'A' && *p <= 'F') { data->chunk_size = (data->chunk_size * 16) + (*p - 'A' + 10); } else if (*p >= 'a' && *p <= 'f') { data->chunk_size = (data->chunk_size * 16) + (*p - 'a' + 10); } else if (data->state == CHUNK_SIZE_START) { data->state = CHUNK_ERROR; break; } else { data->state = CHUNK_SIZE_EXT; break; } data->state = CHUNK_SIZE; p++; } if (data->state == CHUNK_ERROR) { continue; } else if (p == end) { return out_len; } case CHUNK_SIZE_EXT: /* skip extension */ while (p < end && *p != '\r' && *p != '\n') { p++; } if (p == end) { return out_len; } case CHUNK_SIZE_CR: if (*p == '\r') { p++; if (p == end) { data->state = CHUNK_SIZE_LF; return out_len; } } case CHUNK_SIZE_LF: if (*p == '\n') { p++; if (data->chunk_size == 0) { /* last chunk */ data->state = CHUNK_TRAILER; continue; } else if (p == end) { data->state = CHUNK_BODY; return out_len; } } else { data->state = CHUNK_ERROR; continue; } case CHUNK_BODY: if ((size_t) (end - p) >= data->chunk_size) { if (p != out) { memmove(out, p, data->chunk_size); } out += data->chunk_size; out_len += data->chunk_size; p += data->chunk_size; if (p == end) { data->state = CHUNK_BODY_CR; return out_len; } } else { if (p != out) { memmove(out, p, end - p); } data->chunk_size -= end - p; data->state=CHUNK_BODY; out_len += end - p; return out_len; } case CHUNK_BODY_CR: if (*p == '\r') { p++; if (p == end) { data->state = CHUNK_BODY_LF; return out_len; } } case CHUNK_BODY_LF: if (*p == '\n') { p++; data->state = CHUNK_SIZE_START; continue; } else { data->state = CHUNK_ERROR; continue; } case CHUNK_TRAILER: /* ignore trailer */ p = end; continue; case CHUNK_ERROR: if (p != out) { memmove(out, p, end - p); } out_len += end - p; return out_len; } } return out_len; } static php_stream_filter_status_t php_chunked_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 ) { php_stream_bucket *bucket; size_t consumed = 0; php_chunked_filter_data *data = (php_chunked_filter_data *) Z_PTR(thisfilter->abstract); while (buckets_in->head) { bucket = php_stream_bucket_make_writeable(buckets_in->head); consumed += bucket->buflen; bucket->buflen = php_dechunk(bucket->buf, bucket->buflen, data); php_stream_bucket_append(buckets_out, bucket); } if (bytes_consumed) { *bytes_consumed = consumed; } return PSFS_PASS_ON; } static void php_chunked_dtor(php_stream_filter *thisfilter) { if (thisfilter && Z_PTR(thisfilter->abstract)) { php_chunked_filter_data *data = (php_chunked_filter_data *) Z_PTR(thisfilter->abstract); pefree(data, data->persistent); } } static const php_stream_filter_ops chunked_filter_ops = { php_chunked_filter, php_chunked_dtor, "dechunk" }; static php_stream_filter *chunked_filter_create(const char *filtername, zval *filterparams, uint8_t persistent) { const php_stream_filter_ops *fops = NULL; php_chunked_filter_data *data; if (strcasecmp(filtername, "dechunk")) { return NULL; } /* Create this filter */ data = (php_chunked_filter_data *)pecalloc(1, sizeof(php_chunked_filter_data), persistent); data->state = CHUNK_SIZE_START; data->chunk_size = 0; data->persistent = persistent; fops = &chunked_filter_ops; return php_stream_filter_alloc(fops, data, persistent); } static const php_stream_filter_factory chunked_filter_factory = { chunked_filter_create }; /* }}} */ static const struct { const php_stream_filter_ops *ops; const 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_convert_ops, &strfilter_convert_factory }, { &consumed_filter_ops, &consumed_filter_factory }, { &chunked_filter_ops, &chunked_filter_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 )) { 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); } return SUCCESS; } /* }}} */
Close