Commit c1ab2b10 authored by sashab's avatar sashab Committed by Commit bot

Fixed crash caused from invalid URLs in the PageInfo dialog

Cleaned up WebsiteSettingsPopup::updatePageDetails in the PageInfo
dialog and fixed a crash from invalid URLs. When a malformed URL is
accessed, the PageInfo dialog will still display the URL, but won't
apply any custom coloring (this only applies to well-formed URLs).

TEST=Visit a malformed URL, such as 'data:html,foo<script', and open the
PageInfo dialog by long-pressing on the URL. The URL should be displayed
(but not colored), and Chrome should not crash.
BUG=427566

Review URL: https://codereview.chromium.org/690343003

Cr-Commit-Position: refs/heads/master@{#302743}
parent e45038f7
...@@ -99,7 +99,6 @@ public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedList ...@@ -99,7 +99,6 @@ public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedList
// The full URL from the URL bar, which is copied to the user's clipboard when they select 'Copy // The full URL from the URL bar, which is copied to the user's clipboard when they select 'Copy
// URL'. // URL'.
private String mFullUrl; private String mFullUrl;
private URI mUrl;
/** /**
* Creates the WebsiteSettingsPopup, but does not display it. Also initializes the corresponding * Creates the WebsiteSettingsPopup, but does not display it. Also initializes the corresponding
...@@ -196,83 +195,134 @@ public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedList ...@@ -196,83 +195,134 @@ public class WebsiteSettingsPopup implements OnClickListener, OnItemSelectedList
} }
} }
@CalledByNative /**
private void updatePageDetails(boolean isInternalPage) { * Gets the color to use for the scheme in the URL title for the given security level. Does not
mFullUrl = mWebContents.getVisibleUrl(); * apply to internal pages.
int securityLevel = ToolbarModel.getSecurityLevelForWebContents(mWebContents); *
* @param toolbarModelSecurityLevel A valid ToolbarModelSecurityLevel, which is the security
try { * level of the page.
mUrl = new URI(mFullUrl); * @return The color ID to color the scheme in the URL title.
} catch (URISyntaxException e) { */
assert false : "Invalid URL specified: " + mFullUrl; private int getSchemeColorId(int toolbarModelSecurityLevel) {
switch (toolbarModelSecurityLevel) {
case ToolbarModelSecurityLevel.NONE:
return R.color.website_settings_popup_url_scheme_http;
case ToolbarModelSecurityLevel.SECURE:
case ToolbarModelSecurityLevel.EV_SECURE:
return R.color.website_settings_popup_url_scheme_https;
case ToolbarModelSecurityLevel.SECURITY_WARNING:
case ToolbarModelSecurityLevel.SECURITY_POLICY_WARNING:
return R.color.website_settings_popup_url_scheme_mixed;
case ToolbarModelSecurityLevel.SECURITY_ERROR:
return R.color.website_settings_popup_url_scheme_broken;
default:
assert false : "Invalid security level specified: " + toolbarModelSecurityLevel;
return R.color.website_settings_popup_url_scheme_http;
}
} }
int schemeColorId = -1; /**
if (securityLevel == ToolbarModelSecurityLevel.SECURITY_ERROR) { * Gets the message to display in the connection message box for the given security level. Does
schemeColorId = R.color.website_settings_popup_url_scheme_broken; * not apply to SECURITY_ERROR pages, since these have their own coloured/formatted message.
*
String leadingText = mContext.getResources().getString( * @param toolbarModelSecurityLevel A valid ToolbarModelSecurityLevel, which is the security
R.string.page_info_connection_broken_leading_text); * level of the page.
String followingText = mContext.getResources().getString( * @return The ID of the message to display in the connection message box.
R.string.page_info_connection_broken_following_text, */
UrlUtilities.getOriginForDisplay(mUrl, false)); private int getConnectionMessageId(int toolbarModelSecurityLevel) {
SpannableStringBuilder sb = new SpannableStringBuilder(leadingText + " " switch (toolbarModelSecurityLevel) {
+ followingText);
final ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources()
.getColor(R.color.website_settings_popup_url_scheme_broken));
final StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
sb.setSpan(redSpan, 0, leadingText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
sb.setSpan(boldSpan, 0, leadingText.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mUrlConnectionMessage.setText(sb);
} else {
int connectionMessageId = 0;
if (isInternalPage) {
schemeColorId = R.color.website_settings_popup_url_scheme_http;
connectionMessageId = R.string.page_info_connection_internal_page;
} else {
switch (securityLevel) {
case ToolbarModelSecurityLevel.NONE: case ToolbarModelSecurityLevel.NONE:
schemeColorId = R.color.website_settings_popup_url_scheme_http; return R.string.page_info_connection_http;
connectionMessageId = R.string.page_info_connection_http;
break;
case ToolbarModelSecurityLevel.SECURE: case ToolbarModelSecurityLevel.SECURE:
case ToolbarModelSecurityLevel.EV_SECURE: case ToolbarModelSecurityLevel.EV_SECURE:
schemeColorId = R.color.website_settings_popup_url_scheme_https; return R.string.page_info_connection_https;
connectionMessageId = R.string.page_info_connection_https;
break;
case ToolbarModelSecurityLevel.SECURITY_WARNING: case ToolbarModelSecurityLevel.SECURITY_WARNING:
case ToolbarModelSecurityLevel.SECURITY_POLICY_WARNING: case ToolbarModelSecurityLevel.SECURITY_POLICY_WARNING:
schemeColorId = R.color.website_settings_popup_url_scheme_mixed; return R.string.page_info_connection_mixed;
connectionMessageId = R.string.page_info_connection_mixed;
break;
default: default:
assert false : "Invalid security level specified: " + securityLevel; assert false : "Invalid security level specified: " + toolbarModelSecurityLevel;
schemeColorId = R.color.website_settings_popup_url_scheme_http; return R.string.page_info_connection_http;
connectionMessageId = R.string.page_info_connection_http; }
} }
/**
* Updates the details (URL title and connection message) displayed in the popup.
*
* @param isInternalPage Whether or not this page is an internal chrome page (e.g. the
* chrome://settings page).
*/
@CalledByNative
private void updatePageDetails(boolean isInternalPage) {
mFullUrl = mWebContents.getVisibleUrl();
int securityLevel = ToolbarModel.getSecurityLevelForWebContents(mWebContents);
URI parsedUrl;
try {
parsedUrl = new URI(mFullUrl);
} catch (URISyntaxException e) {
parsedUrl = null;
} }
mUrlConnectionMessage.setText(mContext.getResources().getString(connectionMessageId));
if (parsedUrl != null) {
// The URL is valid - color the scheme (and other components) for the security level.
SpannableStringBuilder sb = new SpannableStringBuilder();
int schemeColorId = R.color.website_settings_popup_url_scheme_http;
if (!isInternalPage) {
schemeColorId = getSchemeColorId(securityLevel);
} }
// Color the URI-parsed version of the URL. sb.append(parsedUrl.toString());
SpannableStringBuilder sb = new SpannableStringBuilder(mUrl.toString()); final ForegroundColorSpan schemeColorSpan = new ForegroundColorSpan(
final ForegroundColorSpan schemeColorSpan = new ForegroundColorSpan(mContext.getResources() mContext.getResources().getColor(schemeColorId));
.getColor(schemeColorId)); sb.setSpan(schemeColorSpan, 0, parsedUrl.getScheme().length(),
sb.setSpan(schemeColorSpan, 0, mUrl.getScheme().length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE); Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
if (securityLevel == ToolbarModelSecurityLevel.SECURITY_ERROR) { if (securityLevel == ToolbarModelSecurityLevel.SECURITY_ERROR) {
sb.setSpan(new StrikethroughSpan(), 0, mUrl.getScheme().length(), sb.setSpan(new StrikethroughSpan(), 0, parsedUrl.getScheme().length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE); Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
} }
// The domain is everything after the scheme until the end of the // The domain is everything after the scheme until the end of the origin.
// origin.
final ForegroundColorSpan domainColorSpan = new ForegroundColorSpan( final ForegroundColorSpan domainColorSpan = new ForegroundColorSpan(
mContext.getResources().getColor(R.color.website_settings_popup_url_domain)); mContext.getResources().getColor(R.color.website_settings_popup_url_domain));
sb.setSpan(domainColorSpan, mUrl.getScheme().length(), sb.setSpan(domainColorSpan, parsedUrl.getScheme().length(),
UrlUtilities.getOriginForDisplay(mUrl, true).length(), UrlUtilities.getOriginForDisplay(parsedUrl, true).length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE); Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mUrlTitle.setText(sb); mUrlTitle.setText(sb);
} else {
// The URL is invalid - still display it in the title, but don't apply any coloring.
mUrlTitle.setText(mFullUrl);
}
// Display the appropriate connection message.
SpannableStringBuilder messageBuilder = new SpannableStringBuilder();
if (securityLevel != ToolbarModelSecurityLevel.SECURITY_ERROR) {
messageBuilder.append(mContext.getResources().getString(
getConnectionMessageId(securityLevel)));
} else {
String originToDisplay;
if (parsedUrl != null) {
originToDisplay = UrlUtilities.getOriginForDisplay(parsedUrl, false);
} else {
// The URL is invalid - just display the full URL.
originToDisplay = mFullUrl;
}
String leadingText = mContext.getResources().getString(
R.string.page_info_connection_broken_leading_text);
String followingText = mContext.getResources().getString(
R.string.page_info_connection_broken_following_text, originToDisplay);
messageBuilder.append(leadingText + " " + followingText);
final ForegroundColorSpan redSpan = new ForegroundColorSpan(mContext.getResources()
.getColor(R.color.website_settings_popup_url_scheme_broken));
final StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
messageBuilder.setSpan(redSpan, 0, leadingText.length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
messageBuilder.setSpan(boldSpan, 0, leadingText.length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
mUrlConnectionMessage.setText(messageBuilder);
} }
/** /**
......
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