[fidl] Fix encode, decode, and validation alignment
All fidl messages are 8-byte aligned and padded, so messages without
out-of-line objects need to be padded up to the next alignment.
Change-Id: I7fbb4a368e1d34d97796301afb005fc8c66b7861
diff --git a/system/ulib/fidl/decoding.cpp b/system/ulib/fidl/decoding.cpp
index dec88d6..aa65bdd 100644
--- a/system/ulib/fidl/decoding.cpp
+++ b/system/ulib/fidl/decoding.cpp
@@ -64,10 +64,10 @@
// Returns true when the buffer space is claimed, and false when
// the requested claim is too large for bytes_.
bool ClaimOutOfLineStorage(uint32_t size, uint32_t* out_offset) {
- // Unlike the inline case, we have to manually maintain
- // alignment here. For example, a pointer to a struct that is
- // 4 bytes still needs to advance the next out-of-line offset
- // by 8 to maintain the aligned-to-FIDL_ALIGNMENT property.
+ // We have to manually maintain alignment here. For example, a pointer
+ // to a struct that is 4 bytes still needs to advance the next
+ // out-of-line offset by 8 to maintain the aligned-to-FIDL_ALIGNMENT
+ // property.
uint64_t aligned_offset = fidl::FidlAlign(out_of_line_offset_ + size);
if (aligned_offset > static_cast<uint64_t>(num_bytes_)) {
return false;
@@ -291,16 +291,7 @@
return WithError("Message size is smaller than expected");
}
- // Any type that calls into ClaimOutOfLineStorage will have a
- // string, vector, struct pointer, or union pointer in the primary
- // message struct. This will force the size of that struct to be a
- // multiple of 8. Any type that does not have any out of line
- // objects, and that has a size 4 modulo 8, would fail the check
- // at the end that out_of_line_offset_ and num_bytes_ are the same
- // if we rounded it. Thus we in fact do not want to round this up
- // to FIDL_ALIGNMENT here, as it is already aligned enough when it
- // needs to be.
- out_of_line_offset_ = type_->coded_struct.size;
+ out_of_line_offset_ = static_cast<uint32_t>(fidl::FidlAlign(type_->coded_struct.size));
Push(Frame::DoneSentinel());
Push(Frame(type_, 0u));
diff --git a/system/ulib/fidl/encoding.cpp b/system/ulib/fidl/encoding.cpp
index e4b5ded..93b892e 100644
--- a/system/ulib/fidl/encoding.cpp
+++ b/system/ulib/fidl/encoding.cpp
@@ -80,10 +80,10 @@
// Returns true when the buffer space is claimed, and false when
// the requested claim is too large for bytes_.
bool ClaimOutOfLineStorage(uint32_t size, const void* storage, uint32_t* out_offset) {
- // Unlike the inline case, we have to manually maintain
- // alignment here. For example, a pointer to a struct that is
- // 4 bytes still needs to advance the next out-of-line offset
- // by 8 to maintain the aligned-to-FIDL_ALIGNMENT property.
+ // We have to manually maintain alignment here. For example, a pointer
+ // to a struct that is 4 bytes still needs to advance the next
+ // out-of-line offset by 8 to maintain the aligned-to-FIDL_ALIGNMENT
+ // property.
if (&bytes_[out_of_line_offset_] != static_cast<const uint8_t*>(storage)) {
return false;
}
@@ -321,16 +321,7 @@
return status_;
}
- // Any type that calls into ClaimOutOfLineStorage will have a
- // string, vector, struct pointer, or union pointer in the primary
- // message struct. This will force the size of that struct to be a
- // multiple of 8. Any type that does not have any out of line
- // objects, and that has a size 4 modulo 8, would fail the check
- // at the end that out_of_line_offset_ and num_bytes_ are the same
- // if we rounded it. Thus we in fact do not want to round this up
- // to FIDL_ALIGNMENT here, as it is already aligned enough when it
- // needs to be.
- out_of_line_offset_ = type_->coded_struct.size;
+ out_of_line_offset_ = static_cast<uint32_t>(fidl::FidlAlign(type_->coded_struct.size));
Push(Frame::DoneSentinel());
Push(Frame(type_, 0u));
diff --git a/system/ulib/fidl/validating.cpp b/system/ulib/fidl/validating.cpp
index 79695ce..7e1b09a 100644
--- a/system/ulib/fidl/validating.cpp
+++ b/system/ulib/fidl/validating.cpp
@@ -58,10 +58,10 @@
// Returns true when the buffer space is claimed, and false when
// the requested claim is too large for bytes_.
bool ClaimOutOfLineStorage(uint32_t size, uint32_t* out_offset) {
- // Unlike the inline case, we have to manually maintain
- // alignment here. For example, a pointer to a struct that is
- // 4 bytes still needs to advance the next out-of-line offset
- // by 8 to maintain the aligned-to-FIDL_ALIGNMENT property.
+ // We have to manually maintain alignment here. For example, a pointer
+ // to a struct that is 4 bytes still needs to advance the next
+ // out-of-line offset by 8 to maintain the aligned-to-FIDL_ALIGNMENT
+ // property.
uint64_t aligned_offset = fidl::FidlAlign(out_of_line_offset_ + size);
if (aligned_offset > static_cast<uint64_t>(num_bytes_)) {
return false;
@@ -283,16 +283,7 @@
return WithError("Message size is smaller than expected");
}
- // Any type that calls into ClaimOutOfLineStorage will have a
- // string, vector, struct pointer, or union pointer in the primary
- // message struct. This will force the size of that struct to be a
- // multiple of 8. Any type that does not have any out of line
- // objects, and that has a size 4 modulo 8, would fail the check
- // at the end that out_of_line_offset_ and num_bytes_ are the same
- // if we rounded it. Thus we in fact do not want to round this up
- // to FIDL_ALIGNMENT here, as it is already aligned enough when it
- // needs to be.
- out_of_line_offset_ = type_->coded_struct.size;
+ out_of_line_offset_ = static_cast<uint32_t>(fidl::FidlAlign(type_->coded_struct.size));
Push(Frame::DoneSentinel());
Push(Frame(type_, 0u));