Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions program/lib/Roundcube/rcube_vcard.php
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ private static function vcard_decode($vcard)
$value = strtoupper($value);
// add next line(s) to value string if QP line end detected
if ($value == 'QUOTED-PRINTABLE') {
while (preg_match('/=$/', $lines[$i])) {
while (isset($lines[$i]) && preg_match('/=$/', $lines[$i]) && isset($lines[$i + 1])) {
$data .= "\n" . $lines[++$i];
}
}
Expand Down Expand Up @@ -1049,7 +1049,7 @@ private static function detect_encoding($string)
$enc = $matches ? strtoupper($matches[1]) : 'BASE64';
// add next line(s) to value string if QP line end detected
if ($enc == 'QUOTED-PRINTABLE') {
while (preg_match('/=$/', $lines[$i])) {
while (isset($lines[$i]) && preg_match('/=$/', $lines[$i]) && isset($lines[$i + 1])) {
$data .= "\n" . $lines[++$i];
}
}
Expand Down
30 changes: 30 additions & 0 deletions tests/Framework/VCardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,36 @@ public function test_parse_six()
$this->assertCount(1, $result['address:work'], 'ITEM1.-prefixed entry');
}

/**
* A QUOTED-PRINTABLE soft-line-break ('=') on the very last line must not
* cause reading past the end of the internal lines array.
*/
public function test_parse_qp_soft_break_on_last_line()
{
$errors = [];
set_error_handler(static function ($errno, $errstr) use (&$errors) {
$errors[] = $errstr;

return true;
});

try {
// Last line ends with '=' (QP soft line break) with no following line
$vcard_string = "BEGIN:VCARD\r\n"
. "VERSION:3.0\r\n"
. "FN:Test\r\n"
. 'NOTE;ENCODING=QUOTED-PRINTABLE:Hello=';

$vcard = new \rcube_vcard($vcard_string, null, true);
$result = $vcard->get_assoc();
} finally {
restore_error_handler();
}

$this->assertSame([], $errors, 'No PHP warnings/errors while decoding');
$this->assertSame('Hello', $result['notes'][0], 'Best-effort QP decode of the dangling line');
}

/**
* Extra whitespace at start of continuation line (#9593/1).
*/
Expand Down
Loading