OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 #include "config.h" | |
6 #include "core/loader/LinkHeader.h" | |
7 | |
8 #include "platform/ParsingUtilities.h" | |
9 | |
10 namespace blink { | |
11 | |
12 // LWSP definition in https://www.ietf.org/rfc/rfc0822.txt | |
13 template <typename CharType> | |
14 static bool isWhitespace(CharType chr) | |
15 { | |
16 return (chr == ' ') || (chr == '\t'); | |
17 } | |
18 | |
19 // Before: | |
20 // | |
21 // <cat.jpg>; rel=preload | |
22 // ^ ^ | |
23 // position end | |
24 // | |
25 // After (if successful: otherwise the method returns false) | |
26 // | |
27 // <cat.jpg>; rel=preload | |
28 // ^ ^ | |
29 // position end | |
30 template <typename CharType> | |
31 static bool parseHeaderStart(CharType*& position, CharType* end) | |
32 { | |
33 skipWhile<CharType, isWhitespace<CharType>>(position, end); | |
34 if (*position != '<') | |
35 return false; | |
Mike West
2015/02/02 13:14:54
I'd prefer `skipExactly` here, rather than hiding
| |
36 skipWhile<CharType, isWhitespace<CharType>>(++position, end); | |
37 return true; | |
38 } | |
39 | |
40 // Before: | |
41 // | |
42 // <cat.jpg>; rel=preload | |
43 // ^ ^ | |
44 // position end | |
45 // | |
46 // After (if successful: otherwise the method returns a null pointer) | |
47 // | |
48 // <cat.jpg>; rel=preload | |
49 // ^ ^ | |
50 // position end | |
51 template <typename CharType> | |
52 static CharType* parseURL(CharType*& position, CharType* end) | |
Mike West
2015/02/02 13:14:54
It's somewhat strange that parsing a URL includes
| |
53 { | |
54 skipUntil<CharType, isWhitespace<CharType>>(position, end, '>'); | |
55 CharType* urlEnd = position; | |
56 skipUntil<CharType>(position, end, '>'); | |
57 if (position == end) | |
58 return nullptr; | |
59 ++position; | |
Mike West
2015/02/02 13:14:54
Prefer `skipExactly` to `++position`. The nice thi
| |
60 return urlEnd; | |
Mike West
2015/02/02 13:14:53
Both SRI and CSP use `String&` out parameters (e.g
| |
61 } | |
62 | |
63 // Before: | |
64 // | |
65 // <cat.jpg>; rel=preload | |
66 // ^ ^ | |
67 // position end | |
68 // | |
69 // After (if successful: otherwise the method returns false, and modifies the is Valid boolean accordingly) | |
70 // | |
71 // <cat.jpg>; rel=preload | |
72 // ^ ^ | |
73 // position end | |
74 template <typename CharType> | |
75 static bool parseParameterDelimiter(CharType*& position, CharType* end, bool& is ValidDelimiter) | |
76 { | |
77 skipWhile<CharType, isWhitespace<CharType>>(position, end); | |
78 if (*position != ';' && position != end) { | |
79 isValidDelimiter = false; | |
Mike West
2015/02/02 13:14:54
You never set this to true. Is that intentional?
| |
80 return false; | |
81 } | |
82 skipWhile<CharType, isWhitespace<CharType>>(++position, end); | |
Mike West
2015/02/02 13:14:54
skipExactly.
| |
83 if (position == end) | |
84 return false; | |
85 return true; | |
86 } | |
87 | |
88 // Before: | |
89 // | |
90 // <cat.jpg>; rel=preload | |
91 // ^ ^ | |
92 // position end | |
93 // | |
94 // After (if successful: otherwise the method returns a null pointer) | |
95 // | |
96 // <cat.jpg>; rel=preload | |
97 // ^ ^ | |
98 // position end | |
99 template <typename CharType> | |
100 static CharType* parseParameterName(CharType*& position, CharType* end) | |
101 { | |
102 skipUntil<CharType, isWhitespace<CharType>>(position, end, '='); | |
Mike West
2015/02/02 13:14:54
What does this mean? I think it means `skipWhile<C
| |
103 CharType* nameEnd = position; | |
104 skipWhile<CharType, isWhitespace<CharType>>(position, end); | |
105 if (*position != '=') | |
106 return nullptr; | |
107 skipWhile<CharType, isWhitespace<CharType>>(++position, end); | |
Mike West
2015/02/02 13:14:53
skipExactly.
| |
108 return nameEnd; | |
109 } | |
110 | |
111 // Before: | |
112 // | |
113 // <cat.jpg>; rel=preload; foo=bar | |
114 // ^ ^ | |
115 // position end | |
116 // | |
117 // After (if successful: otherwise the method returns a null pointer) | |
118 // | |
119 // <cat.jpg>; rel=preload; foo=bar | |
120 // ^ ^ | |
121 // position end | |
122 template <typename CharType> | |
123 static CharType* parseParameterValue(CharType*& position, CharType* end) | |
124 { | |
125 CharType* valueStart = position; | |
126 skipUntil<CharType, isWhitespace<CharType>>(position, end, ';'); | |
Mike West
2015/02/02 13:14:53
Ditto.
| |
127 CharType* valueEnd = position; | |
128 skipWhile<CharType, isWhitespace<CharType>>(position, end); | |
129 if ((valueEnd == valueStart) || (*position != ';' && position != end)) | |
Mike West
2015/02/02 13:14:54
`skipExactly` should take care of this whole claus
| |
130 return nullptr; | |
131 return valueEnd; | |
132 } | |
133 | |
134 template <typename CharType> | |
135 bool LinkHeader::init(CharType* headerValue, unsigned len) | |
136 { | |
137 CharType* position = headerValue; | |
138 CharType* end = headerValue + len; | |
139 | |
140 if (!parseHeaderStart(position, end)) | |
141 return false; | |
142 | |
143 CharType* urlStart = position; | |
144 CharType* urlEnd = parseURL(position, end); | |
145 if (!urlEnd) | |
146 return false; | |
147 m_url = String(urlStart, urlEnd - urlStart); | |
148 | |
149 while (position < end) { | |
150 bool isValidDelimiter = true; | |
151 if (!parseParameterDelimiter(position, end, isValidDelimiter)) | |
152 return isValidDelimiter; | |
153 | |
154 CharType* nameStart = position; | |
155 CharType* nameEnd = parseParameterName(position, end); | |
156 if (!nameEnd) | |
157 return false; | |
158 | |
159 CharType* valueStart = position; | |
160 CharType* valueEnd = parseParameterValue(position, end); | |
161 if (!valueEnd) | |
162 return false; | |
163 | |
164 if (String(nameStart, nameEnd - nameStart) == "rel") | |
Mike West
2015/02/02 13:14:54
Is this hard-coded because 'rel' is the only accep
| |
165 m_rel = String(valueStart, valueEnd - valueStart); | |
166 } | |
167 | |
168 return true; | |
169 } | |
170 | |
171 LinkHeader::LinkHeader(const String& header) | |
172 { | |
173 if (header.isNull()) { | |
174 m_isValid = false; | |
175 return; | |
176 } | |
177 | |
178 if (header.is8Bit()) | |
179 m_isValid = init(header.characters8(), header.length()); | |
180 else | |
181 m_isValid = init(header.characters16(), header.length()); | |
182 } | |
183 | |
184 } | |
OLD | NEW |