diff options
-rw-r--r-- | base/time.cc | 16 | ||||
-rw-r--r-- | base/time.h | 5 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_windows.cc | 13 | ||||
-rw-r--r-- | net/ftp/ftp_directory_listing_parser_windows_unittest.cc | 11 |
4 files changed, 42 insertions, 3 deletions
diff --git a/base/time.cc b/base/time.cc index 2c40d21..a274056 100644 --- a/base/time.cc +++ b/base/time.cc @@ -105,4 +105,20 @@ bool Time::FromString(const wchar_t* time_string, Time* parsed_time) { return true; } +// Time::Exploded ------------------------------------------------------------- + +inline bool is_in_range(int value, int lo, int hi) { + return lo <= value && value <= hi; +} + +bool Time::Exploded::HasValidValues() const { + return is_in_range(month, 1, 12) && + is_in_range(day_of_week, 0, 6) && + is_in_range(day_of_month, 1, 31) && + is_in_range(hour, 0, 23) && + is_in_range(minute, 0, 59) && + is_in_range(second, 0, 60) && + is_in_range(millisecond, 0, 999); +} + } // namespace base diff --git a/base/time.h b/base/time.h index 8d92e75..e885593 100644 --- a/base/time.h +++ b/base/time.h @@ -214,6 +214,11 @@ class Time { int second; // Second within the current minute (0-59 plus leap // seconds which may take it up to 60). int millisecond; // Milliseconds within the current second (0-999) + + // A cursory test for whether the data members are within their + // respective ranges. A 'true' return value does not guarantee the + // Exploded value can be successfully converted to a Time value. + bool HasValidValues() const; }; // Contains the NULL time. Use Time::Now() to get the current time. diff --git a/net/ftp/ftp_directory_listing_parser_windows.cc b/net/ftp/ftp_directory_listing_parser_windows.cc index 85ae6d5..890ffc5 100644 --- a/net/ftp/ftp_directory_listing_parser_windows.cc +++ b/net/ftp/ftp_directory_listing_parser_windows.cc @@ -48,11 +48,18 @@ bool WindowsDateListingToTime(const std::vector<string16>& columns, return false; if (!StringToInt(time_parts[1], &time_exploded.minute)) return false; + if (!time_exploded.HasValidValues()) + return false; string16 am_or_pm(columns[1].substr(5, 2)); - if (EqualsASCII(am_or_pm, "PM")) - time_exploded.hour += 12; - else if (!EqualsASCII(am_or_pm, "AM")) + if (EqualsASCII(am_or_pm, "PM")) { + if (time_exploded.hour < 12) + time_exploded.hour += 12; + } else if (EqualsASCII(am_or_pm, "AM")) { + if (time_exploded.hour == 12) + time_exploded.hour = 0; + } else { return false; + } // We don't know the time zone of the server, so just use local time. *time = base::Time::FromLocalExploded(time_exploded); diff --git a/net/ftp/ftp_directory_listing_parser_windows_unittest.cc b/net/ftp/ftp_directory_listing_parser_windows_unittest.cc index a768d05..eaf48ca 100644 --- a/net/ftp/ftp_directory_listing_parser_windows_unittest.cc +++ b/net/ftp/ftp_directory_listing_parser_windows_unittest.cc @@ -50,6 +50,12 @@ TEST_F(FtpDirectoryListingParserWindowsTest, Good) { { "11-02-09 05:32PM <DIR> My Directory", net::FtpDirectoryListingEntry::DIRECTORY, "My Directory", -1, 2009, 11, 2, 17, 32 }, + { "12-25-10 12:00AM <DIR> Christmas Midnight", + net::FtpDirectoryListingEntry::DIRECTORY, "Christmas Midnight", -1, + 2010, 12, 25, 0, 0 }, + { "12-25-10 12:00PM <DIR> Christmas Midday", + net::FtpDirectoryListingEntry::DIRECTORY, "Christmas Midday", -1, + 2010, 12, 25, 12, 0 }, }; for (size_t i = 0; i < arraysize(good_cases); i++) { SCOPED_TRACE(StringPrintf("Test[%" PRIuS "]: %s", i, good_cases[i].input)); @@ -68,6 +74,11 @@ TEST_F(FtpDirectoryListingParserWindowsTest, Bad) { "11-FEB-09 05:32PM <DIR> NT", "11-02 05:32PM <DIR> NT", "11-02-09 05:32PM -1 NT", + "99-25-10 12:00AM 0 months out of range", + "12-99-10 12:00AM 0 days out of range", + "12-25-10 99:00AM 0 hours out of range", + "12-25-10 12:99AM 0 minutes out of range", + "12-25-10 12:00ZM 0 what does ZM mean", }; for (size_t i = 0; i < arraysize(bad_cases); i++) { net::FtpDirectoryListingParserWindows parser; |