diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php
index b317fe4a8d..a9a6d4b892 100644
--- a/phpBB/phpbb/textformatter/s9e/utils.php
+++ b/phpBB/phpbb/textformatter/s9e/utils.php
@@ -136,4 +136,17 @@ class utils implements \phpbb\textformatter\utils_interface
 	{
 		return \s9e\TextFormatter\Unparser::unparse($xml);
 	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	public function is_empty($text)
+	{
+		if ($text === null || $text === '')
+		{
+			return true;
+		}
+
+		return trim($this->unparse($text)) === '';
+	}
 }
diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php
index 4810453cd1..4b7392976a 100644
--- a/phpBB/phpbb/textformatter/utils_interface.php
+++ b/phpBB/phpbb/textformatter/utils_interface.php
@@ -62,10 +62,18 @@ interface utils_interface
 	public function remove_bbcode($text, $bbcode_name, $depth = 0);
 
 	/**
-	* Return a parsed text to its original form
-	*
-	* @param  string $text Parsed text
-	* @return string       Original plain text
-	*/
+	 * Return a parsed text to its original form
+	 *
+	 * @param  string $text Parsed text
+	 * @return string       Original plain text
+	 */
 	public function unparse($text);
+
+	/**
+	 * Return whether or not a parsed text represent an empty text.
+	 *
+	 * @param  string $text Parsed text
+	 * @return bool         Tue if the original text is empty
+	 */
+	public function is_empty($text);
 }
diff --git a/phpBB/posting.php b/phpBB/posting.php
index b0aef2482a..aa10059796 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -816,6 +816,7 @@ if ($load && ($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_
 	load_drafts($topic_id, $forum_id);
 }
 
+$bbcode_utils = $phpbb_container->get('text_formatter.utils');
 
 if ($submit || $preview || $refresh)
 {
@@ -1178,7 +1179,7 @@ if ($submit || $preview || $refresh)
 		$post_data['poll_title'] = '';
 		$post_data['poll_start'] = $post_data['poll_length'] = $post_data['poll_max_options'] = $post_data['poll_last_vote'] = $post_data['poll_vote_change'] = 0;
 	}
-	else if (!$auth->acl_get('f_poll', $forum_id) && ($mode == 'edit') && ($post_id == $post_data['topic_first_post_id']) && ($original_poll_data['poll_title'] != ''))
+	else if (!$auth->acl_get('f_poll', $forum_id) && ($mode == 'edit') && ($post_id == $post_data['topic_first_post_id']) && !$bbcode_utils->is_empty($original_poll_data['poll_title']))
 	{
 		// We have a poll but the editing user is not permitted to create/edit it.
 		// So we just keep the original poll-data.
@@ -1601,7 +1602,7 @@ if ($generate_quote)
 
 	if ($config['allow_bbcode'])
 	{
-		$message_parser->message = $phpbb_container->get('text_formatter.utils')->generate_quote(
+		$message_parser->message = $bbcode_utils->generate_quote(
 			censor_text($message_parser->message),
 			array(
 				'author'  => $post_data['quote_username'],
@@ -1639,7 +1640,7 @@ $attachment_data = $message_parser->attachment_data;
 $filename_data = $message_parser->filename_data;
 $post_data['post_text'] = $message_parser->message;
 
-if (sizeof($post_data['poll_options']) || !empty($post_data['poll_title']))
+if (sizeof($post_data['poll_options']) || (isset($post_data['poll_title']) && !$bbcode_utils->is_empty($post_data['poll_title'])))
 {
 	$message_parser->message = $post_data['poll_title'];
 	$message_parser->bbcode_uid = $post_data['bbcode_uid'];
diff --git a/tests/functional/posting_test.php b/tests/functional/posting_test.php
index 9dd8a1dc91..83acefd2f3 100644
--- a/tests/functional/posting_test.php
+++ b/tests/functional/posting_test.php
@@ -86,6 +86,24 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
 		$this->assertRegexp($expected, $crawler->filter('textarea#message')->text());
 	}
 
+	/**
+	 * @see https://tracker.phpbb.com/browse/PHPBB3-14962
+	 */
+	public function test_edit()
+	{
+		$this->login();
+		$this->create_topic(2, 'Test Topic post', 'Test topic post');
+
+		$url =  self::$client->getCrawler()->selectLink('Edit')->link()->getUri();
+		$post_id = $this->get_parameter_from_link($url, 'p');
+		$crawler = self::request('GET', "posting.php?mode=edit&f=2&p={$post_id}&sid={$this->sid}");
+		$form = $crawler->selectButton('Submit')->form();
+		$form->setValues(array('message' => 'Edited post'));
+		$crawler = self::submit($form);
+
+		$this->assertContains('Edited post', $crawler->filter("#post_content{$post_id} .content")->text());
+	}
+
 	/**
 	* @testdox max_quote_depth is applied to the text populating the posting form
 	*/