Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 package org.chromium.chrome.browser; | 5 package org.chromium.chrome.browser; |
| 6 | 6 |
| 7 import android.app.Dialog; | 7 import android.app.Dialog; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.content.DialogInterface; | 9 import android.content.DialogInterface; |
| 10 import android.graphics.Color; | 10 import android.graphics.Color; |
| 11 import android.graphics.drawable.ColorDrawable; | 11 import android.graphics.drawable.ColorDrawable; |
| 12 import android.net.Uri; | |
| 12 import android.text.Layout; | 13 import android.text.Layout; |
| 13 import android.text.Spannable; | 14 import android.text.Spannable; |
| 14 import android.text.SpannableStringBuilder; | 15 import android.text.SpannableStringBuilder; |
| 15 import android.text.style.ForegroundColorSpan; | 16 import android.text.style.ForegroundColorSpan; |
| 16 import android.text.style.StyleSpan; | 17 import android.text.style.StyleSpan; |
| 17 import android.util.AttributeSet; | 18 import android.util.AttributeSet; |
| 18 import android.view.Gravity; | 19 import android.view.Gravity; |
| 19 import android.view.LayoutInflater; | 20 import android.view.LayoutInflater; |
| 20 import android.view.View; | 21 import android.view.View; |
| 21 import android.view.View.OnClickListener; | 22 import android.view.View.OnClickListener; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 if (maxLines != mCurrentMaxLines) { | 158 if (maxLines != mCurrentMaxLines) { |
| 158 setMaxLines(maxLines); | 159 setMaxLines(maxLines); |
| 159 return true; | 160 return true; |
| 160 } | 161 } |
| 161 return false; | 162 return false; |
| 162 } | 163 } |
| 163 } | 164 } |
| 164 | 165 |
| 165 private static final int MAX_TABLET_DIALOG_WIDTH_DP = 400; | 166 private static final int MAX_TABLET_DIALOG_WIDTH_DP = 400; |
| 166 | 167 |
| 168 // This is the "reserved" character set from RFC 3986, plus the '%' characte r. | |
| 169 private static final String URI_RESERVED_CHARACTERS = "!*'();:@&=+$,/?#[]%"; | |
| 170 | |
| 171 private static final char FIRST_UNICODE_WHITESPACE = '\u2000'; | |
| 172 private static final char FINAL_UNICODE_WHITESPACE = '\u200F'; | |
| 173 private static final char UNICODE_NBSP = '\u00A0'; | |
| 174 | |
| 167 private final Context mContext; | 175 private final Context mContext; |
| 168 private final Profile mProfile; | 176 private final Profile mProfile; |
| 169 private final WebContents mWebContents; | 177 private final WebContents mWebContents; |
| 170 | 178 |
| 171 // A pointer to the C++ object for this UI. | 179 // A pointer to the C++ object for this UI. |
| 172 private final long mNativeWebsiteSettingsPopup; | 180 private final long mNativeWebsiteSettingsPopup; |
| 173 | 181 |
| 174 // The outer container, filled with the layout from website_settings.xml. | 182 // The outer container, filled with the layout from website_settings.xml. |
| 175 private final LinearLayout mContainer; | 183 private final LinearLayout mContainer; |
| 176 | 184 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 282 mFullUrl = mWebContents.getVisibleUrl(); | 290 mFullUrl = mWebContents.getVisibleUrl(); |
| 283 try { | 291 try { |
| 284 mParsedUrl = new URI(mFullUrl); | 292 mParsedUrl = new URI(mFullUrl); |
| 285 mIsInternalPage = UrlUtilities.isInternalScheme(mParsedUrl); | 293 mIsInternalPage = UrlUtilities.isInternalScheme(mParsedUrl); |
| 286 } catch (URISyntaxException e) { | 294 } catch (URISyntaxException e) { |
| 287 mParsedUrl = null; | 295 mParsedUrl = null; |
| 288 mIsInternalPage = false; | 296 mIsInternalPage = false; |
| 289 } | 297 } |
| 290 mSecurityLevel = ToolbarModel.getSecurityLevelForWebContents(mWebContent s); | 298 mSecurityLevel = ToolbarModel.getSecurityLevelForWebContents(mWebContent s); |
| 291 | 299 |
| 292 SpannableStringBuilder urlBuilder = new SpannableStringBuilder(mFullUrl) ; | 300 String displayUrl = encodeSuspiciousFragment(mFullUrl); |
| 301 SpannableStringBuilder urlBuilder = new SpannableStringBuilder(displayUr l); | |
| 293 OmniboxUrlEmphasizer.emphasizeUrl(urlBuilder, mContext.getResources(), m Profile, | 302 OmniboxUrlEmphasizer.emphasizeUrl(urlBuilder, mContext.getResources(), m Profile, |
| 294 mSecurityLevel, mIsInternalPage, true); | 303 mSecurityLevel, mIsInternalPage, true); |
| 295 mUrlTitle.setText(urlBuilder); | 304 mUrlTitle.setText(urlBuilder); |
| 296 | 305 |
| 297 // Set the URL connection message now, and the URL after layout (so it | 306 // Set the URL connection message now, and the URL after layout (so it |
| 298 // can calculate its ideal height). | 307 // can calculate its ideal height). |
| 299 mUrlConnectionMessage.setText(getUrlConnectionMessage()); | 308 mUrlConnectionMessage.setText(getUrlConnectionMessage()); |
| 300 } | 309 } |
| 301 | 310 |
| 302 /** | 311 /** |
| 312 * Percent-encodes a URL fragment if it contains suspicious unicode whitespa ce characters. | |
|
Matt Giuca
2015/03/24 06:28:37
nit: Unicode is a proper noun (always capitalize w
tsergeant
2015/03/25 01:55:24
Done.
| |
| 313 * Otherwise, returns the original URL. All parts of the URL other than the fragment will | |
| 314 * already be encoded. | |
| 315 */ | |
| 316 public static String encodeSuspiciousFragment(String urlStr) { | |
|
Matt Giuca
2015/03/24 06:28:37
What do you mean by "fragment" here? Do you mean s
tsergeant
2015/03/25 01:55:24
The intention was that even though we're working o
Matt Giuca
2015/03/25 03:23:24
You should remove the last sentence of the documen
| |
| 317 if (isSuspiciousUrl(urlStr)) { | |
|
Matt Giuca
2015/03/24 06:28:37
I'm not too keen on this behaviour, as you will be
tsergeant
2015/03/25 01:55:24
Makes sense, Done.
| |
| 318 // Explicitly pass the set of reserved characters to prevent them fr om being escaped. | |
| 319 return Uri.encode(urlStr, URI_RESERVED_CHARACTERS); | |
| 320 } | |
| 321 return urlStr; | |
| 322 } | |
| 323 | |
| 324 /** | |
| 325 * Returns true if the fragment string contains characters that could be use d to inject a | |
| 326 * phishing attack into the popup. We filter based on any unicode whitespace character. | |
| 327 */ | |
| 328 public static boolean isSuspiciousUrl(String urlStr) { | |
| 329 for (int i = 0; i < urlStr.length(); i++) { | |
| 330 char fragmentChar = urlStr.charAt(i); | |
| 331 if ((fragmentChar >= FIRST_UNICODE_WHITESPACE | |
| 332 && fragmentChar <= FINAL_UNICODE_WHITESPACE) | |
| 333 || fragmentChar == ' ' | |
| 334 || fragmentChar == UNICODE_NBSP) | |
| 335 return true; | |
| 336 } | |
| 337 return false; | |
| 338 } | |
| 339 | |
| 340 /** | |
| 303 * Sets the visibility of the lower area of the dialog (containing the permi ssions and 'Site | 341 * Sets the visibility of the lower area of the dialog (containing the permi ssions and 'Site |
| 304 * Settings' button). | 342 * Settings' button). |
| 305 * | 343 * |
| 306 * @param isVisible Whether to show or hide the dialog area. | 344 * @param isVisible Whether to show or hide the dialog area. |
| 307 */ | 345 */ |
| 308 private void setVisibilityOfLowerDialogArea(boolean isVisible) { | 346 private void setVisibilityOfLowerDialogArea(boolean isVisible) { |
| 309 mHorizontalSeparator.setVisibility(isVisible ? View.VISIBLE : View.GONE) ; | 347 mHorizontalSeparator.setVisibility(isVisible ? View.VISIBLE : View.GONE) ; |
| 310 mLowerDialogArea.setVisibility(isVisible ? View.VISIBLE : View.GONE); | 348 mLowerDialogArea.setVisibility(isVisible ? View.VISIBLE : View.GONE); |
| 311 } | 349 } |
| 312 | 350 |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 new WebsiteSettingsPopup(context, profile, webContents); | 574 new WebsiteSettingsPopup(context, profile, webContents); |
| 537 } | 575 } |
| 538 | 576 |
| 539 private static native long nativeInit(WebsiteSettingsPopup popup, WebContent s webContents); | 577 private static native long nativeInit(WebsiteSettingsPopup popup, WebContent s webContents); |
| 540 | 578 |
| 541 private native void nativeDestroy(long nativeWebsiteSettingsPopupAndroid); | 579 private native void nativeDestroy(long nativeWebsiteSettingsPopupAndroid); |
| 542 | 580 |
| 543 private native void nativeOnPermissionSettingChanged(long nativeWebsiteSetti ngsPopupAndroid, | 581 private native void nativeOnPermissionSettingChanged(long nativeWebsiteSetti ngsPopupAndroid, |
| 544 int type, int setting); | 582 int type, int setting); |
| 545 } | 583 } |
| OLD | NEW |