From 30c821d14308de2f08dee3b5e6410c3403c7a928 Mon Sep 17 00:00:00 2001 From: Josh Aas Date: Tue, 31 Aug 2010 14:01:21 -0400 Subject: [PATCH] Bug 590052: For values that vary in size by architecture like 'long', 'unsigned long', 'size_t', and pointers, standardize on their longer (64-bit) form for sending via IPC. Part of making cross-architecture IPC work. r=cjones a=blocking-b6 --- ipc/chromium/src/base/pickle.cc | 59 +++++++++++++++++++++++++-------- ipc/chromium/src/base/pickle.h | 20 ++++++++--- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/ipc/chromium/src/base/pickle.cc b/ipc/chromium/src/base/pickle.cc index 31c5d2bbd90..8f99f66e144 100644 --- a/ipc/chromium/src/base/pickle.cc +++ b/ipc/chromium/src/base/pickle.cc @@ -133,35 +133,45 @@ bool Pickle::ReadInt(void** iter, int* result) const { return true; } +// Always written as a 64-bit value since the size for this type can +// differ between architectures. bool Pickle::ReadLong(void** iter, long* result) const { DCHECK(iter); if (!*iter) *iter = const_cast(payload()); - if (!IteratorHasRoomFor(*iter, sizeof(*result))) + int64 bigResult = 0; + if (!IteratorHasRoomFor(*iter, sizeof(bigResult))) return false; // TODO(jar) bug 1129285: Pickle should be cleaned up, and not dependent on // alignment. - memcpy(result, *iter, sizeof(*result)); + memcpy(&bigResult, *iter, sizeof(bigResult)); + DCHECK(bigResult <= LONG_MAX && bigResult >= LONG_MIN); + *result = static_cast(bigResult); - UpdateIter(iter, sizeof(*result)); + UpdateIter(iter, sizeof(bigResult)); return true; } +// Always written as a 64-bit value since the size for this type can +// differ between architectures. bool Pickle::ReadULong(void** iter, unsigned long* result) const { DCHECK(iter); if (!*iter) *iter = const_cast(payload()); - if (!IteratorHasRoomFor(*iter, sizeof(*result))) + uint64 bigResult = 0; + if (!IteratorHasRoomFor(*iter, sizeof(bigResult))) return false; // TODO(jar) bug 1129285: Pickle should be cleaned up, and not dependent on // alignment. - memcpy(result, *iter, sizeof(*result)); + memcpy(&bigResult, *iter, sizeof(bigResult)); + DCHECK(bigResult <= ULONG_MAX); + *result = static_cast(bigResult); - UpdateIter(iter, sizeof(*result)); + UpdateIter(iter, sizeof(bigResult)); return true; } @@ -171,20 +181,24 @@ bool Pickle::ReadLength(void** iter, int* result) const { return ((*result) >= 0); } +// Always written as a 64-bit value since the size for this type can +// differ between architectures. bool Pickle::ReadSize(void** iter, size_t* result) const { DCHECK(iter); if (!*iter) *iter = const_cast(payload()); - if (!IteratorHasRoomFor(*iter, sizeof(*result))) + uint64 bigResult = 0; + if (!IteratorHasRoomFor(*iter, sizeof(bigResult))) return false; // TODO(jar) bug 1129285: Pickle should be cleaned up, and not dependent on // alignment. - // Next line is otherwise the same as: memcpy(result, *iter, sizeof(*result)); - *result = *reinterpret_cast(*iter); + memcpy(&bigResult, *iter, sizeof(bigResult)); + DCHECK(bigResult <= std::numeric_limits::max()); + *result = static_cast(bigResult); - UpdateIter(iter, sizeof(*result)); + UpdateIter(iter, sizeof(bigResult)); return true; } @@ -230,6 +244,20 @@ bool Pickle::ReadInt64(void** iter, int64* result) const { return true; } +bool Pickle::ReadUInt64(void** iter, uint64* result) const { + DCHECK(iter); + if (!*iter) + *iter = const_cast(payload()); + + if (!IteratorHasRoomFor(*iter, sizeof(*result))) + return false; + + memcpy(result, *iter, sizeof(*result)); + + UpdateIter(iter, sizeof(*result)); + return true; +} + bool Pickle::ReadDouble(void** iter, double* result) const { DCHECK(iter); if (!*iter) @@ -244,17 +272,22 @@ bool Pickle::ReadDouble(void** iter, double* result) const { return true; } +// Always written as a 64-bit value since the size for this type can +// differ between architectures. bool Pickle::ReadIntPtr(void** iter, intptr_t* result) const { DCHECK(iter); if (!*iter) *iter = const_cast(payload()); - if (!IteratorHasRoomFor(*iter, sizeof(*result))) + int64 bigResult = 0; + if (!IteratorHasRoomFor(*iter, sizeof(bigResult))) return false; - memcpy(result, *iter, sizeof(*result)); + memcpy(&bigResult, *iter, sizeof(bigResult)); + DCHECK(bigResult <= std::numeric_limits::max() && bigResult >= std::numeric_limits::min()); + *result = static_cast(bigResult); - UpdateIter(iter, sizeof(*result)); + UpdateIter(iter, sizeof(bigResult)); return true; } diff --git a/ipc/chromium/src/base/pickle.h b/ipc/chromium/src/base/pickle.h index 592c249294f..7a5f22cbdf2 100644 --- a/ipc/chromium/src/base/pickle.h +++ b/ipc/chromium/src/base/pickle.h @@ -75,6 +75,7 @@ class Pickle { bool ReadInt32(void** iter, int32* result) const; bool ReadUInt32(void** iter, uint32* result) const; bool ReadInt64(void** iter, int64* result) const; + bool ReadUInt64(void** iter, uint64* result) const; bool ReadDouble(void** iter, double* result) const; bool ReadIntPtr(void** iter, intptr_t* result) const; bool ReadUnsignedChar(void** iter, unsigned char* result) const; @@ -105,13 +106,19 @@ class Pickle { return WriteBytes(&value, sizeof(value)); } bool WriteLong(long value) { - return WriteBytes(&value, sizeof(value)); + // Always written as a 64-bit value since the size for this type can + // differ between architectures. + return WriteInt64(int64(value)); } bool WriteULong(unsigned long value) { - return WriteBytes(&value, sizeof(value)); + // Always written as a 64-bit value since the size for this type can + // differ between architectures. + return WriteUInt64(uint64(value)); } bool WriteSize(size_t value) { - return WriteBytes(&value, sizeof(value)); + // Always written as a 64-bit value since the size for this type can + // differ between architectures. + return WriteUInt64(uint64(value)); } bool WriteInt32(int32 value) { return WriteBytes(&value, sizeof(value)); @@ -122,11 +129,16 @@ class Pickle { bool WriteInt64(int64 value) { return WriteBytes(&value, sizeof(value)); } + bool WriteUInt64(uint64 value) { + return WriteBytes(&value, sizeof(value)); + } bool WriteDouble(double value) { return WriteBytes(&value, sizeof(value)); } bool WriteIntPtr(intptr_t value) { - return WriteBytes(&value, sizeof(value)); + // Always written as a 64-bit value since the size for this type can + // differ between architectures. + return WriteInt64(int64(value)); } bool WriteUnsignedChar(unsigned char value) { return WriteBytes(&value, sizeof(value));