OLD | NEW |
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 // Portions of this code based on Mozilla: | 5 // Portions of this code based on Mozilla: |
6 // (netwerk/cookie/src/nsCookieService.cpp) | 6 // (netwerk/cookie/src/nsCookieService.cpp) |
7 /* ***** BEGIN LICENSE BLOCK ***** | 7 /* ***** BEGIN LICENSE BLOCK ***** |
8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
9 * | 9 * |
10 * The contents of this file are subject to the Mozilla Public License Version | 10 * The contents of this file are subject to the Mozilla Public License Version |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 if (!valid_octet) | 117 if (!valid_octet) |
118 return false; | 118 return false; |
119 } | 119 } |
120 return true; | 120 return true; |
121 } | 121 } |
122 | 122 |
123 bool IsControlCharacter(unsigned char c) { | 123 bool IsControlCharacter(unsigned char c) { |
124 return c <= 31; | 124 return c <= 31; |
125 } | 125 } |
126 | 126 |
127 bool IsValidCookieAttributeValue(const std::string& value) { | |
128 // The greatest common denominator of cookie attribute values is | |
129 // <any CHAR except CTLs or ";"> according to RFC 6265. | |
130 for (std::string::const_iterator i = value.begin(); i != value.end(); ++i) { | |
131 if (IsControlCharacter(*i) || *i == ';') | |
132 return false; | |
133 } | |
134 return true; | |
135 } | |
136 | |
137 } // namespace | 127 } // namespace |
138 | 128 |
139 namespace net { | 129 namespace net { |
140 | 130 |
141 ParsedCookie::ParsedCookie(const std::string& cookie_line) | 131 ParsedCookie::ParsedCookie(const std::string& cookie_line) |
142 : path_index_(0), | 132 : path_index_(0), |
143 domain_index_(0), | 133 domain_index_(0), |
144 expires_index_(0), | 134 expires_index_(0), |
145 maxage_index_(0), | 135 maxage_index_(0), |
146 secure_index_(0), | 136 secure_index_(0), |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 out.append("; "); | 223 out.append("; "); |
234 out.append(it->first); | 224 out.append(it->first); |
235 if (it->first != kSecureTokenName && it->first != kHttpOnlyTokenName) { | 225 if (it->first != kSecureTokenName && it->first != kHttpOnlyTokenName) { |
236 out.append("="); | 226 out.append("="); |
237 out.append(it->second); | 227 out.append(it->second); |
238 } | 228 } |
239 } | 229 } |
240 return out; | 230 return out; |
241 } | 231 } |
242 | 232 |
| 233 // static |
243 std::string::const_iterator ParsedCookie::FindFirstTerminator( | 234 std::string::const_iterator ParsedCookie::FindFirstTerminator( |
244 const std::string& s) { | 235 const std::string& s) { |
245 std::string::const_iterator end = s.end(); | 236 std::string::const_iterator end = s.end(); |
246 size_t term_pos = s.find_first_of(std::string(kTerminator, kTerminatorLen)); | 237 size_t term_pos = s.find_first_of(std::string(kTerminator, kTerminatorLen)); |
247 if (term_pos != std::string::npos) { | 238 if (term_pos != std::string::npos) { |
248 // We found a character we should treat as an end of string. | 239 // We found a character we should treat as an end of string. |
249 end = s.begin() + term_pos; | 240 end = s.begin() + term_pos; |
250 } | 241 } |
251 return end; | 242 return end; |
252 } | 243 } |
253 | 244 |
| 245 // static |
254 bool ParsedCookie::ParseToken(std::string::const_iterator* it, | 246 bool ParsedCookie::ParseToken(std::string::const_iterator* it, |
255 const std::string::const_iterator& end, | 247 const std::string::const_iterator& end, |
256 std::string::const_iterator* token_start, | 248 std::string::const_iterator* token_start, |
257 std::string::const_iterator* token_end) { | 249 std::string::const_iterator* token_end) { |
258 DCHECK(it && token_start && token_end); | 250 DCHECK(it && token_start && token_end); |
259 std::string::const_iterator token_real_end; | 251 std::string::const_iterator token_real_end; |
260 | 252 |
261 // Seek past any whitespace before the "token" (the name). | 253 // Seek past any whitespace before the "token" (the name). |
262 // token_start should point at the first character in the token | 254 // token_start should point at the first character in the token |
263 if (SeekPast(it, end, kWhitespace)) | 255 if (SeekPast(it, end, kWhitespace)) |
(...skipping 16 matching lines...) Expand all Loading... |
280 // Point after it. | 272 // Point after it. |
281 ++(*it); | 273 ++(*it); |
282 } | 274 } |
283 *token_end = *it; | 275 *token_end = *it; |
284 | 276 |
285 // Seek us back to the end of the token. | 277 // Seek us back to the end of the token. |
286 *it = token_real_end; | 278 *it = token_real_end; |
287 return true; | 279 return true; |
288 } | 280 } |
289 | 281 |
| 282 // static |
290 void ParsedCookie::ParseValue(std::string::const_iterator* it, | 283 void ParsedCookie::ParseValue(std::string::const_iterator* it, |
291 const std::string::const_iterator& end, | 284 const std::string::const_iterator& end, |
292 std::string::const_iterator* value_start, | 285 std::string::const_iterator* value_start, |
293 std::string::const_iterator* value_end) { | 286 std::string::const_iterator* value_end) { |
294 DCHECK(it && value_start && value_end); | 287 DCHECK(it && value_start && value_end); |
295 | 288 |
296 // Seek past any whitespace that might in-between the token and value. | 289 // Seek past any whitespace that might in-between the token and value. |
297 SeekPast(it, end, kWhitespace); | 290 SeekPast(it, end, kWhitespace); |
298 // value_start should point at the first character of the value. | 291 // value_start should point at the first character of the value. |
299 *value_start = *it; | 292 *value_start = *it; |
300 | 293 |
301 // Just look for ';' to terminate ('=' allowed). | 294 // Just look for ';' to terminate ('=' allowed). |
302 // We can hit the end, maybe they didn't terminate. | 295 // We can hit the end, maybe they didn't terminate. |
303 SeekTo(it, end, kValueSeparator); | 296 SeekTo(it, end, kValueSeparator); |
304 | 297 |
305 // Will be pointed at the ; seperator or the end. | 298 // Will be pointed at the ; seperator or the end. |
306 *value_end = *it; | 299 *value_end = *it; |
307 | 300 |
308 // Ignore any unwanted whitespace after the value. | 301 // Ignore any unwanted whitespace after the value. |
309 if (*value_end != *value_start) { // Could have an empty value | 302 if (*value_end != *value_start) { // Could have an empty value |
310 --(*value_end); | 303 --(*value_end); |
311 SeekBackPast(value_end, *value_start, kWhitespace); | 304 SeekBackPast(value_end, *value_start, kWhitespace); |
312 ++(*value_end); | 305 ++(*value_end); |
313 } | 306 } |
314 } | 307 } |
315 | 308 |
| 309 // static |
316 std::string ParsedCookie::ParseTokenString(const std::string& token) { | 310 std::string ParsedCookie::ParseTokenString(const std::string& token) { |
317 std::string::const_iterator it = token.begin(); | 311 std::string::const_iterator it = token.begin(); |
318 std::string::const_iterator end = FindFirstTerminator(token); | 312 std::string::const_iterator end = FindFirstTerminator(token); |
319 | 313 |
320 std::string::const_iterator token_start, token_end; | 314 std::string::const_iterator token_start, token_end; |
321 if (ParseToken(&it, end, &token_start, &token_end)) | 315 if (ParseToken(&it, end, &token_start, &token_end)) |
322 return std::string(token_start, token_end); | 316 return std::string(token_start, token_end); |
323 return std::string(); | 317 return std::string(); |
324 } | 318 } |
325 | 319 |
| 320 // static |
326 std::string ParsedCookie::ParseValueString(const std::string& value) { | 321 std::string ParsedCookie::ParseValueString(const std::string& value) { |
327 std::string::const_iterator it = value.begin(); | 322 std::string::const_iterator it = value.begin(); |
328 std::string::const_iterator end = FindFirstTerminator(value); | 323 std::string::const_iterator end = FindFirstTerminator(value); |
329 | 324 |
330 std::string::const_iterator value_start, value_end; | 325 std::string::const_iterator value_start, value_end; |
331 ParseValue(&it, end, &value_start, &value_end); | 326 ParseValue(&it, end, &value_start, &value_end); |
332 return std::string(value_start, value_end); | 327 return std::string(value_start, value_end); |
333 } | 328 } |
334 | 329 |
| 330 // static |
| 331 bool ParsedCookie::IsValidCookieAttributeValue(const std::string& value) { |
| 332 // The greatest common denominator of cookie attribute values is |
| 333 // <any CHAR except CTLs or ";"> according to RFC 6265. |
| 334 for (std::string::const_iterator i = value.begin(); i != value.end(); ++i) { |
| 335 if (IsControlCharacter(*i) || *i == ';') |
| 336 return false; |
| 337 } |
| 338 return true; |
| 339 } |
| 340 |
335 // Parse all token/value pairs and populate pairs_. | 341 // Parse all token/value pairs and populate pairs_. |
336 void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { | 342 void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { |
337 pairs_.clear(); | 343 pairs_.clear(); |
338 | 344 |
339 // Ok, here we go. We should be expecting to be starting somewhere | 345 // Ok, here we go. We should be expecting to be starting somewhere |
340 // before the cookie line, not including any header name... | 346 // before the cookie line, not including any header name... |
341 std::string::const_iterator start = cookie_line.begin(); | 347 std::string::const_iterator start = cookie_line.begin(); |
342 std::string::const_iterator it = start; | 348 std::string::const_iterator it = start; |
343 | 349 |
344 // TODO(erikwright): Make sure we're stripping \r\n in the network code. | 350 // TODO(erikwright): Make sure we're stripping \r\n in the network code. |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 --*indexes[i]; | 505 --*indexes[i]; |
500 } | 506 } |
501 pairs_.erase(pairs_.begin() + index); | 507 pairs_.erase(pairs_.begin() + index); |
502 } | 508 } |
503 | 509 |
504 bool ParsedCookie::IsSameSiteAttributeValid() const { | 510 bool ParsedCookie::IsSameSiteAttributeValid() const { |
505 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; | 511 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; |
506 } | 512 } |
507 | 513 |
508 } // namespace net | 514 } // namespace net |
OLD | NEW |