Home | History | Annotate | Download | only in ftp
      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/strings/string_util.h"
      9 #include "base/strings/stringprintf.h"
     10 #include "net/ftp/ftp_directory_listing_parser_ls.h"
     11 
     12 namespace net {
     13 
     14 namespace {
     15 
     16 typedef FtpDirectoryListingParserTest FtpDirectoryListingParserLsTest;
     17 
     18 TEST_F(FtpDirectoryListingParserLsTest, Good) {
     19   const struct SingleLineTestData good_cases[] = {
     20     { "-rw-r--r--    1 ftp      ftp           528 Nov 01  2007 README",
     21       FtpDirectoryListingEntry::FILE, "README", 528,
     22       2007, 11, 1, 0, 0 },
     23     { "drwxr-xr-x    3 ftp      ftp          4096 May 15 18:11 directory",
     24       FtpDirectoryListingEntry::DIRECTORY, "directory", -1,
     25       1994, 5, 15, 18, 11 },
     26     { "lrwxrwxrwx 1 0  0 26 Sep 18 2008 pub -> vol/1/.CLUSTER/var_ftp/pub",
     27       FtpDirectoryListingEntry::SYMLINK, "pub", -1,
     28       2008, 9, 18, 0, 0 },
     29     { "lrwxrwxrwx 1 0  0 3 Oct 12 13:37 mirror -> pub",
     30       FtpDirectoryListingEntry::SYMLINK, "mirror", -1,
     31       1994, 10, 12, 13, 37 },
     32     { "drwxrwsr-x    4 501      501          4096 Feb 20  2007 pub",
     33       FtpDirectoryListingEntry::DIRECTORY, "pub", -1,
     34       2007, 2, 20, 0, 0 },
     35     { "drwxr-xr-x   4 (?)      (?)          4096 Apr  8  2007 jigdo",
     36       FtpDirectoryListingEntry::DIRECTORY, "jigdo", -1,
     37       2007, 4, 8, 0, 0 },
     38     { "drwx-wx-wt  2 root  wheel  512 Jul  1 02:15 incoming",
     39       FtpDirectoryListingEntry::DIRECTORY, "incoming", -1,
     40       1994, 7, 1, 2, 15 },
     41     { "-rw-r--r-- 1 2 3 3447432 May 18  2009 Foo - Manual.pdf",
     42       FtpDirectoryListingEntry::FILE, "Foo - Manual.pdf", 3447432,
     43       2009, 5, 18, 0, 0 },
     44     { "d-wx-wx-wt+  4 ftp      989          512 Dec  8 15:54 incoming",
     45       FtpDirectoryListingEntry::DIRECTORY, "incoming", -1,
     46       1993, 12, 8, 15, 54 },
     47     { "drwxrwxrwx   1 owner    group               1024 Sep 13  0:30 audio",
     48       FtpDirectoryListingEntry::DIRECTORY, "audio", -1,
     49       1994, 9, 13, 0, 30 },
     50     { "lrwxrwxrwx 1 0  0 26 Sep 18 2008 pub",
     51       FtpDirectoryListingEntry::SYMLINK, "pub", -1,
     52       2008, 9, 18, 0, 0 },
     53     { "-rw-r--r--    1 ftp      ftp           -528 Nov 01  2007 README",
     54       FtpDirectoryListingEntry::FILE, "README", -1,
     55       2007, 11, 1, 0, 0 },
     56 
     57     // Tests for the wu-ftpd variant:
     58     { "drwxr-xr-x   2 sys          512 Mar 27  2009 pub",
     59       FtpDirectoryListingEntry::DIRECTORY, "pub", -1,
     60       2009, 3, 27, 0, 0 },
     61     { "lrwxrwxrwx 0  0 26 Sep 18 2008 pub -> vol/1/.CLUSTER/var_ftp/pub",
     62       FtpDirectoryListingEntry::SYMLINK, "pub", -1,
     63       2008, 9, 18, 0, 0 },
     64     { "drwxr-xr-x   (?)      (?)          4096 Apr  8  2007 jigdo",
     65       FtpDirectoryListingEntry::DIRECTORY, "jigdo", -1,
     66       2007, 4, 8, 0, 0 },
     67     { "-rw-r--r-- 2 3 3447432 May 18  2009 Foo - Manual.pdf",
     68       FtpDirectoryListingEntry::FILE, "Foo - Manual.pdf", 3447432,
     69       2009, 5, 18, 0, 0 },
     70 
     71     // Tests for "ls -l" style listings sent by an OS/2 server (FtpServer):
     72     { "-r--r--r--  1 ftp      -A---       13274 Mar  1  2006 UpTime.exe",
     73       FtpDirectoryListingEntry::FILE, "UpTime.exe", 13274,
     74       2006, 3, 1, 0, 0 },
     75     { "dr--r--r--  1 ftp      -----           0 Nov 17 17:08 kernels",
     76       FtpDirectoryListingEntry::DIRECTORY, "kernels", -1,
     77       1993, 11, 17, 17, 8 },
     78 
     79     // Tests for "ls -l" style listing sent by Xplain FTP Server.
     80     { "drwxr-xr-x               folder        0 Jul 17  2006 online",
     81       FtpDirectoryListingEntry::DIRECTORY, "online", -1,
     82       2006, 7, 17, 0, 0 },
     83 
     84     // Tests for "ls -l" style listing with owning group name
     85     // not separated from file size (http://crbug.com/58963).
     86     { "-rw-r--r-- 1 ftpadmin ftpadmin125435904 Apr  9  2008 .pureftpd-upload",
     87       FtpDirectoryListingEntry::FILE, ".pureftpd-upload", 0,
     88       2008, 4, 9, 0, 0 },
     89 
     90     // Tests for "ls -l" style listing with number of links
     91     // not separated from permission listing (http://crbug.com/70394).
     92     { "drwxr-xr-x1732 266      111        90112 Jun 21  2001 .rda_2",
     93       FtpDirectoryListingEntry::DIRECTORY, ".rda_2", -1,
     94       2001, 6, 21, 0, 0 },
     95 
     96     // Tests for "ls -l" style listing with group name containing spaces.
     97     { "drwxrwxr-x   3 %%%%     Domain Users     4096 Dec  9  2009 %%%%%",
     98       FtpDirectoryListingEntry::DIRECTORY, "%%%%%", -1,
     99       2009, 12, 9, 0, 0 },
    100 
    101     // Tests for "ls -l" style listing in Russian locale (note the swapped
    102     // parts order: the day of month is the first, before month).
    103     { "-rwxrwxr-x 1 ftp ftp 123 23 \xd0\xbc\xd0\xb0\xd0\xb9 2011 test",
    104       FtpDirectoryListingEntry::FILE, "test", 123,
    105       2011, 5, 23, 0, 0 },
    106     { "drwxrwxr-x 1 ftp ftp 4096 19 \xd0\xbe\xd0\xba\xd1\x82 2011 dir",
    107       FtpDirectoryListingEntry::DIRECTORY, "dir", -1,
    108       2011, 10, 19, 0, 0 },
    109 
    110     // Plan9 sends entry type "a" for append-only files.
    111     { "ar-xr-xr-x   2 none     none         512 Apr 26 17:52 plan9",
    112       FtpDirectoryListingEntry::FILE, "plan9", 512,
    113       1994, 4, 26, 17, 52 },
    114 
    115     // Hylafax sends a shorter permission listing.
    116     { "drwxrwx   2       10     4096 Jul 28 02:41 tmp",
    117       FtpDirectoryListingEntry::DIRECTORY, "tmp", -1,
    118       1994, 7, 28, 2, 41 },
    119 
    120     // Completely different date format (YYYY-MM-DD).
    121     { "drwxrwxrwx 2 root root  4096 2012-02-07 00:31 notas_servico",
    122       FtpDirectoryListingEntry::DIRECTORY, "notas_servico", -1,
    123       2012, 2, 7, 0, 31 },
    124     { "-rwxrwxrwx 2 root root  4096 2012-02-07 00:31 notas_servico",
    125       FtpDirectoryListingEntry::FILE, "notas_servico", 4096,
    126       2012, 2, 7, 0, 31 },
    127 
    128     // Weird permission bits.
    129     { "drwx--l---   2 0        10           512 Dec 22  1994 swetzel",
    130       FtpDirectoryListingEntry::DIRECTORY, "swetzel", -1,
    131       1994, 12, 22, 0, 0 },
    132 
    133     { "drwxrwxr-x   1 500     244         660 Jan  1 00:0 bin",
    134       FtpDirectoryListingEntry::DIRECTORY, "bin", -1,
    135       1994, 1, 1, 0, 0 },
    136 
    137     // Garbage in date (but still parseable).
    138     { "lrw-rw-rw-   1 user     group         542 "
    139       "/t11/member/incomingFeb  8  2007 "
    140       "Shortcut to incoming.lnk -> /t11/member/incoming",
    141       FtpDirectoryListingEntry::SYMLINK, "Shortcut to incoming.lnk", -1,
    142       2007, 2, 8, 0, 0 },
    143 
    144     // Garbage in permissions (with no effect on other bits).
    145     // Also test multiple "columns" resulting from the garbage.
    146     { "garbage    1 ftp      ftp           528 Nov 01  2007 README",
    147       FtpDirectoryListingEntry::FILE, "README", 528,
    148       2007, 11, 1, 0, 0 },
    149     { "gar bage    1 ftp      ftp           528 Nov 01  2007 README",
    150       FtpDirectoryListingEntry::FILE, "README", 528,
    151       2007, 11, 1, 0, 0 },
    152     { "g a r b a g e    1 ftp      ftp           528 Nov 01  2007 README",
    153       FtpDirectoryListingEntry::FILE, "README", 528,
    154       2007, 11, 1, 0, 0 },
    155   };
    156   for (size_t i = 0; i < arraysize(good_cases); i++) {
    157     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
    158                                     good_cases[i].input));
    159 
    160     std::vector<FtpDirectoryListingEntry> entries;
    161     EXPECT_TRUE(ParseFtpDirectoryListingLs(
    162         GetSingleLineTestCase(good_cases[i].input),
    163         GetMockCurrentTime(),
    164         &entries));
    165     VerifySingleLineTestCase(good_cases[i], entries);
    166   }
    167 }
    168 
    169 TEST_F(FtpDirectoryListingParserLsTest, Ignored) {
    170   const char* ignored_cases[] = {
    171     "drwxr-xr-x 2 0 0 4096 Mar 18  2007  ",  // http://crbug.com/60065
    172 
    173     "ftpd: .: Permission denied",
    174     "ftpd-BSD: .: Permission denied",
    175     "ls: .: EDC5111I Permission denied.",
    176 
    177     // Tests important for security: verify that after we detect the column
    178     // offset we don't try to access invalid memory on malformed input.
    179     "drwxr-xr-x 3 ftp ftp 4096 May 15 18:11",
    180     "drwxr-xr-x 3 ftp     4096 May 15 18:11",
    181     "drwxr-xr-x   folder     0 May 15 18:11",
    182   };
    183   for (size_t i = 0; i < arraysize(ignored_cases); i++) {
    184     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
    185                                     ignored_cases[i]));
    186 
    187     std::vector<FtpDirectoryListingEntry> entries;
    188     EXPECT_TRUE(ParseFtpDirectoryListingLs(
    189                     GetSingleLineTestCase(ignored_cases[i]),
    190                     GetMockCurrentTime(),
    191                     &entries));
    192     EXPECT_EQ(0U, entries.size());
    193   }
    194 }
    195 
    196 TEST_F(FtpDirectoryListingParserLsTest, Bad) {
    197   const char* bad_cases[] = {
    198     " foo",
    199     "garbage",
    200     "-rw-r--r-- ftp ftp",
    201     "-rw-r--r-- ftp ftp 528 Foo 01 2007 README",
    202     "-rw-r--r-- 1 ftp ftp",
    203     "-rw-r--r-- 1 ftp ftp 528 Foo 01 2007 README",
    204 
    205     // Invalid month value (30).
    206     "drwxrwxrwx 2 root root  4096 2012-30-07 00:31 notas_servico",
    207   };
    208   for (size_t i = 0; i < arraysize(bad_cases); i++) {
    209     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
    210                                     bad_cases[i]));
    211 
    212     std::vector<FtpDirectoryListingEntry> entries;
    213     EXPECT_FALSE(ParseFtpDirectoryListingLs(GetSingleLineTestCase(bad_cases[i]),
    214                                             GetMockCurrentTime(),
    215                                             &entries));
    216   }
    217 }
    218 
    219 }  // namespace
    220 
    221 }  // namespace net
    222