From 8a077e0e943d87ee1d26b0501f0b9bcc472ab904 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 17 May 2015 20:15:06 +0200 Subject: [ticket/13847] Move quote generation to text_formatter.utils PHPBB3-13847 --- phpBB/phpbb/textformatter/s9e/utils.php | 37 +++++++++++++++++++ phpBB/phpbb/textformatter/utils_interface.php | 12 +++++++ phpBB/posting.php | 6 +++- tests/functional/posting_test.php | 14 ++++++++ tests/text_formatter/s9e/utils_test.php | 51 +++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index e21dedecc4..fe33c04da3 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -34,6 +34,43 @@ class utils implements \phpbb\textformatter\utils_interface return \s9e\TextFormatter\Utils::removeFormatting($xml); } + /** + * Return given string between quotes + * + * Will use either single- or double- quotes depending on whichever requires to be escaped. + * Quotes and backslashes are escaped with backslashes where necessary + * + * @param string $str Original string + * @return string Escaped string within quotes + */ + protected function enquote($str) + { + $quote = (strpos($str, '"') === false || strpos($str, "'") !== false) ? '"' : "'"; + + return $quote . addcslashes($str, '\\' . $quote) . $quote; + } + + /** + * {@inheritdoc} + */ + public function generate_quote($text, array $attributes = array()) + { + $quote = '[quote'; + if (isset($attributes['author'])) + { + // Add the author as the BBCode's default attribute + $quote .= '=' . $this->enquote($attributes['author']); + unset($attributes['author']); + } + foreach ($attributes as $name => $value) + { + $quote .= ' ' . $name . '=' . $this->enquote($value); + } + $quote .= ']' . $text . '[/quote]'; + + return $quote; + } + /** * Get a list of quote authors, limited to the outermost quotes * diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 6d3fd13021..41a6ba2345 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -28,6 +28,18 @@ interface utils_interface */ public function clean_formatting($text); + /** + * Create a quote block for given text + * + * Possible attributes: + * - author + * + * @param string $text Quote's text + * @param array $attributes Quote's attributes + * @return string Quote block to be used in a new post/text + */ + public function generate_quote($text, array $attributes = array()); + /** * Get a list of quote authors, limited to the outermost quotes * diff --git a/phpBB/posting.php b/phpBB/posting.php index a4fb4d7a8d..4d52da2567 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -1597,7 +1597,11 @@ if ($generate_quote) { if ($config['allow_bbcode']) { - $message_parser->message = '[quote="' . $post_data['quote_username'] . '"]' . censor_text(trim($message_parser->message)) . "[/quote]\n"; + $message_parser->message = $phpbb_container->get('text_formatter.utils')->generate_quote( + censor_text(trim($message_parser->message)), + array('author' => $post_data['quote_username']) + ); + $message_parser->message .= "\n"; } else { diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php index 5c083aef37..8677237772 100644 --- a/tests/functional/posting_test.php +++ b/tests/functional/posting_test.php @@ -72,6 +72,20 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case $this->assertContains('😀', $crawler->text()); } + public function test_quote() + { + $text = 'Test post "\' &&amp;'; + $expected = '[quote="admin"]' . $text . '[/quote]'; + + $this->login(); + $topic = $this->create_topic(2, 'Test Topic 1', 'Test topic'); + $post = $this->create_post(2, $topic['topic_id'], 'Re: Test Topic 1', $text); + + $crawler = self::request('GET', "posting.php?mode=quote&f=2&t={$post['topic_id']}&p={$post['post_id']}&sid={$this->sid}"); + + $this->assertContains($expected, $crawler->filter('textarea#message')->text()); + } + /** * @testdox max_quote_depth is applied to the text populating the posting form */ diff --git a/tests/text_formatter/s9e/utils_test.php b/tests/text_formatter/s9e/utils_test.php index b1b937709c..3c92965b49 100644 --- a/tests/text_formatter/s9e/utils_test.php +++ b/tests/text_formatter/s9e/utils_test.php @@ -108,6 +108,57 @@ class phpbb_textformatter_s9e_utils_test extends phpbb_test_case ); } + /** + * @dataProvider get_generate_quote_tests + */ + public function test_generate_quote($text, $params, $expected) + { + $container = $this->get_test_case_helpers()->set_s9e_services(); + $utils = $container->get('text_formatter.utils'); + + $this->assertSame($expected, $utils->generate_quote($text, $params)); + } + + public function get_generate_quote_tests() + { + return array( + array( + '...', + array(), + '[quote]...[/quote]', + ), + array( + '...', + array('author' => 'Brian Kibler'), + '[quote="Brian Kibler"]...[/quote]', + ), + array( + '...', + array('author' => 'Brian "Brian Kibler" Kibler of Brian Kibler Gaming'), + '[quote=\'Brian "Brian Kibler" Kibler of Brian Kibler Gaming\']...[/quote]', + ), + array( + '...', + array('author' => "Brian Kibler Gaming's Brian Kibler"), + '[quote="Brian Kibler Gaming\'s Brian Kibler"]...[/quote]', + ), + array( + '...', + array('author' => "\\\"'"), + '[quote="\\\\\\"\'"]...[/quote]', + ), + array( + '...', + array( + 'author' => 'user', + 'post_id' => 123, + 'url' => 'http://example.org' + ), + '[quote="user" post_id="123" url="http://example.org"]...[/quote]', + ), + ); + } + /** * @dataProvider get_remove_bbcode_tests */ -- cgit v1.2.1 From e50d9186ce15367e8f6e2aab5c04481ca0046ec6 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Tue, 19 May 2015 23:10:35 +0200 Subject: [ticket/13847] Changed enquote() logic to use whichever is the shortest Will enclose attribute values in single- or double- quotes depending on whichever requires the least escaping. Characters that need to be escaped are always escaped regardless. PHPBB3-13847 --- phpBB/phpbb/textformatter/s9e/utils.php | 7 ++++--- tests/text_formatter/s9e/utils_test.php | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index fe33c04da3..04df589930 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -37,7 +37,7 @@ class utils implements \phpbb\textformatter\utils_interface /** * Return given string between quotes * - * Will use either single- or double- quotes depending on whichever requires to be escaped. + * Will use either single- or double- quotes depending on whichever requires less escaping. * Quotes and backslashes are escaped with backslashes where necessary * * @param string $str Original string @@ -45,9 +45,10 @@ class utils implements \phpbb\textformatter\utils_interface */ protected function enquote($str) { - $quote = (strpos($str, '"') === false || strpos($str, "'") !== false) ? '"' : "'"; + $singleQuoted = "'" . addcslashes($str, "\\'") . "'"; + $doubleQuoted = '"' . addcslashes($str, '\\"') . '"'; - return $quote . addcslashes($str, '\\' . $quote) . $quote; + return (strlen($singleQuoted) < strlen($doubleQuoted)) ? $singleQuoted : $doubleQuoted; } /** diff --git a/tests/text_formatter/s9e/utils_test.php b/tests/text_formatter/s9e/utils_test.php index 3c92965b49..555f29cb38 100644 --- a/tests/text_formatter/s9e/utils_test.php +++ b/tests/text_formatter/s9e/utils_test.php @@ -147,6 +147,21 @@ class phpbb_textformatter_s9e_utils_test extends phpbb_test_case array('author' => "\\\"'"), '[quote="\\\\\\"\'"]...[/quote]', ), + array( + '...', + array('author' => 'Lots of doubles """ one single \' one backslash \\'), + '[quote=\'Lots of doubles """ one single \\\' one backslash \\\\\']...[/quote]', + ), + array( + '...', + array('author' => "Lots of singles ''' one double \" one backslash \\"), + '[quote="Lots of singles \'\'\' one double \\" one backslash \\\\"]...[/quote]', + ), + array( + '...', + array('author' => 'Defaults to doublequotes """\'\'\''), + '[quote="Defaults to doublequotes \\"\\"\\"\'\'\'"]...[/quote]', + ), array( '...', array( -- cgit v1.2.1 From 2a7a06da2a166b814732bdfa790e53b80da8a612 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 25 May 2015 20:54:30 +0200 Subject: [ticket/13847] Updated ucp_pm_compose to use the utils service ...when quoting a post PHPBB3-13847 --- phpBB/includes/ucp/ucp_pm_compose.php | 6 +++++- tests/functional/private_messages_test.php | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index 59952182df..67e53718a0 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -947,7 +947,11 @@ function compose_pm($id, $mode, $action, $user_folders = array()) { $message_link = ''; } - $message_parser->message = $message_link . '[quote="' . $quote_username . '"]' . censor_text(trim($message_parser->message)) . "[/quote]\n"; + $quote_text = $phpbb_container->get('text_formatter.utils')->generate_quote( + censor_text(trim($message_parser->message)), + array('author' => $quote_username) + ); + $message_parser->message = $message_link . $quote_text . "\n"; } if (($action == 'reply' || $action == 'quote' || $action == 'quotepost') && !$preview && !$refresh) diff --git a/tests/functional/private_messages_test.php b/tests/functional/private_messages_test.php index 1f6dc3a979..4851fc4c64 100644 --- a/tests/functional/private_messages_test.php +++ b/tests/functional/private_messages_test.php @@ -66,4 +66,18 @@ class phpbb_functional_private_messages_test extends phpbb_functional_test_case $crawler = self::submit($form); $this->assertContains($this->lang('CONFIG_UPDATED'), $crawler->filter('.successbox')->text()); } + + public function test_quote() + { + $text = 'Test post'; + $expected = '[quote="admin"]' . $text . '[/quote]'; + + $this->login(); + $topic = $this->create_topic(2, 'Test Topic 1', 'Test topic'); + $post = $this->create_post(2, $topic['topic_id'], 'Re: Test Topic 1', $text); + + $crawler = self::request('GET', 'ucp.php?i=pm&mode=compose&action=quotepost&p=' . $post['post_id'] . '&sid=' . $this->sid); + + $this->assertContains($expected, $crawler->filter('textarea#message')->text()); + } } -- cgit v1.2.1 From 64e1824abdb2a9c860e049f10ecc81c051160ff5 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Mon, 25 May 2015 21:04:12 +0200 Subject: [ticket/13847] Updated ucp_pm_compose to use utils when forwarding PHPBB3-13847 --- phpBB/includes/ucp/ucp_pm_compose.php | 6 +++++- tests/functional/private_messages_test.php | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index 67e53718a0..53be1b3b29 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -979,7 +979,11 @@ function compose_pm($id, $mode, $action, $user_folders = array()) $forward_text[] = sprintf($user->lang['FWD_FROM'], $quote_username_text); $forward_text[] = sprintf($user->lang['FWD_TO'], implode($user->lang['COMMA_SEPARATOR'], $fwd_to_field['to'])); - $message_parser->message = implode("\n", $forward_text) . "\n\n[quote="{$quote_username}"]\n" . censor_text(trim($message_parser->message)) . "\n[/quote]"; + $quote_text = $phpbb_container->get('text_formatter.utils')->generate_quote( + censor_text(trim($message_parser->message)), + array('author' => $quote_username) + ); + $message_parser->message = implode("\n", $forward_text) . "\n\n" . $quote_text; $message_subject = ((!preg_match('/^Fwd:/', $message_subject)) ? 'Fwd: ' : '') . censor_text($message_subject); } diff --git a/tests/functional/private_messages_test.php b/tests/functional/private_messages_test.php index 4851fc4c64..3f602d62fb 100644 --- a/tests/functional/private_messages_test.php +++ b/tests/functional/private_messages_test.php @@ -67,7 +67,7 @@ class phpbb_functional_private_messages_test extends phpbb_functional_test_case $this->assertContains($this->lang('CONFIG_UPDATED'), $crawler->filter('.successbox')->text()); } - public function test_quote() + public function test_quote_post() { $text = 'Test post'; $expected = '[quote="admin"]' . $text . '[/quote]'; @@ -80,4 +80,17 @@ class phpbb_functional_private_messages_test extends phpbb_functional_test_case $this->assertContains($expected, $crawler->filter('textarea#message')->text()); } + + public function test_quote_forward() + { + $text = 'This is a test private message sent by the testing framework.'; + $expected = '[quote="admin"]' . $text . '[/quote]'; + + $this->login(); + $message_id = $this->create_private_message('Test', $text, array(2)); + + $crawler = self::request('GET', 'ucp.php?i=pm&mode=compose&action=forward&f=0&p=' . $message_id . '&sid=' . $this->sid); + + $this->assertContains($expected, $crawler->filter('textarea#message')->text()); + } } -- cgit v1.2.1