mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-30 14:00:02 +00:00
Handle +/-inf in protos (#7256)
* Handle +/-inf in protos * Check for digit in 4th pos
This commit is contained in:
@@ -489,10 +489,21 @@ CheckedError Parser::Next() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto has_sign = (c == '+') || (c == '-');
|
const auto has_sign = (c == '+') || (c == '-');
|
||||||
if (has_sign && IsIdentifierStart(*cursor_)) {
|
if (has_sign) {
|
||||||
// '-'/'+' and following identifier - it could be a predefined
|
// Check for +/-inf which is considered a float constant.
|
||||||
// constant. Return the sign in token_, see ParseSingleValue.
|
if (strncmp(cursor_, "inf", 3) == 0 &&
|
||||||
return NoError();
|
!(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 =
|
auto dot_lvl =
|
||||||
@@ -2178,8 +2189,12 @@ template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace EnumHelper {
|
namespace EnumHelper {
|
||||||
template<BaseType E> struct EnumValType { typedef int64_t type; };
|
template<BaseType E> struct EnumValType {
|
||||||
template<> struct EnumValType<BASE_TYPE_ULONG> { typedef uint64_t type; };
|
typedef int64_t type;
|
||||||
|
};
|
||||||
|
template<> struct EnumValType<BASE_TYPE_ULONG> {
|
||||||
|
typedef uint64_t type;
|
||||||
|
};
|
||||||
} // namespace EnumHelper
|
} // namespace EnumHelper
|
||||||
|
|
||||||
struct EnumValBuilder {
|
struct EnumValBuilder {
|
||||||
@@ -2885,8 +2900,11 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
|
|||||||
if (key == "default") {
|
if (key == "default") {
|
||||||
// Temp: skip non-numeric and non-boolean defaults (enums).
|
// Temp: skip non-numeric and non-boolean defaults (enums).
|
||||||
auto numeric = strpbrk(val.c_str(), "0123456789-+.");
|
auto numeric = strpbrk(val.c_str(), "0123456789-+.");
|
||||||
if (IsScalar(type.base_type) &&
|
if (IsFloat(type.base_type) &&
|
||||||
(numeric == val.c_str() || val == "inf" || val == "-inf")) {
|
(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;
|
field->value.constant = val;
|
||||||
} else if (val == "true") {
|
} else if (val == "true") {
|
||||||
field->value.constant = val;
|
field->value.constant = val;
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ table ProtoMessage {
|
|||||||
/// doc comment for r.
|
/// doc comment for r.
|
||||||
r:proto.test.ProtoMessage_.Anonymous0;
|
r:proto.test.ProtoMessage_.Anonymous0;
|
||||||
outer_enum:proto.test.ProtoEnum;
|
outer_enum:proto.test.ProtoEnum;
|
||||||
|
u:float = +inf;
|
||||||
|
v:float = +inf;
|
||||||
|
w:float = -inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
|
|||||||
@@ -67,4 +67,8 @@ message ProtoMessage {
|
|||||||
OtherMessage t = 18;
|
OtherMessage t = 18;
|
||||||
}
|
}
|
||||||
optional ProtoEnum outer_enum = 33;
|
optional ProtoEnum outer_enum = 33;
|
||||||
|
// Tests that `inf` and `+/-inf` can be parsed in proto options.
|
||||||
|
optional float u = 34 [default = inf];
|
||||||
|
optional float v = 35 [default = +inf];
|
||||||
|
optional float w = 36 [default = -inf];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ table ProtoMessage {
|
|||||||
/// doc comment for r.
|
/// doc comment for r.
|
||||||
r:proto.test.ProtoMessage_.Anonymous0;
|
r:proto.test.ProtoMessage_.Anonymous0;
|
||||||
outer_enum:proto.test.ProtoEnum;
|
outer_enum:proto.test.ProtoEnum;
|
||||||
|
u:float = +inf;
|
||||||
|
v:float = +inf;
|
||||||
|
w:float = -inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ table ProtoMessage {
|
|||||||
/// doc comment for r.
|
/// doc comment for r.
|
||||||
r:proto.test.test_namespace_suffix.ProtoMessage_.Anonymous0;
|
r:proto.test.test_namespace_suffix.ProtoMessage_.Anonymous0;
|
||||||
outer_enum:proto.test.test_namespace_suffix.ProtoEnum;
|
outer_enum:proto.test.test_namespace_suffix.ProtoEnum;
|
||||||
|
u:float = +inf;
|
||||||
|
v:float = +inf;
|
||||||
|
w:float = -inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ table ProtoMessage {
|
|||||||
/// doc comment for r.
|
/// doc comment for r.
|
||||||
r:proto.test.ProtoMessage_.RUnion;
|
r:proto.test.ProtoMessage_.RUnion;
|
||||||
outer_enum:proto.test.ProtoEnum;
|
outer_enum:proto.test.ProtoEnum;
|
||||||
|
u:float = +inf;
|
||||||
|
v:float = +inf;
|
||||||
|
w:float = -inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ table ProtoMessage {
|
|||||||
/// doc comment for r.
|
/// doc comment for r.
|
||||||
r:proto.test.ProtoMessage_.RUnion;
|
r:proto.test.ProtoMessage_.RUnion;
|
||||||
outer_enum:proto.test.ProtoEnum;
|
outer_enum:proto.test.ProtoEnum;
|
||||||
|
u:float = +inf;
|
||||||
|
v:float = +inf;
|
||||||
|
w:float = -inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.ProtoMessage_;
|
namespace proto.test.ProtoMessage_;
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ table ProtoMessage {
|
|||||||
/// doc comment for r.
|
/// doc comment for r.
|
||||||
r:proto.test.test_namespace_suffix.ProtoMessage_.RUnion;
|
r:proto.test.test_namespace_suffix.ProtoMessage_.RUnion;
|
||||||
outer_enum:proto.test.test_namespace_suffix.ProtoEnum;
|
outer_enum:proto.test.test_namespace_suffix.ProtoEnum;
|
||||||
|
u:float = +inf;
|
||||||
|
v:float = +inf;
|
||||||
|
w:float = -inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
namespace proto.test.test_namespace_suffix.ProtoMessage_;
|
||||||
|
|||||||
Reference in New Issue
Block a user