From 94f8ce3334b64fd3d414540d650c753d2e8a159a Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 12 Aug 2016 10:37:40 +0200 Subject: [PATCH] Make html::parse_attrib_string() more robust Fixes PHP Error: Expression parse error on: ($app->config->get('preview_pane',rcube_utils::get_boolean('')) == true ? ' checked=checked' : ') --- program/lib/Roundcube/html.php | 12 ++++----- tests/Framework/Html.php | 46 +++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/program/lib/Roundcube/html.php b/program/lib/Roundcube/html.php index 8c2534a58..07b72009d 100644 --- a/program/lib/Roundcube/html.php +++ b/program/lib/Roundcube/html.php @@ -344,14 +344,14 @@ class html public static function parse_attrib_string($str) { $attrib = array(); - $regexp = '/\s*([-_a-z]+)=(["\'])??(?(2)([^\2]*)\2|(\S+?))/Ui'; + $html = '
'; - preg_match_all($regexp, stripslashes($str), $regs, PREG_SET_ORDER); + $document = new DOMDocument('1.0', RCUBE_CHARSET); + @$document->loadHTML($html); - // convert attributes to an associative array (name => value) - if ($regs) { - foreach ($regs as $attr) { - $attrib[strtolower($attr[1])] = html_entity_decode($attr[3] . $attr[4]); + if ($node = $document->getElementsByTagName('div')->item(0)) { + foreach ($node->attributes as $name => $attr) { + $attrib[strtolower($name)] = $attr->nodeValue; } } diff --git a/tests/Framework/Html.php b/tests/Framework/Html.php index 259d73e1a..edc3466b0 100644 --- a/tests/Framework/Html.php +++ b/tests/Framework/Html.php @@ -61,9 +61,9 @@ class Framework_Html extends PHPUnit_Framework_TestCase * Test for attrib_string() * @dataProvider data_attrib_string */ - function test_attrib_string($arg1, $arg2, $result) + function test_attrib_string($arg1, $arg2, $expected) { - $this->assertEquals(html::attrib_string($arg1, $arg2), $result); + $this->assertEquals($expected, html::attrib_string($arg1, $arg2)); } /** @@ -86,8 +86,46 @@ class Framework_Html extends PHPUnit_Framework_TestCase * Test for quote() * @dataProvider data_quote */ - function test_quote($str, $result) + function test_quote($str, $expected) { - $this->assertEquals(html::quote($str), $result); + $this->assertEquals($expected, html::quote($str)); + } + + /** + * Data for test_parse_attrib_string() + */ + function data_parse_attrib_string() + { + return array( + array( + '', + array(), + ), + array( + 'test="test1-val"', + array('test' => 'test1-val'), + ), + array( + 'test1="test1-val" test2=test2-val', + array('test1' => 'test1-val', 'test2' => 'test2-val'), + ), + array( + ' test1="test1\'val" test2=\'test2"val\' ', + array('test1' => 'test1\'val', 'test2' => 'test2"val'), + ), + array( + 'expression="test == true ? \' test\' : \'\'" ', + array('expression' => 'test == true ? \' test\' : \'\''), + ), + ); + } + + /** + * Test for parse_attrib_string() + * @dataProvider data_parse_attrib_string + */ + function test_parse_attrib_string($arg1, $expected) + { + $this->assertEquals($expected, html::parse_attrib_string($arg1)); } }