summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVladimir Glavnyy <31897320+vglavnyy@users.noreply.github.com>2021-02-11 02:37:16 +0700
committerGitHub <noreply@github.com>2021-02-10 11:37:16 -0800
commitfee095410b0969765b5c2545c10e585f69e961b0 (patch)
tree998cf645d76badfc2eaf4f564eeb120445a08634 /src
parent6f3e45eca1fde7a68cb72fd4499a3647f719c9db (diff)
downloadflatbuffers-fee095410b0969765b5c2545c10e585f69e961b0.tar.gz
flatbuffers-fee095410b0969765b5c2545c10e585f69e961b0.tar.bz2
flatbuffers-fee095410b0969765b5c2545c10e585f69e961b0.zip
[idl_parser] Validate `force_align` on all possible paths (#6430)
* [idl_parser] Validate `force_align` on all possible paths - added validation of `force_align` for `Vector`. - added assertion to `flatbuffers::PreAlign` method These changes should resolve following oss-fuzz issues: - 6275816289861632 - 5713529908887552 - 4761242994606080 * size_t problem on Mac * Fix review notes
Diffstat (limited to 'src')
-rw-r--r--src/idl_parser.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index 7cdddaff..e32adc67 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -1458,6 +1458,23 @@ void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) {
SimpleQsort(r, end, width, comparator, swapper);
}
+CheckedError Parser::ParseAlignAttribute(const std::string &align_constant,
+ size_t min_align, size_t *align) {
+ // Use uint8_t to avoid problems with size_t==`unsigned long` on LP64.
+ uint8_t align_value;
+ if (StringToNumber(align_constant.c_str(), &align_value) &&
+ VerifyAlignmentRequirements(static_cast<size_t>(align_value),
+ min_align)) {
+ *align = align_value;
+ return NoError();
+ }
+ return Error("unexpected force_align value '" + align_constant +
+ "', alignment must be a power of two integer ranging from the "
+ "type\'s natural alignment " +
+ NumToString(min_align) + " to " +
+ NumToString(FLATBUFFERS_MAX_ALIGNMENT));
+}
+
CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
FieldDef *field, size_t fieldn) {
uoffset_t count = 0;
@@ -1470,13 +1487,14 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
});
ECHECK(err);
- const auto *force_align = field->attributes.Lookup("force_align");
- const size_t align =
- force_align ? static_cast<size_t>(atoi(force_align->constant.c_str()))
- : 1;
const size_t len = count * InlineSize(type) / InlineAlignment(type);
const size_t elemsize = InlineAlignment(type);
- if (align > 1) { builder_.ForceVectorAlignment(len, elemsize, align); }
+ const auto force_align = field->attributes.Lookup("force_align");
+ if (force_align) {
+ size_t align;
+ ECHECK(ParseAlignAttribute(force_align->constant, 1, &align));
+ if (align > 1) { builder_.ForceVectorAlignment(len, elemsize, align); }
+ }
builder_.StartVector(len, elemsize);
for (uoffset_t i = 0; i < count; i++) {
@@ -2457,17 +2475,12 @@ CheckedError Parser::ParseDecl() {
struct_def->attributes.Lookup("original_order") == nullptr && !fixed;
EXPECT('{');
while (token_ != '}') ECHECK(ParseField(*struct_def));
- auto force_align = struct_def->attributes.Lookup("force_align");
if (fixed) {
+ const auto force_align = struct_def->attributes.Lookup("force_align");
if (force_align) {
- auto align = static_cast<size_t>(atoi(force_align->constant.c_str()));
- if (force_align->type.base_type != BASE_TYPE_INT ||
- align < struct_def->minalign || align > FLATBUFFERS_MAX_ALIGNMENT ||
- align & (align - 1))
- return Error(
- "force_align must be a power of two integer ranging from the"
- "struct\'s natural alignment to " +
- NumToString(FLATBUFFERS_MAX_ALIGNMENT));
+ size_t align;
+ ECHECK(ParseAlignAttribute(force_align->constant, struct_def->minalign,
+ &align));
struct_def->minalign = align;
}
if (!struct_def->bytesize) return Error("size 0 structs not allowed");