Explorar o código

Merge pull request #6681 from thomasvl/objc_fix2

Pull the ObjC fixes from #6679 to the 3.10.x branch
Paul Yang %!s(int64=6) %!d(string=hai) anos
pai
achega
3a0be889c2
Modificáronse 2 ficheiros con 26 adicións e 14 borrados
  1. 10 2
      objectivec/GPBCodedInputStream.m
  2. 16 12
      objectivec/GPBUtilities_PackagePrivate.h

+ 10 - 2
objectivec/GPBCodedInputStream.m

@@ -93,14 +93,22 @@ static int8_t ReadRawByte(GPBCodedInputStreamState *state) {
 
 
 static int32_t ReadRawLittleEndian32(GPBCodedInputStreamState *state) {
 static int32_t ReadRawLittleEndian32(GPBCodedInputStreamState *state) {
   CheckSize(state, sizeof(int32_t));
   CheckSize(state, sizeof(int32_t));
-  int32_t value = OSReadLittleInt32(state->bytes, state->bufferPos);
+  // Not using OSReadLittleInt32 because it has undocumented dependency
+  // on reads being aligned.
+  int32_t value;
+  memcpy(&value, state->bytes + state->bufferPos, sizeof(int32_t));
+  value = OSSwapLittleToHostInt32(value);
   state->bufferPos += sizeof(int32_t);
   state->bufferPos += sizeof(int32_t);
   return value;
   return value;
 }
 }
 
 
 static int64_t ReadRawLittleEndian64(GPBCodedInputStreamState *state) {
 static int64_t ReadRawLittleEndian64(GPBCodedInputStreamState *state) {
   CheckSize(state, sizeof(int64_t));
   CheckSize(state, sizeof(int64_t));
-  int64_t value = OSReadLittleInt64(state->bytes, state->bufferPos);
+  // Not using OSReadLittleInt64 because it has undocumented dependency
+  // on reads being aligned.  
+  int64_t value;
+  memcpy(&value, state->bytes + state->bufferPos, sizeof(int64_t));
+  value = OSSwapLittleToHostInt64(value);
   state->bufferPos += sizeof(int64_t);
   state->bufferPos += sizeof(int64_t);
   return value;
   return value;
 }
 }

+ 16 - 12
objectivec/GPBUtilities_PackagePrivate.h

@@ -71,27 +71,31 @@ GPB_INLINE void GPBDebugCheckRuntimeVersion() {
 // Conversion functions for de/serializing floating point types.
 // Conversion functions for de/serializing floating point types.
 
 
 GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
 GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
-  union { double f; int64_t i; } u;
-  u.f = v;
-  return u.i;
+  GPBInternalCompileAssert(sizeof(double) == sizeof(int64_t), double_not_64_bits);
+  int64_t result;
+  memcpy(&result, &v, sizeof(result));
+  return result;
 }
 }
 
 
 GPB_INLINE int32_t GPBConvertFloatToInt32(float v) {
 GPB_INLINE int32_t GPBConvertFloatToInt32(float v) {
-  union { float f; int32_t i; } u;
-  u.f = v;
-  return u.i;
+  GPBInternalCompileAssert(sizeof(float) == sizeof(int32_t), float_not_32_bits);
+  int32_t result;
+  memcpy(&result, &v, sizeof(result));
+  return result;
 }
 }
 
 
 GPB_INLINE double GPBConvertInt64ToDouble(int64_t v) {
 GPB_INLINE double GPBConvertInt64ToDouble(int64_t v) {
-  union { double f; int64_t i; } u;
-  u.i = v;
-  return u.f;
+  GPBInternalCompileAssert(sizeof(double) == sizeof(int64_t), double_not_64_bits);
+  double result;
+  memcpy(&result, &v, sizeof(result));
+  return result;
 }
 }
 
 
 GPB_INLINE float GPBConvertInt32ToFloat(int32_t v) {
 GPB_INLINE float GPBConvertInt32ToFloat(int32_t v) {
-  union { float f; int32_t i; } u;
-  u.i = v;
-  return u.f;
+  GPBInternalCompileAssert(sizeof(float) == sizeof(int32_t), float_not_32_bits);
+  float result;
+  memcpy(&result, &v, sizeof(result));
+  return result;
 }
 }
 
 
 GPB_INLINE int32_t GPBLogicalRightShift32(int32_t value, int32_t spaces) {
 GPB_INLINE int32_t GPBLogicalRightShift32(int32_t value, int32_t spaces) {