Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/android/vr_shell/textures/url_bar_texture.h" | 5 #include "chrome/browser/android/vr_shell/textures/url_bar_texture.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 ~TestUrlBarTexture() override {} | 43 ~TestUrlBarTexture() override {} |
| 44 | 44 |
| 45 void DrawURL(const GURL& gurl) { | 45 void DrawURL(const GURL& gurl) { |
| 46 unsupported_mode_ = UiUnsupportedMode::kCount; | 46 unsupported_mode_ = UiUnsupportedMode::kCount; |
| 47 SetURL(gurl); | 47 SetURL(gurl); |
| 48 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul( | 48 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul( |
| 49 texture_size_.width(), texture_size_.height()); | 49 texture_size_.width(), texture_size_.height()); |
| 50 DrawAndLayout(surface->getCanvas(), texture_size_); | 50 DrawAndLayout(surface->getCanvas(), texture_size_); |
| 51 } | 51 } |
| 52 | 52 |
| 53 static void TestUrlStyling(const base::string16& formatted_url, | |
|
cjgrant
2017/06/23 16:02:52
This is unrelated to RTL; just cleanup to the publ
| |
| 54 const url::Parsed& parsed, | |
| 55 security_state::SecurityLevel security_level, | |
| 56 vr_shell::RenderTextWrapper* render_text, | |
| 57 const ColorScheme& color_scheme) { | |
| 58 ApplyUrlStyling(formatted_url, parsed, security_level, render_text, | |
| 59 color_scheme); | |
| 60 } | |
| 61 | |
| 53 void SetForceFontFallbackFailure(bool force) { | 62 void SetForceFontFallbackFailure(bool force) { |
| 54 SetForceFontFallbackFailureForTesting(force); | 63 SetForceFontFallbackFailureForTesting(force); |
| 55 } | 64 } |
| 56 | 65 |
| 57 size_t GetNumberOfFontFallbacksForURL(const GURL& gurl) { | 66 size_t GetNumberOfFontFallbacksForURL(const GURL& gurl) { |
| 58 url::Parsed parsed; | 67 url::Parsed parsed; |
| 59 const base::string16 text = url_formatter::FormatUrl( | 68 const base::string16 text = url_formatter::FormatUrl( |
| 60 gurl, url_formatter::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, | 69 gurl, url_formatter::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, |
| 61 &parsed, nullptr, nullptr); | 70 &parsed, nullptr, nullptr); |
| 62 | 71 |
| 63 gfx::FontList font_list; | 72 gfx::FontList font_list; |
| 64 if (!GetFontList(kUrlHeight, text, &font_list)) | 73 if (!GetFontList(kUrlHeight, text, &font_list)) |
| 65 return 0; | 74 return 0; |
| 66 | 75 |
| 67 return font_list.GetFonts().size(); | 76 return font_list.GetFonts().size(); |
| 68 } | 77 } |
| 69 | 78 |
| 70 // Reports the last unsupported mode that was encountered. Returns kCount if | 79 // Reports the last unsupported mode that was encountered. Returns kCount if |
| 71 // no unsupported mode was encountered. | 80 // no unsupported mode was encountered. |
| 72 UiUnsupportedMode unsupported_mode() const { return unsupported_mode_; } | 81 UiUnsupportedMode unsupported_mode() const { return unsupported_mode_; } |
| 73 | 82 |
| 83 gfx::RenderText* url_render_text() { return url_render_text_.get(); } | |
| 84 const base::string16& url_text() { return url_text_; } | |
| 85 | |
| 74 private: | 86 private: |
| 75 void OnUnsupportedFeature(UiUnsupportedMode mode) { | 87 void OnUnsupportedFeature(UiUnsupportedMode mode) { |
| 76 unsupported_mode_ = mode; | 88 unsupported_mode_ = mode; |
| 77 } | 89 } |
| 78 | 90 |
| 79 gfx::Size texture_size_; | 91 gfx::Size texture_size_; |
| 80 gfx::Rect bounds_; | 92 gfx::Rect bounds_; |
| 81 UiUnsupportedMode unsupported_mode_ = UiUnsupportedMode::kCount; | 93 UiUnsupportedMode unsupported_mode_ = UiUnsupportedMode::kCount; |
| 82 }; | 94 }; |
| 83 | 95 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 109 protected: | 121 protected: |
| 110 void Verify(const std::string& url_string, | 122 void Verify(const std::string& url_string, |
| 111 SecurityLevel level, | 123 SecurityLevel level, |
| 112 const std::string& expected_string) { | 124 const std::string& expected_string) { |
| 113 GURL url(base::UTF8ToUTF16(url_string)); | 125 GURL url(base::UTF8ToUTF16(url_string)); |
| 114 url::Parsed parsed; | 126 url::Parsed parsed; |
| 115 const base::string16 formatted_url = url_formatter::FormatUrl( | 127 const base::string16 formatted_url = url_formatter::FormatUrl( |
| 116 url, url_formatter::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, | 128 url, url_formatter::kFormatUrlOmitAll, net::UnescapeRule::NORMAL, |
| 117 &parsed, nullptr, nullptr); | 129 &parsed, nullptr, nullptr); |
| 118 EXPECT_EQ(formatted_url, base::UTF8ToUTF16(expected_string)); | 130 EXPECT_EQ(formatted_url, base::UTF8ToUTF16(expected_string)); |
| 119 UrlBarTexture::ApplyUrlStyling( | 131 TestUrlBarTexture::TestUrlStyling( |
| 120 formatted_url, parsed, level, &mock_, | 132 formatted_url, parsed, level, &mock_, |
| 121 ColorScheme::GetColorScheme(ColorScheme::kModeNormal)); | 133 ColorScheme::GetColorScheme(ColorScheme::kModeNormal)); |
| 122 UrlBarTexture::ApplyUrlStyling( | 134 TestUrlBarTexture::TestUrlStyling( |
| 123 formatted_url, parsed, level, &mock_, | 135 formatted_url, parsed, level, &mock_, |
| 124 ColorScheme::GetColorScheme(ColorScheme::kModeIncognito)); | 136 ColorScheme::GetColorScheme(ColorScheme::kModeIncognito)); |
| 125 } | 137 } |
| 126 | 138 |
| 127 testing::InSequence in_sequence_; | 139 testing::InSequence in_sequence_; |
| 128 MockRenderText mock_; | 140 MockRenderText mock_; |
| 129 }; | 141 }; |
| 130 | 142 |
| 131 #if !defined(OS_LINUX) | 143 #if !defined(OS_LINUX) |
| 132 // TODO(crbug/731894): This test does not work on Linux. | 144 // TODO(crbug/731894): This test does not work on Linux. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 texture.DrawURL(GURL("https://foo.com")); | 207 texture.DrawURL(GURL("https://foo.com")); |
| 196 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); | 208 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); |
| 197 texture.SetForceFontFallbackFailure(true); | 209 texture.SetForceFontFallbackFailure(true); |
| 198 texture.DrawURL(GURL("https://bar.com")); | 210 texture.DrawURL(GURL("https://bar.com")); |
| 199 EXPECT_EQ(UiUnsupportedMode::kUnhandledCodePoint, texture.unsupported_mode()); | 211 EXPECT_EQ(UiUnsupportedMode::kUnhandledCodePoint, texture.unsupported_mode()); |
| 200 texture.SetForceFontFallbackFailure(false); | 212 texture.SetForceFontFallbackFailure(false); |
| 201 texture.DrawURL(GURL("https://baz.com")); | 213 texture.DrawURL(GURL("https://baz.com")); |
| 202 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); | 214 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); |
| 203 } | 215 } |
| 204 | 216 |
| 205 TEST(UrlBarTextureTest, WillFailOnStrongRTLChar) { | 217 TEST(UrlBarTextureTest, MaliciousRTLIsRenderedLTR) { |
| 206 TestUrlBarTexture texture; | 218 TestUrlBarTexture texture; |
| 207 texture.DrawURL(GURL("https://ש.com")); | 219 |
| 208 EXPECT_EQ(UiUnsupportedMode::kURLWithStrongRTLChars, | 220 // Construct a malicious URL that attempts to spoof the hostname. |
| 209 texture.unsupported_mode()); | 221 const std::string real_host("127.0.0.1"); |
| 222 const std::string spoofed_host("attack.com"); | |
| 223 const std::string url = | |
| 224 "http://" + real_host + "/ا/http://" + spoofed_host + ""; | |
| 225 | |
| 226 texture.DrawURL(GURL(base::UTF8ToUTF16(url))); | |
| 227 | |
| 228 // Determine the logical character ranges of the legitimate and spoofed | |
| 229 // hostnames in the processed URL text. | |
| 230 base::string16 text = texture.url_text(); | |
| 231 base::string16 real_16 = base::UTF8ToUTF16(real_host); | |
| 232 base::string16 spoofed_16 = base::UTF8ToUTF16(spoofed_host); | |
| 233 size_t position = text.find(real_16); | |
| 234 ASSERT_NE(position, base::string16::npos); | |
| 235 gfx::Range real_range(position, position + real_16.size()); | |
| 236 position = text.find(spoofed_16); | |
| 237 ASSERT_NE(position, base::string16::npos); | |
| 238 gfx::Range spoofed_range(position, position + spoofed_16.size()); | |
| 239 | |
| 240 // Extract the pixel locations at which hostnames were actually rendered. | |
| 241 auto real_bounds = | |
| 242 texture.url_render_text()->GetSubstringBoundsForTesting(real_range); | |
| 243 auto spoofed_bounds = | |
| 244 texture.url_render_text()->GetSubstringBoundsForTesting(spoofed_range); | |
| 245 EXPECT_EQ(real_bounds.size(), 1u); | |
| 246 EXPECT_GE(spoofed_bounds.size(), 1u); | |
| 247 | |
| 248 // Verify that any spoofed portion of the hostname has remained to the right | |
| 249 // of the legitimate hostname. This will fail if LTR directionality is not | |
| 250 // specified during URL rendering. | |
| 251 auto minimum_position = real_bounds[0].x() + real_bounds[0].width(); | |
|
cjgrant
2017/06/23 16:02:53
If I remove the new LTR directionality setting ove
| |
| 252 for (const auto& region : spoofed_bounds) { | |
| 253 EXPECT_GT(region.x(), minimum_position); | |
| 254 } | |
| 210 } | 255 } |
| 211 | 256 |
| 212 TEST(UrlBarTexture, ElisionIsAnUnsupportedMode) { | 257 TEST(UrlBarTexture, ElisionIsAnUnsupportedMode) { |
| 213 TestUrlBarTexture texture; | 258 TestUrlBarTexture texture; |
| 214 texture.DrawURL(GURL( | 259 texture.DrawURL(GURL( |
| 215 "https://" | 260 "https://" |
| 216 "thereisnopossiblewaythatthishostnamecouldbecontainedinthelimitedspacetha" | 261 "thereisnopossiblewaythatthishostnamecouldbecontainedinthelimitedspacetha" |
| 217 "tweareaffordedtousitsreallynotsomethingweshouldconsiderorplanfororpinour" | 262 "tweareaffordedtousitsreallynotsomethingweshouldconsiderorplanfororpinour" |
| 218 "hopesonlestwegetdisappointedor.sad.com")); | 263 "hopesonlestwegetdisappointedor.sad.com")); |
| 219 EXPECT_EQ(UiUnsupportedMode::kCouldNotElideURL, texture.unsupported_mode()); | 264 EXPECT_EQ(UiUnsupportedMode::kCouldNotElideURL, texture.unsupported_mode()); |
| 220 } | 265 } |
| 221 | 266 |
| 222 TEST(UrlBarTexture, ShortURLAreIndeedSupported) { | 267 TEST(UrlBarTexture, ShortURLAreIndeedSupported) { |
| 223 TestUrlBarTexture texture; | 268 TestUrlBarTexture texture; |
| 224 texture.DrawURL(GURL("https://short.com/")); | 269 texture.DrawURL(GURL("https://short.com/")); |
| 225 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); | 270 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); |
| 226 } | 271 } |
| 227 | 272 |
| 228 TEST(UrlBarTexture, LongPathsDoNotRequireElisionAndAreSupported) { | 273 TEST(UrlBarTexture, LongPathsDoNotRequireElisionAndAreSupported) { |
| 229 TestUrlBarTexture texture; | 274 TestUrlBarTexture texture; |
| 230 texture.DrawURL(GURL( | 275 texture.DrawURL(GURL( |
| 231 "https://something.com/" | 276 "https://something.com/" |
| 232 "thereisnopossiblewaythatthishostnamecouldbecontainedinthelimitedspacetha" | 277 "thereisnopossiblewaythatthishostnamecouldbecontainedinthelimitedspacetha" |
| 233 "tweareaffordedtousitsreallynotsomethingweshouldconsiderorplanfororpinour" | 278 "tweareaffordedtousitsreallynotsomethingweshouldconsiderorplanfororpinour" |
| 234 "hopesonlestwegetdisappointedorsad.com")); | 279 "hopesonlestwegetdisappointedorsad.com")); |
| 235 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); | 280 EXPECT_EQ(UiUnsupportedMode::kCount, texture.unsupported_mode()); |
| 236 } | 281 } |
| 237 | 282 |
| 238 } // namespace vr_shell | 283 } // namespace vr_shell |
| OLD | NEW |