Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4696)

Unified Diff: chrome/browser/android/url_sanitize_utils.cc

Issue 646333002: Update EscapeExternalHandlerValue to keep '#', '[', and ']' (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sanitize fragment and path Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/url_sanitize_utils.cc
diff --git a/chrome/browser/android/url_sanitize_utils.cc b/chrome/browser/android/url_sanitize_utils.cc
new file mode 100644
index 0000000000000000000000000000000000000000..dde84b77aa360a4035fd7b2df28346401fe65980
--- /dev/null
+++ b/chrome/browser/android/url_sanitize_utils.cc
@@ -0,0 +1,108 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/url_sanitize_utils.h"
+
+#include "base/logging.h"
+
+namespace chrome {
+namespace android {
+
+namespace {
+
+static const char kHexString[] = "0123456789ABCDEF";
+inline char IntToHex(int i) {
+ DCHECK_GE(i, 0) << i << " not a hex value";
+ DCHECK_LE(i, 15) << i << " not a hex value";
+ return kHexString[i];
+}
+
+inline bool IsHexChar(unsigned char c) {
+ if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ||
+ (c >= '0' && c <= '9'))
+ return true;
+ return false;
+}
+
+// A fast bit-vector map for ascii characters.
+//
+// Internally stores 256 bits in an array of 8 ints.
+// Does quick bit-flicking to lookup needed characters.
+struct Charmap {
+ bool Contains(unsigned char c) const {
+ return ((map[c >> 5] & (1 << (c & 31))) != 0);
+ }
+
+ uint32 map[8];
+};
+
+// Everything except alphanumerics, and some reserved characters
+// (;/?:@&=+$,-_.!~*'()). See RFC 2396 for the list of reserved characters.
+static const Charmap kQueryOrRefPartCharmap = {{
+ 0xffffffffL, 0x5000002dL, 0x78000000L, 0xb8000001L,
+ 0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
+}};
+
+// Everything except alphanumerics, and some reserved characters
+// (;/:@&=+$,-_.!~*'()). See RFC 2396 for the list of reserved characters.
+static const Charmap kPathPartCharmap = {{
+ 0xffffffffL, 0xd000002dL, 0x78000000L, 0xb8000001L,
+ 0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
+}};
asanka 2014/10/14 16:46:03 Are these tables different from net/base/escape.cc
Jaekyun Seok (inactive) 2014/10/15 08:02:25 Yes, both are different from net/base/escape.cc.
asanka 2014/10/17 00:07:28 Doesn't net::EscapeExternalHandlerValue() do what
+
+// Given text to escape and a Charmap defining which values to escape,
+// return an escaped string. If characters are already escaped, they aren't
+// converted.
+static std::string Escape(const std::string& text, const Charmap& charmap) {
+ std::string escaped;
+ escaped.reserve(text.length() * 3);
+ for (unsigned int i = 0; i < text.length(); ++i) {
+ unsigned char c = static_cast<unsigned char>(text[i]);
+ if ('%' == c && i + 2 < text.length() &&
+ IsHexChar(static_cast<unsigned char>(text[i + 1])) &&
+ IsHexChar(static_cast<unsigned char>(text[i + 2]))) {
+ escaped.push_back('%');
+ } else if (charmap.Contains(c)) {
+ escaped.push_back('%');
+ escaped.push_back(IntToHex(c >> 4));
+ escaped.push_back(IntToHex(c & 0xf));
+ } else {
+ escaped.push_back(c);
+ }
+ }
+ return escaped;
+}
+
+} // namespace
+
+GURL SanitizeUrl(const GURL& url) {
+ std::string query_input = url.query();
+ std::string ref_input = url.ref();
+ std::string path_input = url.path();
+ std::string query_output = Escape(query_input, kQueryOrRefPartCharmap);
+ std::string ref_output = Escape(ref_input, kQueryOrRefPartCharmap);
+ std::string path_output = Escape(path_input, kPathPartCharmap);
+
+ GURL::Replacements replacements;
+ bool modified = false;
+ if (!query_output.empty() && query_output != query_input) {
+ replacements.SetQueryStr(query_output);
+ modified = true;
+ }
+ if (!ref_output.empty() && ref_output != ref_input) {
+ replacements.SetRefStr(ref_output);
+ modified = true;
+ }
+ if (!path_output.empty() && path_output != path_input) {
+ replacements.SetPathStr(path_output);
+ modified = true;
+ }
+
+ if (modified)
+ return url.ReplaceComponents(replacements);
+ return url;
+}
+
+} // namespace android
+} // namespace chrome

Powered by Google App Engine
This is Rietveld 408576698