Commit 439ca948 authored by Tom Anderson's avatar Tom Anderson Committed by Commit Bot

Linux native notifications: Only escape <, >, and & characters for HTML

Canonical's notification development guidelines [1] specifies that
only '<', '>', and '&' characters should be escaped when the
notification server supports the 'body-markup' capability.

Previously, we were escaping single and double quote characters as
well.  On Cinnamon, this would cause the ' character to render as
&#39;.  This CL only escapes the recommended chracters.

[1] https://wiki.ubuntu.com/NotificationDevelopmentGuidelines#If_a_notification_uses_a_.2BIBw.3C.2BIB0_or_.2BIBw.26.2BIB0_character.2C_and_it_has_missing_or_wrong_text

BUG=676220
TBR=peter@chromium.org
CC=​thestig@chromium.org

Change-Id: I3e6f6ea60be52a9e4f406c728701f9f666362bc6
Reviewed-on: https://chromium-review.googlesource.com/688294Reviewed-by: default avatarThomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505133}
parent 81ac8f61
...@@ -111,6 +111,15 @@ gfx::Image DeepCopyImage(const gfx::Image& image) { ...@@ -111,6 +111,15 @@ gfx::Image DeepCopyImage(const gfx::Image& image) {
return gfx::Image(*image_skia); return gfx::Image(*image_skia);
} }
void EscapeUnsafeCharacters(std::string* message) {
// Canonical's notification development guidelines recommends only
// escaping the '&', '<', and '>' characters:
// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines
base::ReplaceChars(*message, "&", "&amp;", message);
base::ReplaceChars(*message, "<", "&lt;", message);
base::ReplaceChars(*message, ">", "&gt;", message);
}
int NotificationPriorityToFdoUrgency(int priority) { int NotificationPriorityToFdoUrgency(int priority) {
enum FdoUrgency { enum FdoUrgency {
LOW = 0, LOW = 0,
...@@ -512,10 +521,11 @@ class NotificationPlatformBridgeLinuxImpl ...@@ -512,10 +521,11 @@ class NotificationPlatformBridgeLinuxImpl
base::ContainsKey(capabilities_, kCapabilityBodyMarkup); base::ContainsKey(capabilities_, kCapabilityBodyMarkup);
if (notification->UseOriginAsContextMessage()) { if (notification->UseOriginAsContextMessage()) {
std::string url_display_text = net::EscapeForHTML( std::string url_display_text =
base::UTF16ToUTF8(url_formatter::FormatUrlForSecurityDisplay( base::UTF16ToUTF8(url_formatter::FormatUrlForSecurityDisplay(
notification->origin_url(), notification->origin_url(),
url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS))); url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS));
EscapeUnsafeCharacters(&url_display_text);
if (base::ContainsKey(capabilities_, kCapabilityBodyHyperlinks)) { if (base::ContainsKey(capabilities_, kCapabilityBodyHyperlinks)) {
body << "<a href=\"" body << "<a href=\""
<< net::EscapePath(notification->origin_url().spec()) << "\">" << net::EscapePath(notification->origin_url().spec()) << "\">"
...@@ -527,13 +537,13 @@ class NotificationPlatformBridgeLinuxImpl ...@@ -527,13 +537,13 @@ class NotificationPlatformBridgeLinuxImpl
std::string context = std::string context =
base::UTF16ToUTF8(notification->context_message()); base::UTF16ToUTF8(notification->context_message());
if (body_markup) if (body_markup)
context = net::EscapeForHTML(context); EscapeUnsafeCharacters(&context);
body << context; body << context;
} }
std::string message = base::UTF16ToUTF8(notification->message()); std::string message = base::UTF16ToUTF8(notification->message());
if (body_markup) if (body_markup)
message = net::EscapeForHTML(message); EscapeUnsafeCharacters(&message);
if (body.tellp()) if (body.tellp())
body << "\n"; body << "\n";
body << message; body << message;
......
...@@ -446,3 +446,23 @@ TEST_F(NotificationPlatformBridgeLinuxTest, MissingBodyCapability) { ...@@ -446,3 +446,23 @@ TEST_F(NotificationPlatformBridgeLinuxTest, MissingBodyCapability) {
CreateNotificationBridgeLinux(std::vector<std::string>{"actions"}, false, CreateNotificationBridgeLinux(std::vector<std::string>{"actions"}, false,
true, false); true, false);
} }
TEST_F(NotificationPlatformBridgeLinuxTest, EscapeHtml) {
EXPECT_CALL(*mock_notification_proxy_.get(),
CallMethodAndBlock(Calls("Notify"), _))
.WillOnce(OnNotify(
[](const NotificationRequest& request) {
EXPECT_EQ("&lt;span id='1' class=\"2\"&gt;&amp;#39;&lt;/span&gt;",
request.body);
},
1));
CreateNotificationBridgeLinux();
notification_bridge_linux_->Display(
NotificationCommon::PERSISTENT, "", "", false,
NotificationBuilder("")
.SetMessage(
base::ASCIIToUTF16("<span id='1' class=\"2\">&#39;</span>"))
.GetResult(),
nullptr);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment