Commit 8ad3c813 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[trac61] separated timeToText() into 32-bit and 64-bit versions.

(this is an intermediate version; the 32-bit version will be fixed to support
overflow cases)
parent 5cfa9db0
......@@ -28,30 +28,83 @@
using namespace std;
namespace {
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
inline bool
isLeap(const int y) {
return ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0);
}
int
yearSecs(const int year) {
return ((isLeap(year) ? 366 : 365 ) * 86400);
}
int
monthSecs(const int month, const int year) {
return ((days[month] + ((month == 1 && isLeap(year)) ? 1 : 0 )) * 86400);
}
}
namespace isc {
namespace dns {
string
timeToText(const time_t timeval) {
struct tm* const t = gmtime(&timeval);
// gmtime() will keep most values within range, but it can
// produce a five-digit year; check for this.
if ((t->tm_year + 1900) > 9999) {
isc_throw(InvalidTime, "Time value out of range: year > 9999");
timeToText64(uint64_t t) {
struct tm tm;
int secs;
// We cannot rely on gmtime() because time_t may not be of 64 bit
// integer. The following conversion logic is borrowed from BIND 9.
tm.tm_year = 70;
while ((secs = yearSecs(tm.tm_year + 1900)) <= t) {
t -= secs;
++tm.tm_year;
if (tm.tm_year + 1900 > 9999) {
isc_throw(InvalidTime,
"Time value out of range (year > 9999): " <<
tm.tm_year + 1900);
}
}
tm.tm_mon = 0;
while ((secs = monthSecs(tm.tm_mon, tm.tm_year + 1900)) <= t) {
t -= secs;
tm.tm_mon++;
}
tm.tm_mday = 1;
while (86400 <= t) {
t -= 86400;
++tm.tm_mday;
}
tm.tm_hour = 0;
while (3600 <= t) {
t -= 3600;
++tm.tm_hour;
}
tm.tm_min = 0;
while (60 <= t) {
t -= 60;
++tm.tm_min;
}
tm.tm_sec = t; // now t < 60, so this substitution is safe.
ostringstream oss;
oss << setfill('0')
<< setw(4) << t->tm_year + 1900
<< setw(2) << t->tm_mon + 1
<< setw(2) << t->tm_mday
<< setw(2) << t->tm_hour
<< setw(2) << t->tm_min
<< setw(2) << t->tm_sec;
<< setw(4) << tm.tm_year + 1900
<< setw(2) << tm.tm_mon + 1
<< setw(2) << tm.tm_mday
<< setw(2) << tm.tm_hour
<< setw(2) << tm.tm_min
<< setw(2) << tm.tm_sec;
return (oss.str());
}
string
timeToText32(const time_t timeval) {
return (timeToText64(timeval));
}
namespace {
const size_t DATE_LEN = 14; // YYYYMMDDHHmmSS
......@@ -64,13 +117,6 @@ checkRange(const int min, const int max, const int value,
}
isc_throw(InvalidTime, "Invalid " << valname << "value: " << value);
}
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
inline bool
isLeap(const int y) {
return ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0);
}
}
uint64_t
......
......@@ -46,7 +46,10 @@ uint64_t
timeFromText64(const std::string& time_txt);
std::string
timeToText(const time_t timeval);
timeToText32(const time_t timeval);
std::string
timeToText64(uint64_t t);
}
}
......
......@@ -157,15 +157,12 @@ RRSIG::~RRSIG() {
string
RRSIG::toText() const {
string expire = timeToText(impl_->timeexpire_);
string inception = timeToText(impl_->timeinception_);
return (impl_->covered_.toText() +
" " + boost::lexical_cast<string>(static_cast<int>(impl_->algorithm_))
+ " " + boost::lexical_cast<string>(static_cast<int>(impl_->labels_))
+ " " + boost::lexical_cast<string>(impl_->originalttl_)
+ " " + expire
+ " " + inception
+ " " + timeToText32(impl_->timeexpire_)
+ " " + timeToText32(impl_->timeinception_)
+ " " + boost::lexical_cast<string>(impl_->tag_)
+ " " + impl_->signer_.toText()
+ " " + encodeBase64(impl_->signature_));
......
......@@ -75,16 +75,13 @@ TEST(DNSSECTimeTest, fromText) {
}
TEST(DNSSECTimeTest, toText) {
EXPECT_EQ("19700101000000", timeToText(0));
EXPECT_EQ("20100311233000", timeToText(1268350200));
EXPECT_EQ("19700101000000", timeToText32(0));
EXPECT_EQ("20100311233000", timeToText32(1268350200));
}
TEST(DNSSECTimeTest, overflow) {
// Jan 1, Year 10,000.
if (sizeof(time_t) > 4) {
EXPECT_THROW(timeToText(static_cast<time_t>(253402300800LL)),
InvalidTime);
}
EXPECT_THROW(timeToText64(253402300800LL), InvalidTime);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment