mirror of
https://github.com/php/php-src.git
synced 2026-04-06 07:32:54 +02:00
MFH: convert.* filters not consuming buckets_in on PSFS_FLUSH_*
This commit is contained in:
@@ -1484,6 +1484,85 @@ static php_stream_filter_status_t strfilter_convert_filter(
|
||||
char *pd;
|
||||
size_t ocnt;
|
||||
|
||||
/* Always wind buckets_in whether this is a flush op or not */
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
} else {
|
||||
pefree(out_buf, inst->persistent);
|
||||
}
|
||||
|
||||
php_stream_bucket_delref(bucket TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (flags != PSFS_FLAG_NORMAL) {
|
||||
/* flush operation */
|
||||
|
||||
@@ -1549,86 +1628,9 @@ static php_stream_filter_status_t strfilter_convert_filter(
|
||||
} else {
|
||||
pefree(out_buf, inst->persistent);
|
||||
}
|
||||
} 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
} else {
|
||||
pefree(out_buf, inst->persistent);
|
||||
}
|
||||
|
||||
php_stream_bucket_delref(bucket TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (bytes_consumed) {
|
||||
*bytes_consumed = consumed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user