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
3 // found in the LICENSE file.
4
5 // Functions for canonicalizing "mailto:" URLs.
6
7 #include "url/url_canon.h"
8 #include "url/url_canon_internal.h"
9 #include "url/url_file.h"
10 #include "url/url_parse_internal.h"
11
12 namespace url {
13
14 namespace {
15
16 template <typename CHAR, typename UCHAR>
DoCanonicalizeMailtoURL(const URLComponentSource<CHAR> & source,const Parsed & parsed,CanonOutput * output,Parsed * new_parsed)17 bool DoCanonicalizeMailtoURL(const URLComponentSource<CHAR>& source,
18 const Parsed& parsed,
19 CanonOutput* output,
20 Parsed* new_parsed) {
21 // mailto: only uses {scheme, path, query} -- clear the rest.
22 new_parsed->username = Component();
23 new_parsed->password = Component();
24 new_parsed->host = Component();
25 new_parsed->port = Component();
26 new_parsed->ref = Component();
27
28 // Scheme (known, so we don't bother running it through the more
29 // complicated scheme canonicalizer).
30 new_parsed->scheme.begin = output->length();
31 output->Append("mailto:", 7);
32 new_parsed->scheme.len = 6;
33
34 bool success = true;
35
36 // Path
37 if (parsed.path.is_valid()) {
38 new_parsed->path.begin = output->length();
39
40 // Copy the path using path URL's more lax escaping rules.
41 // We convert to UTF-8 and escape non-ASCII, but leave all
42 // ASCII characters alone.
43 int end = parsed.path.end();
44 for (int i = parsed.path.begin; i < end; ++i) {
45 UCHAR uch = static_cast<UCHAR>(source.path[i]);
46 if (uch < 0x20 || uch >= 0x80)
47 success &= AppendUTF8EscapedChar(source.path, &i, end, output);
48 else
49 output->push_back(static_cast<char>(uch));
50 }
51
52 new_parsed->path.len = output->length() - new_parsed->path.begin;
53 } else {
54 // No path at all
55 new_parsed->path.reset();
56 }
57
58 // Query -- always use the default utf8 charset converter.
59 CanonicalizeQuery(source.query, parsed.query, NULL,
60 output, &new_parsed->query);
61
62 return success;
63 }
64
65 } // namespace
66
CanonicalizeMailtoURL(const char * spec,int spec_len,const Parsed & parsed,CanonOutput * output,Parsed * new_parsed)67 bool CanonicalizeMailtoURL(const char* spec,
68 int spec_len,
69 const Parsed& parsed,
70 CanonOutput* output,
71 Parsed* new_parsed) {
72 return DoCanonicalizeMailtoURL<char, unsigned char>(
73 URLComponentSource<char>(spec), parsed, output, new_parsed);
74 }
75
CanonicalizeMailtoURL(const base::char16 * spec,int spec_len,const Parsed & parsed,CanonOutput * output,Parsed * new_parsed)76 bool CanonicalizeMailtoURL(const base::char16* spec,
77 int spec_len,
78 const Parsed& parsed,
79 CanonOutput* output,
80 Parsed* new_parsed) {
81 return DoCanonicalizeMailtoURL<base::char16, base::char16>(
82 URLComponentSource<base::char16>(spec), parsed, output, new_parsed);
83 }
84
ReplaceMailtoURL(const char * base,const Parsed & base_parsed,const Replacements<char> & replacements,CanonOutput * output,Parsed * new_parsed)85 bool ReplaceMailtoURL(const char* base,
86 const Parsed& base_parsed,
87 const Replacements<char>& replacements,
88 CanonOutput* output,
89 Parsed* new_parsed) {
90 URLComponentSource<char> source(base);
91 Parsed parsed(base_parsed);
92 SetupOverrideComponents(base, replacements, &source, &parsed);
93 return DoCanonicalizeMailtoURL<char, unsigned char>(
94 source, parsed, output, new_parsed);
95 }
96
ReplaceMailtoURL(const char * base,const Parsed & base_parsed,const Replacements<base::char16> & replacements,CanonOutput * output,Parsed * new_parsed)97 bool ReplaceMailtoURL(const char* base,
98 const Parsed& base_parsed,
99 const Replacements<base::char16>& replacements,
100 CanonOutput* output,
101 Parsed* new_parsed) {
102 RawCanonOutput<1024> utf8;
103 URLComponentSource<char> source(base);
104 Parsed parsed(base_parsed);
105 SetupUTF16OverrideComponents(base, replacements, &utf8, &source, &parsed);
106 return DoCanonicalizeMailtoURL<char, unsigned char>(
107 source, parsed, output, new_parsed);
108 }
109
110 } // namespace url
111