1 // Copyright (c) 2011 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 "net/ftp/ftp_directory_listing_parser_unittest.h" 6 7 #include "base/format_macros.h" 8 #include "base/string_split.h" 9 #include "base/string_util.h" 10 #include "base/stringprintf.h" 11 #include "base/utf_string_conversions.h" 12 #include "net/ftp/ftp_directory_listing_parser_vms.h" 13 14 namespace net { 15 16 namespace { 17 18 typedef FtpDirectoryListingParserTest FtpDirectoryListingParserVmsTest; 19 20 TEST_F(FtpDirectoryListingParserVmsTest, Good) { 21 const struct SingleLineTestData good_cases[] = { 22 { "README.TXT;4 2 18-APR-2000 10:40:39.90", 23 FtpDirectoryListingEntry::FILE, "readme.txt", 1024, 24 2000, 4, 18, 10, 40 }, 25 { ".WELCOME;1 2 13-FEB-2002 23:32:40.47", 26 FtpDirectoryListingEntry::FILE, ".welcome", 1024, 27 2002, 2, 13, 23, 32 }, 28 { "FILE.;1 2 13-FEB-2002 23:32:40.47", 29 FtpDirectoryListingEntry::FILE, "file.", 1024, 30 2002, 2, 13, 23, 32 }, 31 { "EXAMPLE.TXT;1 1 4-NOV-2009 06:02 [JOHNDOE] (RWED,RWED,,)", 32 FtpDirectoryListingEntry::FILE, "example.txt", 512, 33 2009, 11, 4, 6, 2 }, 34 { "ANNOUNCE.TXT;2 1/16 12-MAR-2005 08:44:57 [SYSTEM] (RWED,RWED,RE,RE)", 35 FtpDirectoryListingEntry::FILE, "announce.txt", 512, 36 2005, 3, 12, 8, 44 }, 37 { "TEST.DIR;1 1 4-MAR-1999 22:14:34 [UCX$NOBO,ANONYMOUS] (RWE,RWE,RWE,RWE)", 38 FtpDirectoryListingEntry::DIRECTORY, "test", -1, 39 1999, 3, 4, 22, 14 }, 40 { "ANNOUNCE.TXT;2 1 12-MAR-2005 08:44:57 [X] (,,,)", 41 FtpDirectoryListingEntry::FILE, "announce.txt", 512, 42 2005, 3, 12, 8, 44 }, 43 { "ANNOUNCE.TXT;2 1 12-MAR-2005 08:44:57 [X] (R,RW,RWD,RE)", 44 FtpDirectoryListingEntry::FILE, "announce.txt", 512, 45 2005, 3, 12, 8, 44 }, 46 { "ANNOUNCE.TXT;2 1 12-MAR-2005 08:44:57 [X] (ED,RED,WD,WED)", 47 FtpDirectoryListingEntry::FILE, "announce.txt", 512, 48 2005, 3, 12, 8, 44 }, 49 }; 50 for (size_t i = 0; i < arraysize(good_cases); i++) { 51 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, 52 good_cases[i].input)); 53 54 std::vector<string16> lines(GetSingleLineTestCase(good_cases[i].input)); 55 56 // The parser requires a directory header before accepting regular input. 57 lines.insert(lines.begin(), 58 ASCIIToUTF16("Directory ANONYMOUS_ROOT:[000000]")); 59 60 // A valid listing must also have a "Total" line at the end. 61 lines.insert(lines.end(), 62 ASCIIToUTF16("Total of 1 file, 2 blocks.")); 63 64 std::vector<FtpDirectoryListingEntry> entries; 65 EXPECT_TRUE(ParseFtpDirectoryListingVms(lines, 66 &entries)); 67 VerifySingleLineTestCase(good_cases[i], entries); 68 } 69 } 70 71 TEST_F(FtpDirectoryListingParserVmsTest, Bad) { 72 const char* bad_cases[] = { 73 "garbage", 74 75 // Missing file version number. 76 "README.TXT 2 18-APR-2000 10:40:39", 77 78 // Missing extension. 79 "README;1 2 18-APR-2000 10:40:39", 80 81 // Malformed file size. 82 "README.TXT;1 garbage 18-APR-2000 10:40:39", 83 "README.TXT;1 -2 18-APR-2000 10:40:39", 84 85 // Malformed date. 86 "README.TXT;1 2 APR-2000 10:40:39", 87 "README.TXT;1 2 -18-APR-2000 10:40:39", 88 "README.TXT;1 2 18-APR 10:40:39", 89 "README.TXT;1 2 18-APR-2000 10", 90 "README.TXT;1 2 18-APR-2000 10:40.25", 91 "README.TXT;1 2 18-APR-2000 10:40.25.25", 92 93 // Malformed security information. 94 "X.TXT;2 1 12-MAR-2005 08:44:57 (RWED,RWED,RE,RE)", 95 "X.TXT;2 1 12-MAR-2005 08:44:57 [SYSTEM]", 96 "X.TXT;2 1 12-MAR-2005 08:44:57 (SYSTEM) (RWED,RWED,RE,RE)", 97 "X.TXT;2 1 12-MAR-2005 08:44:57 [SYSTEM] [RWED,RWED,RE,RE]", 98 "X.TXT;2 1 12-MAR-2005 08:44:57 [X] (RWED)", 99 "X.TXT;2 1 12-MAR-2005 08:44:57 [X] (RWED,RWED,RE,RE,RE)", 100 "X.TXT;2 1 12-MAR-2005 08:44:57 [X] (RWED,RWEDRWED,RE,RE)", 101 "X.TXT;2 1 12-MAR-2005 08:44:57 [X] (RWED,DEWR,RE,RE)", 102 "X.TXT;2 1 12-MAR-2005 08:44:57 [X] (RWED,RWED,Q,RE)", 103 "X.TXT;2 1 12-MAR-2005 08:44:57 [X] (RWED,RRWWEEDD,RE,RE)", 104 }; 105 for (size_t i = 0; i < arraysize(bad_cases); i++) { 106 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, bad_cases[i])); 107 108 std::vector<string16> lines(GetSingleLineTestCase(bad_cases[i])); 109 110 // The parser requires a directory header before accepting regular input. 111 lines.insert(lines.begin(), 112 ASCIIToUTF16("Directory ANONYMOUS_ROOT:[000000]")); 113 114 // A valid listing must also have a "Total" line at the end. 115 lines.insert(lines.end(), 116 ASCIIToUTF16("Total of 1 file, 2 blocks.")); 117 118 std::vector<FtpDirectoryListingEntry> entries; 119 EXPECT_FALSE(ParseFtpDirectoryListingVms(lines, 120 &entries)); 121 } 122 } 123 124 TEST_F(FtpDirectoryListingParserVmsTest, BadDataAfterFooter) { 125 const char* bad_cases[] = { 126 "garbage", 127 "Total of 1 file, 2 blocks.", 128 "Directory ANYNYMOUS_ROOT:[000000]", 129 }; 130 for (size_t i = 0; i < arraysize(bad_cases); i++) { 131 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i, bad_cases[i])); 132 133 std::vector<string16> lines( 134 GetSingleLineTestCase("README.TXT;4 2 18-APR-2000 10:40:39.90")); 135 136 // The parser requires a directory header before accepting regular input. 137 lines.insert(lines.begin(), 138 ASCIIToUTF16("Directory ANONYMOUS_ROOT:[000000]")); 139 140 // A valid listing must also have a "Total" line at the end. 141 lines.insert(lines.end(), 142 ASCIIToUTF16("Total of 1 file, 2 blocks.")); 143 144 { 145 // Make sure the listing is valid before we add data after footer. 146 std::vector<FtpDirectoryListingEntry> entries; 147 EXPECT_TRUE(ParseFtpDirectoryListingVms(lines, 148 &entries)); 149 } 150 151 { 152 // Insert a line at the end of the listing that should make it invalid. 153 lines.insert(lines.end(), 154 ASCIIToUTF16(bad_cases[i])); 155 std::vector<FtpDirectoryListingEntry> entries; 156 EXPECT_FALSE(ParseFtpDirectoryListingVms(lines, 157 &entries)); 158 } 159 } 160 } 161 162 } // namespace 163 164 } // namespace net 165