Skip to content

Commit

Permalink
Fix #64166: quoted-printable-encode stream filter incorrectly discard…
Browse files Browse the repository at this point in the history
…ing whitespace

If trailing whitespace on a line is detected, mark the linebreak as a
soft linebreak.
  • Loading branch information
slusarz authored and smalyshev committed Jun 16, 2013
1 parent 2208447 commit 600d6de
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
12 changes: 12 additions & 0 deletions ext/standard/filters.c
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
unsigned int line_ccnt;
unsigned int lb_ptr;
unsigned int lb_cnt;
unsigned int prev_ws;
int opts;
static char qp_digits[] = "0123456789ABCDEF";

Expand All @@ -807,6 +808,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
icnt = *in_left_p;
pd = (unsigned char *)(*out_pp);
ocnt = *out_left_p;
prev_ws = 0;

for (;;) {
if (!(opts & PHP_CONV_QPRINT_OPT_BINARY) && inst->lbchars != NULL && inst->lbchars_len > 0) {
Expand All @@ -825,6 +827,14 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
break;
}

/* If the character(s) immediately before the line break
* is whitespace, need to convert to soft linebreak to
* preserve that data. */
if (prev_ws > 0) {
*(pd++) = '=';
ocnt--;
}

for (i = 0; i < lb_cnt; i++) {
*(pd++) = inst->lbchars[i];
ocnt--;
Expand All @@ -842,6 +852,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
}

c = NEXT_CHAR(ps, icnt, lb_ptr, lb_cnt, inst->lbchars);
prev_ws = 0;

if (!(opts & PHP_CONV_QPRINT_OPT_BINARY) && (c == '\t' || c == ' ')) {
if (line_ccnt < 2 && inst->lbchars != NULL) {
Expand All @@ -866,6 +877,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
*(pd++) = c;
ocnt--;
line_ccnt--;
prev_ws = 1;
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))) {
Expand Down
32 changes: 32 additions & 0 deletions ext/standard/tests/streams/bug64166.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
Bug #64166: quoted-printable-encode stream filter incorrectly discarding whitespace
--FILE--
<?php
$data = "FIRST \nSECOND";

$fd = fopen('php://temp', 'w+');
fwrite($fd, $data);
rewind($fd);

$res = stream_filter_append($fd, 'convert.quoted-printable-encode', STREAM_FILTER_READ, array(
'line-break-chars' => "\n",
'line-length' => 7
));
var_dump(stream_get_contents($fd, -1, 0));

stream_filter_remove($res);

rewind($fd);
stream_filter_append($fd, 'convert.quoted-printable-encode', STREAM_FILTER_READ, array(
'line-break-chars' => "\n",
'line-length' => 6
));
var_dump(stream_get_contents($fd, -1, 0));
?>
--EXPECT--
string(14) "FIRST =
SECOND"
string(18) "FIRST=
=
SECON=
D"

0 comments on commit 600d6de

Please sign in to comment.