Handle +/-inf in protos (#7256)

* Handle +/-inf in protos

* Check for digit in 4th pos
This commit is contained in:
Derek Bailey
2022-04-19 13:07:26 -07:00
committed by GitHub
parent 7bcd857b87
commit ccfb4c20bf
8 changed files with 48 additions and 8 deletions

View File

@@ -489,10 +489,21 @@ CheckedError Parser::Next() {
}
const auto has_sign = (c == '+') || (c == '-');
if (has_sign && IsIdentifierStart(*cursor_)) {
// '-'/'+' and following identifier - it could be a predefined
// constant. Return the sign in token_, see ParseSingleValue.
return NoError();
if (has_sign) {
// Check for +/-inf which is considered a float constant.
if (strncmp(cursor_, "inf", 3) == 0 &&
!(IsIdentifierStart(cursor_[4]) || is_digit(cursor_[4]))) {
attribute_.assign(cursor_ - 1, cursor_ + 3);
token_ = kTokenFloatConstant;
cursor_ += 3;
return NoError();
}
if (IsIdentifierStart(*cursor_)) {
// '-'/'+' and following identifier - it could be a predefined
// constant. Return the sign in token_, see ParseSingleValue.
return NoError();
}
}
auto dot_lvl =
@@ -2178,8 +2189,12 @@ template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) {
}
namespace EnumHelper {
template<BaseType E> struct EnumValType { typedef int64_t type; };
template<> struct EnumValType<BASE_TYPE_ULONG> { typedef uint64_t type; };
template<BaseType E> struct EnumValType {
typedef int64_t type;
};
template<> struct EnumValType<BASE_TYPE_ULONG> {
typedef uint64_t type;
};
} // namespace EnumHelper
struct EnumValBuilder {
@@ -2885,8 +2900,11 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
if (key == "default") {
// Temp: skip non-numeric and non-boolean defaults (enums).
auto numeric = strpbrk(val.c_str(), "0123456789-+.");
if (IsScalar(type.base_type) &&
(numeric == val.c_str() || val == "inf" || val == "-inf")) {
if (IsFloat(type.base_type) &&
(val == "inf" || val == "+inf" || val == "-inf")) {
// Prefer to be explicit with +inf.
field->value.constant = val == "inf" ? "+inf" : val;
} else if (IsScalar(type.base_type) && numeric == val.c_str()) {
field->value.constant = val;
} else if (val == "true") {
field->value.constant = val;