Commit f1365704 authored by Wouter van Oortmerssen's avatar Wouter van Oortmerssen Committed by GitHub

Merge pull request #4004 from sahiljain/fix-3909

Return error when full string cannot be parsed into int
parents 4b79ff53 b6ba322a
...@@ -95,20 +95,20 @@ inline std::string IntToStringHex(int i, int xdigits) { ...@@ -95,20 +95,20 @@ inline std::string IntToStringHex(int i, int xdigits) {
} }
// Portable implementation of strtoll(). // Portable implementation of strtoll().
inline int64_t StringToInt(const char *str, int base = 10) { inline int64_t StringToInt(const char *str, char **endptr = nullptr, int base = 10) {
#ifdef _MSC_VER #ifdef _MSC_VER
return _strtoi64(str, nullptr, base); return _strtoi64(str, endptr, base);
#else #else
return strtoll(str, nullptr, base); return strtoll(str, endptr, base);
#endif #endif
} }
// Portable implementation of strtoull(). // Portable implementation of strtoull().
inline int64_t StringToUInt(const char *str, int base = 10) { inline int64_t StringToUInt(const char *str, char **endptr = nullptr, int base = 10) {
#ifdef _MSC_VER #ifdef _MSC_VER
return _strtoui64(str, nullptr, base); return _strtoui64(str, endptr, base);
#else #else
return strtoull(str, nullptr, base); return strtoull(str, endptr, base);
#endif #endif
} }
......
...@@ -219,7 +219,7 @@ CheckedError Parser::ParseHexNum(int nibbles, int64_t *val) { ...@@ -219,7 +219,7 @@ CheckedError Parser::ParseHexNum(int nibbles, int64_t *val) {
return Error("escape code must be followed by " + NumToString(nibbles) + return Error("escape code must be followed by " + NumToString(nibbles) +
" hex digits"); " hex digits");
std::string target(cursor_, cursor_ + nibbles); std::string target(cursor_, cursor_ + nibbles);
*val = StringToUInt(target.c_str(), 16); *val = StringToUInt(target.c_str(), nullptr, 16);
cursor_ += nibbles; cursor_ += nibbles;
return NoError(); return NoError();
} }
...@@ -447,7 +447,7 @@ CheckedError Parser::Next() { ...@@ -447,7 +447,7 @@ CheckedError Parser::Next() {
cursor_++; cursor_++;
while (isxdigit(static_cast<unsigned char>(*cursor_))) cursor_++; while (isxdigit(static_cast<unsigned char>(*cursor_))) cursor_++;
attribute_.append(start + 2, cursor_); attribute_.append(start + 2, cursor_);
attribute_ = NumToString(StringToUInt(attribute_.c_str(), 16)); attribute_ = NumToString(StringToUInt(attribute_.c_str(), nullptr, 16));
token_ = kTokenIntegerConstant; token_ = kTokenIntegerConstant;
return NoError(); return NoError();
} }
...@@ -1093,10 +1093,15 @@ CheckedError Parser::ParseSingleValue(Value &e) { ...@@ -1093,10 +1093,15 @@ CheckedError Parser::ParseSingleValue(Value &e) {
NEXT(); NEXT();
} else { // Numeric constant in string. } else { // Numeric constant in string.
if (IsInteger(e.type.base_type)) { if (IsInteger(e.type.base_type)) {
// TODO(wvo): do we want to check for garbage after the number? char *end;
e.constant = NumToString(StringToInt(attribute_.c_str())); e.constant = NumToString(StringToInt(attribute_.c_str(), &end));
if (*end)
return Error("invalid integer: " + attribute_);
} else if (IsFloat(e.type.base_type)) { } else if (IsFloat(e.type.base_type)) {
e.constant = NumToString(strtod(attribute_.c_str(), nullptr)); char *end;
e.constant = NumToString(strtod(attribute_.c_str(), &end));
if (*end)
return Error("invalid float: " + attribute_);
} else { } else {
assert(0); // Shouldn't happen, we covered all types. assert(0); // Shouldn't happen, we covered all types.
e.constant = "0"; e.constant = "0";
......
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