Commit 2bfde554 authored by Samuel Huang's avatar Samuel Huang Committed by Commit Bot

[DevUI DFM] Improve usability of chrome://dev-ui-loader URL redirection.

Visiting the chrome:// URL of a host that's in the DevUI DFM triggers
install / load flow through chrome://dev-ui-loader, which then
redirects to the original chrome:// URL on completion. Previously the
flow suffers from the following:
* Bug: The state "installed" should be "ready".
* /path?query/fragment of the original URL is discarded.
* Redirect to chrome://dev-ui-loader is possible, leading to bizarre
  redirect chains.

This CL fixes the above by replacing "?page=<host>" with
"?url=<escaped URL>". This involves escaping the URL in the (C++) URL
rendering code and unescaping the URL in the (JS) URL reading code.
Invalid "?url=" simply leads to chrome://chrome-urls.

Bug: 927131
Change-Id: Ia7c1c7874f76ee6d80b347fc49a73dec50a5c80c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1783519
Commit-Queue: Samuel Huang <huangs@chromium.org>
Reviewed-by: default avatarTibor Goldschwendt <tiborg@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Reviewed-by: default avatarDan Beam <dbeam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#693206}
parent 142c8716
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "chrome/browser/android/dev_ui/dev_ui_module_provider.h" #include "chrome/browser/android/dev_ui/dev_ui_module_provider.h"
#include "chrome/common/webui_url_constants.h" #include "chrome/common/webui_url_constants.h"
#include "net/base/url_util.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace chrome { namespace chrome {
...@@ -32,12 +33,11 @@ bool HandleDfmifiedDevUiPageURL( ...@@ -32,12 +33,11 @@ bool HandleDfmifiedDevUiPageURL(
// No need to check ModuleInstalled(): It's implied by ModuleLoaded(). // No need to check ModuleInstalled(): It's implied by ModuleLoaded().
return false; return false;
} }
// Provide |url->host()| so the DevUI loader can redirect to the proper page // Create URL to the DevUI loader with "?url=<escaped original URL>" so that
// after install / load. // after install / load, the loader can redirect to the original URL.
// TODO(huangs): Escape /path?query#fragment and pass these; unescape in *url = net::AppendQueryParameter(
// chrome://dev-ui-loader when redirecting. GURL(std::string(kChromeUIDevUiLoaderURL) + "dev_ui_loader.html"), "url",
*url = GURL(std::string(kChromeUIDevUiLoaderURL) + url->spec());
"dev_ui_loader.html?page=" + url->host());
return true; return true;
} }
......
...@@ -5,29 +5,44 @@ ...@@ -5,29 +5,44 @@
(function() { (function() {
'use strict'; 'use strict';
/** @param {string} page */ /** @return {!URL} */
function redirectToChromePage(page) { function getRedirectUrl() {
try { // For potential TypeError from new URL().
const urlString = new URL(location).searchParams.get('url');
if (urlString) {
const url = new URL(decodeURIComponent(urlString));
// Perform basic filtering. Also skip 'dev-ui-loader' to avoid redirect
// cycle (benign but bizarre). Note that |url.host| is always lowercase.
if (url.protocol === 'chrome:' && url.host.match(/[a-z0-9_\-]+/) &&
url.host !== 'dev-ui-loader') {
return url;
}
}
} catch (e) {
}
return new URL('chrome://chrome-urls');
}
function redirectToChromePage() {
// Use replace() so the current page disappears from history. // Use replace() so the current page disappears from history.
location.replace('chrome://' + page); location.replace(getRedirectUrl());
} }
function doInstall() { function doInstall() {
cr.sendWithPromise('installAndLoadDevUiDfm').then((response) => { cr.sendWithPromise('installAndLoadDevUiDfm').then((response) => {
const query = new URL(window.location).searchParams;
const targetPage = (query.get('page') || '').replace(/[^a-z0-9_\-]/g, '');
const status = response[0]; const status = response[0];
if (status === 'failure') { if (status === 'success' || status === 'noop') {
redirectToChromePage();
} else if (status === 'failure') {
document.querySelector('#failure-message').hidden = false; document.querySelector('#failure-message').hidden = false;
} else if (status === 'success' || status === 'noop') {
redirectToChromePage(targetPage);
} }
}); });
} }
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
cr.sendWithPromise('getDevUiDfmState').then((state) => { cr.sendWithPromise('getDevUiDfmState').then((state) => {
if (state === 'installed') { if (state === 'ready') {
redirectToChromePage('chrome-urls'); redirectToChromePage();
} else if (state === 'not-installed' || 'not-loaded') { } else if (state === 'not-installed' || 'not-loaded') {
doInstall(); doInstall();
} }
......
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