static const size_t kCapacityReadOnly = static_cast<size_t>(-1);
PickleIterator::PickleIterator(const Pickle& pickle)
- : read_ptr_(pickle.payload()),
- read_end_ptr_(pickle.end_of_payload()) {
+ : payload_(pickle.payload()),
+ read_index_(0),
+ end_index_(pickle.payload_size()) {
}
template <typename Type>
return true;
}
+inline void PickleIterator::Advance(size_t size) {
+ size_t aligned_size = AlignInt(size, sizeof(uint32_t));
+ if (end_index_ - read_index_ < aligned_size) {
+ read_index_ = end_index_;
+ } else {
+ read_index_ += aligned_size;
+ }
+}
+
template<typename Type>
inline const char* PickleIterator::GetReadPointerAndAdvance() {
- const char* current_read_ptr = read_ptr_;
- if (read_ptr_ + sizeof(Type) > read_end_ptr_)
+ if (sizeof(Type) > end_index_ - read_index_) {
+ read_index_ = end_index_;
return NULL;
- if (sizeof(Type) < sizeof(uint32))
- read_ptr_ += AlignInt(sizeof(Type), sizeof(uint32));
- else
- read_ptr_ += sizeof(Type);
+ }
+ const char* current_read_ptr = payload_ + read_index_;
+ Advance(sizeof(Type));
return current_read_ptr;
}
const char* PickleIterator::GetReadPointerAndAdvance(int num_bytes) {
- if (num_bytes < 0 || read_end_ptr_ - read_ptr_ < num_bytes)
+ if (num_bytes < 0 ||
+ end_index_ - read_index_ < static_cast<size_t>(num_bytes)) {
+ read_index_ = end_index_;
return NULL;
- const char* current_read_ptr = read_ptr_;
- read_ptr_ += AlignInt(num_bytes, sizeof(uint32));
+ }
+ const char* current_read_ptr = payload_ + read_index_;
+ Advance(num_bytes);
return current_read_ptr;
}
-inline const char* PickleIterator::GetReadPointerAndAdvance(int num_elements,
- size_t size_element) {
+inline const char* PickleIterator::GetReadPointerAndAdvance(
+ int num_elements,
+ size_t size_element) {
// Check for int32 overflow.
int64 num_bytes = static_cast<int64>(num_elements) * size_element;
int num_bytes32 = static_cast<int>(num_bytes);
return ReadBuiltinType(result);
}
+bool PickleIterator::ReadSizeT(size_t* result) {
+ // Always read size_t as a 64-bit value to ensure compatibility between 32-bit
+ // and 64-bit processes.
+ uint64 result_uint64 = 0;
+ bool success = ReadBuiltinType(&result_uint64);
+ *result = static_cast<size_t>(result_uint64);
+ // Fail if the cast above truncates the value.
+ return success && (*result == result_uint64);
+}
+
bool PickleIterator::ReadFloat(float* result) {
// crbug.com/315213
// The source data may not be properly aligned, and unaligned float reads
return true;
}
+bool PickleIterator::ReadDouble(double* result) {
+ // crbug.com/315213
+ // The source data may not be properly aligned, and unaligned double reads
+ // cause SIGBUS on some ARM platforms, so force using memcpy to copy the data
+ // into the result.
+ const char* read_from = GetReadPointerAndAdvance<double>();
+ if (!read_from)
+ return false;
+ memcpy(result, read_from, sizeof(*result));
+ return true;
+}
+
bool PickleIterator::ReadString(std::string* result) {
int len;
if (!ReadInt(&len))
char* write = mutable_payload() + write_offset_;
memcpy(write, data, length);
memset(write + length, 0, data_len - length);
- header_->payload_size = static_cast<uint32>(write_offset_ + length);
+ header_->payload_size = static_cast<uint32>(new_size);
write_offset_ = new_size;
}