1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "url/url_parse.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/basictypes.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "url/url_parse.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Some implementations of base/basictypes.h may define ARRAYSIZE. 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// If it's not defined, we define it to the ARRAYSIZE_UNSAFE macro 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// which is in our version of basictypes.h. 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef ARRAYSIZE 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define ARRAYSIZE ARRAYSIZE_UNSAFE 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Interesting IE file:isms... 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:/foo/bar file:///foo/bar 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The result here seems totally invalid!?!? This isn't UNC. 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:/ 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:// or any other number of slashes 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// IE6 doesn't do anything at all if you click on this link. No error: 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// nothing. IE6's history system seems to always color this link, so I'm 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// guessing that it maps internally to the empty URL. 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// C:\ file:///C:/ 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// / file:///C:/ 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// /foo file:///C:/foo 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Interestingly, IE treats "/" as an alias for "c:\", which makes sense, 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// but is weird to think about on Windows. 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:foo/ file:foo/ (invalid?!?!?) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:/foo/ file:///foo/ (invalid?!?!?) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file://foo/ file://foo/ (UNC to server "foo") 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:///foo/ file:///foo/ (invalid) 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:////foo/ file://foo/ (UNC to server "foo") 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Any more than four slashes is also treated as UNC. 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:C:/ file://C:/ 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file:/C:/ file://C:/ 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The number of slashes after "file:" don't matter if the thing following 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// it looks like an absolute drive path. Also, slashes and backslashes are 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// equally valid here. 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace url { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Used for regular URL parse cases. 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct URLParseCase { 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* input; 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* scheme; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* username; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* password; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* host; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int port; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* path; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* query; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* ref; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Simpler version of URLParseCase for testing path URLs. 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct PathURLParseCase { 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* input; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* scheme; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* path; 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Simpler version of URLParseCase for testing mailto URLs. 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct MailtoURLParseCase { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* input; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* scheme; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* path; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* query; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// More complicated version of URLParseCase for testing filesystem URLs. 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct FileSystemURLParseCase { 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* input; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* inner_scheme; 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* inner_username; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* inner_password; 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* inner_host; 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int inner_port; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* inner_path; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* path; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* query; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* ref; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ComponentMatches(const char* input, 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* reference, 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const Component& component) { 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the component is nonexistant (length == -1), it should begin at 0. 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(component.len >= 0 || component.len == -1); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Begin should be valid. 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_LE(0, component.begin); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // A NULL reference means the component should be nonexistant. 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reference) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return component.len == -1; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (component.len < 0) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; // Reference is not NULL but we don't have anything 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (strlen(reference) != static_cast<size_t>(component.len)) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; // Lengths don't match 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now check the actual characters. 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return strncmp(reference, &input[component.begin], component.len) == 0; 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ExpectInvalidComponent(const Component& component) { 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(0, component.begin); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(-1, component.len); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Parsed ---------------------------------------------------------------------- 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, Length) { 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* length_cases[] = { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // One with everything in it. 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:99/foo?bar#baz", 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // One with nothing in it. 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "", 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Working backwards, let's start taking off stuff from the full one. 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:99/foo?bar#", 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:99/foo?bar", 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:99/foo?", 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:99/foo", 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:99/", 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:99", 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host:", 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user:pass@host", 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://host", 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http://user@", 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "http:", 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < arraysize(length_cases); i++) { 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int true_length = static_cast<int>(strlen(length_cases[i])); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseStandardURL(length_cases[i], true_length, &parsed); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(true_length, parsed.Length()); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, CountCharactersBefore) { 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct CountCase { 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* url; 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Parsed::ComponentType component; 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool include_delimiter; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int expected_count; 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } count_cases[] = { 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Test each possibility in the case where all components are present. 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 0 1 2 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 0123456789012345678901 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::SCHEME, true, 0}, 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::SCHEME, false, 0}, 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::USERNAME, true, 7}, 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::USERNAME, false, 7}, 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::PASSWORD, true, 9}, 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::PASSWORD, false, 9}, 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::HOST, true, 11}, 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::HOST, false, 11}, 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::PORT, true, 12}, 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::PORT, false, 13}, 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::PATH, false, 14}, 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::PATH, true, 14}, 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::QUERY, true, 16}, 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::QUERY, false, 17}, 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::REF, true, 18}, 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q#r", Parsed::REF, false, 19}, 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now test when the requested component is missing. 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?", Parsed::REF, true, 17}, 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p?q", Parsed::REF, true, 18}, 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8/p#r", Parsed::QUERY, true, 16}, 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h:8#r", Parsed::PATH, true, 14}, 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@h/", Parsed::PORT, true, 12}, 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u:p@/", Parsed::HOST, true, 11}, 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This case is a little weird. It will report that the password would 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // start where the host begins. This is arguably correct, although you 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // could also argue that it should start at the '@' sign. Doing it 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // starting with the '@' sign is actually harder, so we don't bother. 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://u@h/", Parsed::PASSWORD, true, 9}, 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://h/", Parsed::USERNAME, true, 7}, 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http:", Parsed::USERNAME, true, 5}, 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"", Parsed::SCHEME, true, 0}, 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure a random component still works when there's nothing there. 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"", Parsed::REF, true, 0}, 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // File URLs are special with no host, so we test those. 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"file:///c:/foo", Parsed::USERNAME, true, 7}, 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"file:///c:/foo", Parsed::PASSWORD, true, 7}, 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"file:///c:/foo", Parsed::HOST, true, 7}, 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"file:///c:/foo", Parsed::PATH, true, 7}, 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE(count_cases); i++) { 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int length = static_cast<int>(strlen(count_cases[i].url)); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Simple test to distinguish file and standard URLs. 2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (length > 0 && count_cases[i].url[0] == 'f') 2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseFileURL(count_cases[i].url, length, &parsed); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseStandardURL(count_cases[i].url, length, &parsed); 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int chars_before = parsed.CountCharactersBefore( 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) count_cases[i].component, count_cases[i].include_delimiter); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(count_cases[i].expected_count, chars_before); 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Standard -------------------------------------------------------------------- 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Input Scheme Usrname Passwd Host Port Path Query Ref 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ------------------------------------ ------- ------- ---------- ------------ --- ---------- ------------ ----- 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static URLParseCase cases[] = { 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Regular URL with all the parts 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://user:pass@foo:21/bar;par?b#c", "http", "user", "pass", "foo", 21, "/bar;par","b", "c"}, 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Known schemes should lean towards authority identification 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http:foo.com", "http", NULL, NULL, "foo.com", -1, NULL, NULL, NULL}, 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Spaces! 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"\t :foo.com \n", "", NULL, NULL, "foo.com", -1, NULL, NULL, NULL}, 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){" foo.com ", NULL, NULL, NULL, "foo.com", -1, NULL, NULL, NULL}, 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"a:\t foo.com", "a", NULL, NULL, "\t foo.com", -1, NULL, NULL, NULL}, 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:21/ b ? d # e ", "http", NULL, NULL, "f", 21, "/ b ", " d ", " e"}, 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Invalid port numbers should be identified and turned into -2, empty port 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // numbers should be -1. Spaces aren't allowed in port numbers 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:/c", "http", NULL, NULL, "f", -1, "/c", NULL, NULL}, 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:0/c", "http", NULL, NULL, "f", 0, "/c", NULL, NULL}, 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:00000000000000/c", "http", NULL, NULL, "f", 0, "/c", NULL, NULL}, 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:00000000000000000000080/c", "http", NULL, NULL, "f", 80, "/c", NULL, NULL}, 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:b/c", "http", NULL, NULL, "f", -2, "/c", NULL, NULL}, 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f: /c", "http", NULL, NULL, "f", -2, "/c", NULL, NULL}, 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:\n/c", "http", NULL, NULL, "f", -2, "/c", NULL, NULL}, 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:fifty-two/c", "http", NULL, NULL, "f", -2, "/c", NULL, NULL}, 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f:999999/c", "http", NULL, NULL, "f", -2, "/c", NULL, NULL}, 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://f: 21 / b ? d # e ", "http", NULL, NULL, "f", -2, "/ b ", " d ", " e"}, 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Creative URLs missing key elements 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"", NULL, NULL, NULL, NULL, -1, NULL, NULL, NULL}, 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){" \t", NULL, NULL, NULL, NULL, -1, NULL, NULL, NULL}, 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":foo.com/", "", NULL, NULL, "foo.com", -1, "/", NULL, NULL}, 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":foo.com\\", "", NULL, NULL, "foo.com", -1, "\\", NULL, NULL}, 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":", "", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":a", "", NULL, NULL, "a", -1, NULL, NULL, NULL}, 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":/", "", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":\\", "", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":#", "", NULL, NULL, NULL, -1, NULL, NULL, ""}, 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"#", NULL, NULL, NULL, NULL, -1, NULL, NULL, ""}, 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"#/", NULL, NULL, NULL, NULL, -1, NULL, NULL, "/"}, 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"#\\", NULL, NULL, NULL, NULL, -1, NULL, NULL, "\\"}, 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"#;?", NULL, NULL, NULL, NULL, -1, NULL, NULL, ";?"}, 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"?", NULL, NULL, NULL, NULL, -1, NULL, "", NULL}, 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"/", NULL, NULL, NULL, NULL, -1, NULL, NULL, NULL}, 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":23", "", NULL, NULL, "23", -1, NULL, NULL, NULL}, 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"/:23", "/", NULL, NULL, "23", -1, NULL, NULL, NULL}, 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"//", NULL, NULL, NULL, NULL, -1, NULL, NULL, NULL}, 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"::", "", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"::23", "", NULL, NULL, NULL, 23, NULL, NULL, NULL}, 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"foo://", "foo", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Username/passwords and things that look like them 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://a:b@c:29/d", "http", "a", "b", "c", 29, "/d", NULL, NULL}, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http::@c:29", "http", "", "", "c", 29, NULL, NULL, NULL}, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ... "]" in the password field isn't allowed, but we tolerate it here... 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://&a:foo(b]c@d:2/", "http", "&a", "foo(b]c", "d", 2, "/", NULL, NULL}, 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://::@c@d:2", "http", "", ":@c", "d", 2, NULL, NULL, NULL}, 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://foo.com:b@d/", "http", "foo.com", "b", "d", -1, "/", NULL, NULL}, 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://foo.com/\\@", "http", NULL, NULL, "foo.com", -1, "/\\@", NULL, NULL}, 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http:\\\\foo.com\\", "http", NULL, NULL, "foo.com", -1, "\\", NULL, NULL}, 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http:\\\\a\\b:c\\d@foo.com\\", "http", NULL, NULL, "a", -1, "\\b:c\\d@foo.com\\", NULL, NULL}, 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tolerate different numbers of slashes. 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"foo:/", "foo", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"foo:/bar.com/", "foo", NULL, NULL, "bar.com", -1, "/", NULL, NULL}, 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"foo://///////", "foo", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"foo://///////bar.com/", "foo", NULL, NULL, "bar.com", -1, "/", NULL, NULL}, 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"foo:////://///", "foo", NULL, NULL, NULL, -1, "/////", NULL, NULL}, 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Raw file paths on Windows aren't handled by the parser. 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"c:/foo", "c", NULL, NULL, "foo", -1, NULL, NULL, NULL}, 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"//foo/bar", NULL, NULL, NULL, "foo", -1, "/bar", NULL, NULL}, 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Use the first question mark for the query and the ref. 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://foo/path;a??e#f#g", "http", NULL, NULL, "foo", -1, "/path;a", "?e", "f#g"}, 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://foo/abcd?efgh?ijkl", "http", NULL, NULL, "foo", -1, "/abcd", "efgh?ijkl", NULL}, 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://foo/abcd#foo?bar", "http", NULL, NULL, "foo", -1, "/abcd", NULL, "foo?bar"}, 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // IPv6, check also interesting uses of colons. 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"[61:24:74]:98", "[61", NULL, NULL, "24:74]", 98, NULL, NULL, NULL}, 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://[61:27]:98", "http", NULL, NULL, "[61:27]", 98, NULL, NULL, NULL}, 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http:[61:27]/:foo", "http", NULL, NULL, "[61:27]", -1, "/:foo", NULL, NULL}, 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://[1::2]:3:4", "http", NULL, NULL, "[1::2]:3", 4, NULL, NULL, NULL}, 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Partially-complete IPv6 literals, and related cases. 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://2001::1", "http", NULL, NULL, "2001:", 1, NULL, NULL, NULL}, 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://[2001::1", "http", NULL, NULL, "[2001::1", -1, NULL, NULL, NULL}, 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://2001::1]", "http", NULL, NULL, "2001::1]", -1, NULL, NULL, NULL}, 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://2001::1]:80", "http", NULL, NULL, "2001::1]", 80, NULL, NULL, NULL}, 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://[2001::1]", "http", NULL, NULL, "[2001::1]", -1, NULL, NULL, NULL}, 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://[2001::1]:80", "http", NULL, NULL, "[2001::1]", 80, NULL, NULL, NULL}, 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"http://[[::]]", "http", NULL, NULL, "[[::]]", -1, NULL, NULL, NULL}, 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, Standard) { 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Declared outside for loop to try to catch cases in init() where we forget 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to reset something that is reset by the constructor. 3210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < arraysize(cases); i++) { 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* url = cases[i].input; 3240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseStandardURL(url, static_cast<int>(strlen(url)), &parsed); 3250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int port = ParsePort(url, parsed.port); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, cases[i].scheme, parsed.scheme)); 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, cases[i].username, parsed.username)); 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, cases[i].password, parsed.password)); 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, cases[i].host, parsed.host)); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(cases[i].port, port); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, cases[i].path, parsed.path)); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, cases[i].query, parsed.query)); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, cases[i].ref, parsed.ref)); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// PathURL -------------------------------------------------------------------- 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Various incarnations of path URLs. 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PathURLParseCase path_cases[] = { 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"", NULL, NULL}, 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":", "", NULL}, 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){":/", "", "/"}, 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"/", NULL, "/"}, 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){" This is \\interesting// \t", NULL, "This is \\interesting// \t"}, 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"about:", "about", NULL}, 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"about:blank", "about", "blank"}, 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){" about: blank ", "about", " blank "}, 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){"javascript :alert(\"He:/l\\l#o?foo\"); ", "javascript ", "alert(\"He:/l\\l#o?foo\"); "}, 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, PathURL) { 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Declared outside for loop to try to catch cases in init() where we forget 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to reset something that is reset by the construtor. 3560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < arraysize(path_cases); i++) { 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* url = path_cases[i].input; 3590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParsePathURL(url, static_cast<int>(strlen(url)), false, &parsed); 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, path_cases[i].scheme, parsed.scheme)) 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << i; 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, path_cases[i].path, parsed.GetContent())) 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << i; 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The remaining components are never used for path urls. 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.username); 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.password); 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.host); 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.port); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Various incarnations of file URLs. 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static URLParseCase file_cases[] = { 376d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#ifdef WIN32 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:server", "file", NULL, NULL, "server", -1, NULL, NULL, NULL}, 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){" file: server \t", "file", NULL, NULL, " server",-1, NULL, NULL, NULL}, 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"FiLe:c|", "FiLe", NULL, NULL, NULL, -1, "c|", NULL, NULL}, 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"FILE:/\\\\/server/file", "FILE", NULL, NULL, "server", -1, "/file", NULL, NULL}, 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file://server/", "file", NULL, NULL, "server", -1, "/", NULL, NULL}, 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file://localhost/c:/", "file", NULL, NULL, NULL, -1, "/c:/", NULL, NULL}, 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file://127.0.0.1/c|\\", "file", NULL, NULL, NULL, -1, "/c|\\", NULL, NULL}, 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:/", "file", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:", "file", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If there is a Windows drive letter, treat any number of slashes as the 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // path part. 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:c:\\fo\\b", "file", NULL, NULL, NULL, -1, "c:\\fo\\b", NULL, NULL}, 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:/c:\\foo/bar", "file", NULL, NULL, NULL, -1, "/c:\\foo/bar",NULL, NULL}, 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file://c:/f\\b", "file", NULL, NULL, NULL, -1, "/c:/f\\b", NULL, NULL}, 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:///C:/foo", "file", NULL, NULL, NULL, -1, "/C:/foo", NULL, NULL}, 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file://///\\/\\/c:\\f\\b", "file", NULL, NULL, NULL, -1, "/c:\\f\\b", NULL, NULL}, 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If there is not a drive letter, we should treat is as UNC EXCEPT for 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // three slashes, which we treat as a Unix style path. 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:server/file", "file", NULL, NULL, "server", -1, "/file", NULL, NULL}, 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:/server/file", "file", NULL, NULL, "server", -1, "/file", NULL, NULL}, 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file://server/file", "file", NULL, NULL, "server", -1, "/file", NULL, NULL}, 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:///server/file", "file", NULL, NULL, NULL, -1, "/server/file",NULL, NULL}, 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file://\\server/file", "file", NULL, NULL, NULL, -1, "\\server/file",NULL, NULL}, 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:////server/file", "file", NULL, NULL, "server", -1, "/file", NULL, NULL}, 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Queries and refs are valid for file URLs as well. 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:///C:/foo.html?#", "file", NULL, NULL, NULL, -1, "/C:/foo.html", "", ""}, 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"file:///C:/foo.html?query=yes#ref", "file", NULL, NULL, NULL, -1, "/C:/foo.html", "query=yes", "ref"}, 404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#else // WIN32 405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // No slashes. 406d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:", "file", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 407d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:path", "file", NULL, NULL, NULL, -1, "path", NULL, NULL}, 408d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:path/", "file", NULL, NULL, NULL, -1, "path/", NULL, NULL}, 409d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:path/f.txt", "file", NULL, NULL, NULL, -1, "path/f.txt", NULL, NULL}, 410d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // One slash. 411d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:/", "file", NULL, NULL, NULL, -1, "/", NULL, NULL}, 412d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:/path", "file", NULL, NULL, NULL, -1, "/path", NULL, NULL}, 413d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:/path/", "file", NULL, NULL, NULL, -1, "/path/", NULL, NULL}, 414d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:/path/f.txt", "file", NULL, NULL, NULL, -1, "/path/f.txt", NULL, NULL}, 415d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Two slashes. 416d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file://", "file", NULL, NULL, NULL, -1, NULL, NULL, NULL}, 417d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file://server", "file", NULL, NULL, "server", -1, NULL, NULL, NULL}, 418d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file://server/", "file", NULL, NULL, "server", -1, "/", NULL, NULL}, 419d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file://server/f.txt", "file", NULL, NULL, "server", -1, "/f.txt", NULL, NULL}, 420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Three slashes. 421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:///", "file", NULL, NULL, NULL, -1, "/", NULL, NULL}, 422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:///path", "file", NULL, NULL, NULL, -1, "/path", NULL, NULL}, 423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:///path/", "file", NULL, NULL, NULL, -1, "/path/", NULL, NULL}, 424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:///path/f.txt", "file", NULL, NULL, NULL, -1, "/path/f.txt", NULL, NULL}, 425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // More than three slashes. 426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:////", "file", NULL, NULL, NULL, -1, "/", NULL, NULL}, 427d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:////path", "file", NULL, NULL, NULL, -1, "/path", NULL, NULL}, 428d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:////path/", "file", NULL, NULL, NULL, -1, "/path/", NULL, NULL}, 429d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:////path/f.txt", "file", NULL, NULL, NULL, -1, "/path/f.txt", NULL, NULL}, 430d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Schemeless URLs 431d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"path/f.txt", NULL, NULL, NULL, NULL, -1, "path/f.txt", NULL, NULL}, 432d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"path:80/f.txt", "path", NULL, NULL, NULL, -1, "80/f.txt", NULL, NULL}, 433d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"path/f.txt:80", "path/f.txt",NULL, NULL, NULL, -1, "80", NULL, NULL}, // Wrong. 434d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"/path/f.txt", NULL, NULL, NULL, NULL, -1, "/path/f.txt", NULL, NULL}, 435d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"/path:80/f.txt", NULL, NULL, NULL, NULL, -1, "/path:80/f.txt",NULL, NULL}, 436d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"/path/f.txt:80", NULL, NULL, NULL, NULL, -1, "/path/f.txt:80",NULL, NULL}, 437d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"//server/f.txt", NULL, NULL, NULL, "server", -1, "/f.txt", NULL, NULL}, 438d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"//server:80/f.txt", NULL, NULL, NULL, "server:80",-1, "/f.txt", NULL, NULL}, 439d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"//server/f.txt:80", NULL, NULL, NULL, "server", -1, "/f.txt:80", NULL, NULL}, 440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"///path/f.txt", NULL, NULL, NULL, NULL, -1, "/path/f.txt", NULL, NULL}, 441d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"///path:80/f.txt", NULL, NULL, NULL, NULL, -1, "/path:80/f.txt",NULL, NULL}, 442d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"///path/f.txt:80", NULL, NULL, NULL, NULL, -1, "/path/f.txt:80",NULL, NULL}, 443d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"////path/f.txt", NULL, NULL, NULL, NULL, -1, "/path/f.txt", NULL, NULL}, 444d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"////path:80/f.txt", NULL, NULL, NULL, NULL, -1, "/path:80/f.txt",NULL, NULL}, 445d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"////path/f.txt:80", NULL, NULL, NULL, NULL, -1, "/path/f.txt:80",NULL, NULL}, 446d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Queries and refs are valid for file URLs as well. 447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:///foo.html?#", "file", NULL, NULL, NULL, -1, "/foo.html", "", ""}, 448d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) {"file:///foo.html?q=y#ref", "file", NULL, NULL, NULL, -1, "/foo.html", "q=y", "ref"}, 449d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif // WIN32 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 452d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST(URLParser, ParseFileURL) { 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Declared outside for loop to try to catch cases in init() where we forget 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to reset something that is reset by the construtor. 4550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 456d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (size_t i = 0; i < arraysize(file_cases); i++) { 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* url = file_cases[i].input; 4580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseFileURL(url, static_cast<int>(strlen(url)), &parsed); 4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int port = ParsePort(url, parsed.port); 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 461d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].scheme, parsed.scheme)) 462d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [" << url << "] " 463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << parsed.scheme.begin << ", " << parsed.scheme.len; 464d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 465d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].username, parsed.username)) 466d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [" << url << "] " 467d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << parsed.username.begin << ", " << parsed.username.len; 468d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 469d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].password, parsed.password)) 470d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [" << url << "] " 471d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << parsed.password.begin << ", " << parsed.password.len; 472d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 473d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].host, parsed.host)) 474d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [" << url << "] " 475d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << parsed.host.begin << ", " << parsed.host.len; 476d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(file_cases[i].port, port) 478d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [ " << url << "] " << port; 479d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 480d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].path, parsed.path)) 481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [" << url << "] " 482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << parsed.path.begin << ", " << parsed.path.len; 483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].query, parsed.query)) 485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [" << url << "] " 486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << parsed.query.begin << ", " << parsed.query.len; 487d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 488d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].ref, parsed.ref)) 489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << " for case #" << i << " [ "<< url << "] " 490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << parsed.query.begin << ", " << parsed.scheme.len; 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, ExtractFileName) { 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct FileCase { 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* input; 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* expected; 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } file_cases[] = { 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com", NULL}, 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/", ""}, 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/search", "search"}, 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/search/", ""}, 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/foo/bar.html?baz=22", "bar.html"}, 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/foo/bar.html#ref", "bar.html"}, 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/search/;param", ""}, 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/foo/bar.html;param#ref", "bar.html"}, 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/foo/bar.html;foo;param#ref", "bar.html;foo"}, 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"http://www.google.com/foo/bar.html?query#ref", "bar.html"}, 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE(file_cases); i++) { 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* url = file_cases[i].input; 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int len = static_cast<int>(strlen(url)); 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 5170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseStandardURL(url, len, &parsed); 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Component file_name; 5200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ExtractFileName(url, parsed.path, &file_name); 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, file_cases[i].expected, file_name)); 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns true if the parameter with index |parameter| in the given URL's 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// query string. The expected key can be NULL to indicate no such key index 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// should exist. The parameter number is 1-based. 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static bool NthParameterIs(const char* url, 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int parameter, 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* expected_key, 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* expected_value) { 5330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 5340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseStandardURL(url, static_cast<int>(strlen(url)), &parsed); 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Component query = parsed.query; 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int i = 1; i <= parameter; i++) { 5390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Component key, value; 5400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!ExtractQueryKeyValue(url, &query, &key, &value)) { 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parameter >= i && !expected_key) 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; // Expected nonexistant key, got one. 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; // Not enough keys. 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (i == parameter) { 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!expected_key) 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (strncmp(&url[key.begin], expected_key, key.len) != 0) 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (strncmp(&url[value.begin], expected_value, value.len) != 0) 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return expected_key == NULL; // We didn't find that many parameters. 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, ExtractQueryKeyValue) { 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs("http://www.google.com", 1, NULL, NULL)); 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Basic case. 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char a[] = "http://www.google.com?arg1=1&arg2=2&bar"; 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(a, 1, "arg1", "1")); 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(a, 2, "arg2", "2")); 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(a, 3, "bar", "")); 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(a, 4, NULL, NULL)); 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Empty param at the end. 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char b[] = "http://www.google.com?foo=bar&"; 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(b, 1, "foo", "bar")); 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(b, 2, NULL, NULL)); 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Empty param at the beginning. 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char c[] = "http://www.google.com?&foo=bar"; 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(c, 1, "", "")); 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(c, 2, "foo", "bar")); 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(c, 3, NULL, NULL)); 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Empty key with value. 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char d[] = "http://www.google.com?=foo"; 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(d, 1, "", "foo")); 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(d, 2, NULL, NULL)); 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Empty value with key. 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char e[] = "http://www.google.com?foo="; 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(e, 1, "foo", "")); 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(e, 2, NULL, NULL)); 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Empty key and values. 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char f[] = "http://www.google.com?&&==&="; 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(f, 1, "", "")); 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(f, 2, "", "")); 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(f, 3, "", "=")); 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(f, 4, "", "")); 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(NthParameterIs(f, 5, NULL, NULL)); 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// MailtoURL -------------------------------------------------------------------- 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static MailtoURLParseCase mailto_cases[] = { 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//|input |scheme |path |query 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:foo@gmail.com", "mailto", "foo@gmail.com", NULL}, 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){" mailto: to \t", "mailto", " to", NULL}, 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:addr1%2C%20addr2 ", "mailto", "addr1%2C%20addr2", NULL}, 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"Mailto:addr1, addr2 ", "Mailto", "addr1, addr2", NULL}, 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:addr1:addr2 ", "mailto", "addr1:addr2", NULL}, 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:?to=addr1,addr2", "mailto", NULL, "to=addr1,addr2"}, 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:?to=addr1%2C%20addr2", "mailto", NULL, "to=addr1%2C%20addr2"}, 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:addr1?to=addr2", "mailto", "addr1", "to=addr2"}, 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:?body=#foobar#", "mailto", NULL, "body=#foobar#",}, 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"mailto:#?body=#foobar#", "mailto", "#", "body=#foobar#"}, 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, MailtoUrl) { 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Declared outside for loop to try to catch cases in init() where we forget 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to reset something that is reset by the construtor. 6190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < arraysize(mailto_cases); ++i) { 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* url = mailto_cases[i].input; 6220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseMailtoURL(url, static_cast<int>(strlen(url)), &parsed); 6230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int port = ParsePort(url, parsed.port); 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].scheme, parsed.scheme)); 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].path, parsed.path)); 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, mailto_cases[i].query, parsed.query)); 6280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(PORT_UNSPECIFIED, port); 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The remaining components are never used for mailto urls. 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.username); 632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.password); 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.port); 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.ref); 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Various incarnations of filesystem URLs. 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static FileSystemURLParseCase filesystem_cases[] = { 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Regular URL with all the parts 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"filesystem:http://user:pass@foo:21/temporary/bar;par?b#c", "http", "user", "pass", "foo", 21, "/temporary", "/bar;par", "b", "c"}, 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"filesystem:https://foo/persistent/bar;par/", "https", NULL, NULL, "foo", -1, "/persistent", "/bar;par/", NULL, NULL}, 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"filesystem:file:///persistent/bar;par/", "file", NULL, NULL, NULL, -1, "/persistent", "/bar;par/", NULL, NULL}, 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"filesystem:file:///persistent/bar;par/?query#ref", "file", NULL, NULL, NULL, -1, "/persistent", "/bar;par/", "query", "ref"}, 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){"filesystem:file:///persistent", "file", NULL, NULL, NULL, -1, "/persistent", "", NULL, NULL}, 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST(URLParser, FileSystemURL) { 649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Declared outside for loop to try to catch cases in init() where we forget 650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to reset something that is reset by the construtor. 6510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Parsed parsed; 652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < arraysize(filesystem_cases); i++) { 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileSystemURLParseCase* parsecase = &filesystem_cases[i]; 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* url = parsecase->input; 6550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ParseFileSystemURL(url, static_cast<int>(strlen(url)), &parsed); 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, "filesystem", parsed.scheme)); 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(!parsecase->inner_scheme, !parsed.inner_parsed()); 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Only check the inner_parsed if there is one. 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (parsed.inner_parsed()) { 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, parsecase->inner_scheme, 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parsed.inner_parsed()->scheme)); 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, parsecase->inner_username, 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parsed.inner_parsed()->username)); 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, parsecase->inner_password, 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parsed.inner_parsed()->password)); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, parsecase->inner_host, 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) parsed.inner_parsed()->host)); 6690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int port = ParsePort(url, parsed.inner_parsed()->port); 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(parsecase->inner_port, port); 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The remaining components are never used for filesystem urls. 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.inner_parsed()->query); 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.inner_parsed()->ref); 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, parsecase->path, parsed.path)); 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, parsecase->query, parsed.query)); 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ComponentMatches(url, parsecase->ref, parsed.ref)); 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The remaining components are never used for filesystem urls. 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.username); 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.password); 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.host); 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExpectInvalidComponent(parsed.port); 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 6900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} // namespace url 691