Commit 16750ef2 authored by Shane Kerr's avatar Shane Kerr
Browse files

Merge branch 'trac3010'

parents 0e6c5afb 2d742ae9
......@@ -42,14 +42,15 @@ myIsalpha(char c) {
struct Unit {
char unit;
uint32_t multiply;
uint32_t max_allowed;
};
Unit units[] = {
{ 'S', 1 },
{ 'M', 60 },
{ 'H', 60 * 60 },
{ 'D', 24 * 60 * 60 },
{ 'W', 7 * 24 * 60 * 60 }
{ 'S', 1, 0xffffffff / 1 },
{ 'M', 60, 0xffffffff / 60 },
{ 'H', 60 * 60, 0xffffffff / (60 * 60) },
{ 'D', 24 * 60 * 60, 0xffffffff / (24 * 60 * 60) },
{ 'W', 7 * 24 * 60 * 60, 0xffffffff / (7 * 24 * 60 * 60) }
};
}
......@@ -66,11 +67,9 @@ parseTTLString(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
}
return (false);
}
// We use a larger data type during the computation. This is because
// some compilers don't fail when out of range, so we check the range
// ourselves later.
int64_t val = 0;
// We use a larger data type to handle negative number cases.
uint64_t val = 0;
const string::const_iterator end = ttlstr.end();
string::const_iterator pos = ttlstr.begin();
......@@ -92,7 +91,7 @@ parseTTLString(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
} else {
// Case without any units at all. Just convert and store
// it.
val = boost::lexical_cast<int64_t>(ttlstr);
val = boost::lexical_cast<uint64_t>(ttlstr);
break;
}
}
......@@ -100,11 +99,13 @@ parseTTLString(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
units_mode = true;
// Find the unit and get the size.
uint32_t multiply = 1; // initialize to silence compiler warnings
uint32_t max_allowed = 0xffffffff;
bool found = false;
for (size_t i = 0; i < sizeof(units) / sizeof(*units); ++i) {
if (toupper(*unit) == units[i].unit) {
found = true;
multiply = units[i].multiply;
max_allowed = units[i].max_allowed;
break;
}
}
......@@ -122,15 +123,25 @@ parseTTLString(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
}
return (false);
}
const int64_t value = boost::lexical_cast<int64_t>(string(pos,
unit));
const uint64_t value =
boost::lexical_cast<uint64_t>(string(pos, unit));
if (value > max_allowed) {
if (error_txt != NULL) {
*error_txt = "Part of TTL out of range: " + ttlstr;
}
return (false);
}
// seconds cannot be out of range at this point.
const uint64_t seconds = value * multiply;
assert(seconds <= 0xffffffff);
// Add what we found
val += multiply * value;
val += seconds;
// Check the partial value is still in range (the value can only
// grow, so if we get out of range now, it won't get better, so
// there's no need to continue).
if (value < 0 || value > 0xffffffff || val < 0 ||
val > 0xffffffff) {
if (val < seconds || val > 0xffffffff) {
if (error_txt != NULL) {
*error_txt = "Part of TTL out of range: " + ttlstr;
}
......@@ -146,9 +157,10 @@ parseTTLString(const string& ttlstr, uint32_t& ttlval, string* error_txt) {
return (false);
}
if (val >= 0 && val <= 0xffffffff) {
if (val <= 0xffffffff) {
ttlval = val;
} else {
// This could be due to negative numbers in input, etc.
if (error_txt != NULL) {
*error_txt = "TTL out of range: " + ttlstr;
}
......
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