View difference between Paste ID: fb084a7b and
SHOW:
|
|
- or go back to the newest paste.
1 | --- php5.2-200809191430\ext\bz2\bz2_filter.c 2008-01-13 00:35:00.000000000 +0100 | |
2 | +++ php5.2-200809181030\ext\bz2\bz2_filter.c 2008-09-19 18:41:52.000000000 +0200 | |
3 | @@ -27,6 +27,13 @@ | |
4 | ||
5 | /* {{{ data structure */ | |
6 | ||
7 | +enum strm_status { | |
8 | + Uninitialised, | |
9 | + Running, | |
10 | + Finished | |
11 | +}; | |
12 | + | |
13 | + | |
14 | typedef struct _php_bz2_filter_data { | |
15 | int persistent; | |
16 | bz_stream strm; | |
17 | @@ -34,6 +41,11 @@ | |
18 | size_t inbuf_len; | |
19 | char *outbuf; | |
20 | size_t outbuf_len; | |
21 | + | |
22 | + /* Decompress options */ | |
23 | + enum strm_status status; | |
24 | + unsigned int small_footprint : 1; | |
25 | + int expect_concatenated : 1; | |
26 | } php_bz2_filter_data; | |
27 | ||
28 | /* }}} */ | |
29 | @@ -65,7 +77,7 @@ | |
30 | php_bz2_filter_data *data; | |
31 | php_stream_bucket *bucket; | |
32 | size_t consumed = 0; | |
33 | - int status; | |
34 | + int bzlib_status; | |
35 | php_stream_filter_status_t exit_status = PSFS_FEED_ME; | |
36 | bz_stream *streamp; | |
37 | ||
38 | @@ -82,6 +94,16 @@ | |
39 | ||
40 | bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC); | |
41 | while (bin < bucket->buflen) { | |
42 | + if (data->status == Uninitialised) { | |
43 | + bzlib_status = BZ2_bzDecompressInit(streamp, 0, data->small_footprint); | |
44 | + | |
45 | + if (BZ_OK != bzlib_status) | |
46 | + return PSFS_ERR_FATAL; | |
47 | + | |
48 | + data->status = Running; | |
49 | + } | |
50 | + | |
51 | + if (data->status == Running) { | |
52 | desired = bucket->buflen - bin; | |
53 | if (desired > data->inbuf_len) { | |
54 | desired = data->inbuf_len; | |
55 | @@ -89,9 +111,19 @@ | |
56 | memcpy(data->strm.next_in, bucket->buf + bin, desired); | |
57 | data->strm.avail_in = desired; | |
58 | ||
59 | - status = BZ2_bzDecompress(&(data->strm)); | |
60 | - if (status != BZ_OK && status != BZ_STREAM_END) { | |
61 | + bzlib_status = BZ2_bzDecompress(&(data->strm)); | |
62 | + | |
63 | + if (bzlib_status == BZ_STREAM_END) { | |
64 | + BZ2_bzDecompressEnd(&(data->strm)); | |
65 | + if (data->expect_concatenated) | |
66 | + data->status = Uninitialised; | |
67 | + else | |
68 | + data->status = Finished; | |
69 | + } else | |
70 | + if (bzlib_status != BZ_OK) { | |
71 | /* Something bad happened */ | |
72 | + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bzip decompress error %d.", bzlib_status); | |
73 | + | |
74 | php_stream_bucket_delref(bucket TSRMLS_CC); | |
75 | return PSFS_ERR_FATAL; | |
76 | } | |
77 | @@ -109,20 +141,25 @@ | |
78 | data->strm.avail_out = data->outbuf_len; | |
79 | data->strm.next_out = data->outbuf; | |
80 | exit_status = PSFS_PASS_ON; | |
81 | - } else if (status == BZ_STREAM_END && data->strm.avail_out >= data->outbuf_len) { | |
82 | + } else if (bzlib_status == BZ_STREAM_END && data->strm.avail_out >= data->outbuf_len) { | |
83 | /* no more data to decompress, and nothing was spat out */ | |
84 | php_stream_bucket_delref(bucket TSRMLS_CC); | |
85 | return PSFS_PASS_ON; | |
86 | } | |
87 | + } else { | |
88 | + consumed += bucket->buflen; | |
89 | + break; | |
90 | } | |
91 | + } | |
92 | + | |
93 | php_stream_bucket_delref(bucket TSRMLS_CC); | |
94 | } | |
95 | ||
96 | - if (flags & PSFS_FLAG_FLUSH_CLOSE) { | |
97 | + if ((data->status == Running) && (flags & PSFS_FLAG_FLUSH_CLOSE)) { | |
98 | /* Spit it out! */ | |
99 | - status = BZ_OK; | |
100 | - while (status == BZ_OK) { | |
101 | - status = BZ2_bzDecompress(&(data->strm)); | |
102 | + bzlib_status = BZ_OK; | |
103 | + while (bzlib_status == BZ_OK) { | |
104 | + bzlib_status = BZ2_bzDecompress(&(data->strm)); | |
105 | if (data->strm.avail_out < data->outbuf_len) { | |
106 | size_t bucketlen = data->outbuf_len - data->strm.avail_out; | |
107 | ||
108 | @@ -131,7 +168,7 @@ | |
109 | data->strm.avail_out = data->outbuf_len; | |
110 | data->strm.next_out = data->outbuf; | |
111 | exit_status = PSFS_PASS_ON; | |
112 | - } else if (status == BZ_OK) { | |
113 | + } else if (bzlib_status == BZ_OK) { | |
114 | break; | |
115 | } | |
116 | } | |
117 | @@ -148,7 +185,7 @@ | |
118 | { | |
119 | if (thisfilter && thisfilter->abstract) { | |
120 | php_bz2_filter_data *data = thisfilter->abstract; | |
121 | - BZ2_bzDecompressEnd(&(data->strm)); | |
122 | + if (data->status == Running) BZ2_bzDecompressEnd(&(data->strm)); | |
123 | pefree(data->inbuf, data->persistent); | |
124 | pefree(data->outbuf, data->persistent); | |
125 | pefree(data, data->persistent); | |
126 | @@ -275,7 +312,7 @@ | |
127 | { | |
128 | php_stream_filter_ops *fops = NULL; | |
129 | php_bz2_filter_data *data; | |
130 | - int status; | |
131 | + int status = BZ_OK; | |
132 | ||
133 | /* Create this filter */ | |
134 | data = pecalloc(1, sizeof(php_bz2_filter_data), persistent); | |
135 | @@ -307,12 +344,22 @@ | |
136 | } | |
137 | ||
138 | if (strcasecmp(filtername, "bzip2.decompress") == 0) { | |
139 | - int smallFootprint = 0; | |
140 | + data->small_footprint = 0; | |
141 | + data->expect_concatenated = 0; | |
142 | ||
143 | if (filterparams) { | |
144 | zval **tmpzval = NULL; | |
145 | ||
146 | if (Z_TYPE_P(filterparams) == IS_ARRAY || Z_TYPE_P(filterparams) == IS_OBJECT) { | |
147 | + | |
148 | + if (SUCCESS == zend_hash_find(HASH_OF(filterparams), "concatenated", sizeof("concatenated"), (void **) &tmpzval) ) { | |
149 | + SEPARATE_ZVAL(tmpzval); | |
150 | + convert_to_boolean_ex(tmpzval); | |
151 | + data->expect_concatenated = Z_LVAL_PP(tmpzval); | |
152 | + zval_ptr_dtor(tmpzval); | |
153 | + tmpzval = NULL; | |
154 | + } | |
155 | + | |
156 | zend_hash_find(HASH_OF(filterparams), "small", sizeof("small"), (void **) &tmpzval); | |
157 | } else { | |
158 | tmpzval = &filterparams; | |
159 | @@ -321,12 +368,12 @@ | |
160 | if (tmpzval) { | |
161 | SEPARATE_ZVAL(tmpzval); | |
162 | convert_to_boolean_ex(tmpzval); | |
163 | - smallFootprint = Z_LVAL_PP(tmpzval); | |
164 | + data->small_footprint = Z_LVAL_PP(tmpzval); | |
165 | zval_ptr_dtor(tmpzval); | |
166 | } | |
167 | } | |
168 | ||
169 | - status = BZ2_bzDecompressInit(&(data->strm), 0, smallFootprint); | |
170 | + data->status = Uninitialised; | |
171 | fops = &php_bz2_decompress_ops; | |
172 | } else if (strcasecmp(filtername, "bzip2.compress") == 0) { | |
173 | int blockSize100k = PHP_BZ2_FILTER_DEFAULT_BLOCKSIZE; | |
174 |