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

Side by Side Diff: net/base/escape.cc

Issue 632843003: Add a function to escape a query part of url (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Follow RFC 2396 to escape a query part of url 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "net/base/escape.h" 5 #include "net/base/escape.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string_piece.h" 11 #include "base/strings/string_piece.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_offset_string_conversions.h" 13 #include "base/strings/utf_offset_string_conversions.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 15
16 namespace net { 16 namespace net {
17 17
18 namespace { 18 namespace {
19 19
20 const char kHexString[] = "0123456789ABCDEF"; 20 const char kHexString[] = "0123456789ABCDEF";
21 inline char IntToHex(int i) { 21 inline char IntToHex(int i) {
22 DCHECK_GE(i, 0) << i << " not a hex value"; 22 DCHECK_GE(i, 0) << i << " not a hex value";
23 DCHECK_LE(i, 15) << i << " not a hex value"; 23 DCHECK_LE(i, 15) << i << " not a hex value";
24 return kHexString[i]; 24 return kHexString[i];
25 } 25 }
26 26
27 inline bool IsHexChar(unsigned char c) {
28 if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ||
29 (c >= '0' && c <= '9'))
30 return true;
31 return false;
32 }
33
27 // A fast bit-vector map for ascii characters. 34 // A fast bit-vector map for ascii characters.
28 // 35 //
29 // Internally stores 256 bits in an array of 8 ints. 36 // Internally stores 256 bits in an array of 8 ints.
30 // Does quick bit-flicking to lookup needed characters. 37 // Does quick bit-flicking to lookup needed characters.
31 struct Charmap { 38 struct Charmap {
32 bool Contains(unsigned char c) const { 39 bool Contains(unsigned char c) const {
33 return ((map[c >> 5] & (1 << (c & 31))) != 0); 40 return ((map[c >> 5] & (1 << (c & 31))) != 0);
34 } 41 }
35 42
36 uint32 map[8]; 43 uint32 map[8];
37 }; 44 };
38 45
39 // Given text to escape and a Charmap defining which values to escape, 46 // Given text to escape and a Charmap defining which values to escape,
40 // return an escaped string. If use_plus is true, spaces are converted 47 // return an escaped string. If use_plus is true, spaces are converted
41 // to +, otherwise, if spaces are in the charmap, they are converted to 48 // to +, otherwise, if spaces are in the charmap, they are converted to
42 // %20. 49 // %20.
43 std::string Escape(const std::string& text, const Charmap& charmap, 50 std::string Escape(const std::string& text, const Charmap& charmap,
44 bool use_plus) { 51 bool use_plus, bool keep_escaped = false) {
45 std::string escaped; 52 std::string escaped;
46 escaped.reserve(text.length() * 3); 53 escaped.reserve(text.length() * 3);
47 for (unsigned int i = 0; i < text.length(); ++i) { 54 for (unsigned int i = 0; i < text.length(); ++i) {
48 unsigned char c = static_cast<unsigned char>(text[i]); 55 unsigned char c = static_cast<unsigned char>(text[i]);
49 if (use_plus && ' ' == c) { 56 if (use_plus && ' ' == c) {
50 escaped.push_back('+'); 57 escaped.push_back('+');
58 } else if (keep_escaped && '%' == c && i + 2 < text.length() &&
59 IsHexChar(static_cast<unsigned char>(text[i + 1])) &&
60 IsHexChar(static_cast<unsigned char>(text[i + 2]))) {
61 escaped.push_back('%');
51 } else if (charmap.Contains(c)) { 62 } else if (charmap.Contains(c)) {
52 escaped.push_back('%'); 63 escaped.push_back('%');
53 escaped.push_back(IntToHex(c >> 4)); 64 escaped.push_back(IntToHex(c >> 4));
54 escaped.push_back(IntToHex(c & 0xf)); 65 escaped.push_back(IntToHex(c & 0xf));
55 } else { 66 } else {
56 escaped.push_back(c); 67 escaped.push_back(c);
57 } 68 }
58 } 69 }
59 return escaped; 70 return escaped;
60 } 71 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL 303 0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
293 }}; 304 }};
294 305
295 // Everything except alphanumerics, the reserved characters(;/?:@&=+$,) and 306 // Everything except alphanumerics, the reserved characters(;/?:@&=+$,) and
296 // !'()*-._~% 307 // !'()*-._~%
297 static const Charmap kExternalHandlerCharmap = {{ 308 static const Charmap kExternalHandlerCharmap = {{
298 0xffffffffL, 0x5000080dL, 0x68000000L, 0xb8000001L, 309 0xffffffffL, 0x5000080dL, 0x68000000L, 0xb8000001L,
299 0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL 310 0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
300 }}; 311 }};
301 312
313 // Everything except alphanumerics, the reserved characters(;/?:@&=+$,), the
314 // mark characters(-_.!~*'()).
315 static const Charmap kQueryPartCharmap = {{
316 0xffffffffL, 0x5000002dL, 0x78000000L, 0xb8000001L,
317 0xffffffffL, 0xffffffffL, 0xffffffffL, 0xffffffffL
318 }};
319
302 } // namespace 320 } // namespace
303 321
304 std::string EscapeQueryParamValue(const std::string& text, bool use_plus) { 322 std::string EscapeQueryParamValue(const std::string& text, bool use_plus) {
305 return Escape(text, kQueryCharmap, use_plus); 323 return Escape(text, kQueryCharmap, use_plus);
306 } 324 }
307 325
308 std::string EscapePath(const std::string& path) { 326 std::string EscapePath(const std::string& path) {
309 return Escape(path, kPathCharmap, false); 327 return Escape(path, kPathCharmap, false);
310 } 328 }
311 329
312 std::string EscapeUrlEncodedData(const std::string& path, bool use_plus) { 330 std::string EscapeUrlEncodedData(const std::string& path, bool use_plus) {
313 return Escape(path, kUrlEscape, use_plus); 331 return Escape(path, kUrlEscape, use_plus);
314 } 332 }
315 333
316 std::string EscapeNonASCII(const std::string& input) { 334 std::string EscapeNonASCII(const std::string& input) {
317 return Escape(input, kNonASCIICharmap, false); 335 return Escape(input, kNonASCIICharmap, false);
318 } 336 }
319 337
320 std::string EscapeExternalHandlerValue(const std::string& text) { 338 std::string EscapeExternalHandlerValue(const std::string& text) {
321 return Escape(text, kExternalHandlerCharmap, false); 339 return Escape(text, kExternalHandlerCharmap, false);
322 } 340 }
323 341
342 std::string EscapeQueryPart(const std::string& query) {
343 return Escape(query, kQueryPartCharmap, false, true);
344 }
345
324 void AppendEscapedCharForHTML(char c, std::string* output) { 346 void AppendEscapedCharForHTML(char c, std::string* output) {
325 AppendEscapedCharForHTMLImpl(c, output); 347 AppendEscapedCharForHTMLImpl(c, output);
326 } 348 }
327 349
328 std::string EscapeForHTML(const std::string& input) { 350 std::string EscapeForHTML(const std::string& input) {
329 return EscapeForHTMLImpl(input); 351 return EscapeForHTMLImpl(input);
330 } 352 }
331 353
332 base::string16 EscapeForHTML(const base::string16& input) { 354 base::string16 EscapeForHTML(const base::string16& input) {
333 return EscapeForHTMLImpl(input); 355 return EscapeForHTMLImpl(input);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 1, kEscapeToChars[i].replacement); 424 1, kEscapeToChars[i].replacement);
403 break; 425 break;
404 } 426 }
405 } 427 }
406 } 428 }
407 } 429 }
408 return text; 430 return text;
409 } 431 }
410 432
411 } // namespace net 433 } // namespace net
OLDNEW
« net/base/escape.h ('K') | « net/base/escape.h ('k') | net/base/escape_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698