Browse Source

FBX: use memcpy() instead of reinterpret_cast or union to populate a float from a blob, causing SIGBUS errors on Android due to memory alignment of the source blob not being a multiple of 4/8. This fixes #24.

Alexander Gessler 11 years ago
parent
commit
becd298e77
1 changed files with 16 additions and 6 deletions
  1. 16 6
      code/FBXParser.cpp

+ 16 - 6
code/FBXParser.cpp

@@ -364,14 +364,24 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
 		}
 
 		if (data[0] == 'F') {
-			ai_assert(t.end() - data == 5);
-			// no byte swapping needed for ieee floats
-			return *reinterpret_cast<const float*>(data+1);
+			// Actual size validation happens during Tokenization so
+			// this is valid as an assertion.
+			ai_assert(t.end() - data == sizeof(float) + 1);
+			// Initially, we did reinterpret_cast, breaking strict aliasing rules.
+			// This actually caused trouble on Android, so let's be safe this time.
+			// https://github.com/assimp/assimp/issues/24
+			
+			float out_float;
+			::memcpy(&out_float, data+1, sizeof(float));
+			return out_float;
 		}
 		else {
-			ai_assert(t.end() - data == 9);
-			// no byte swapping needed for ieee floats
-			return static_cast<float>(*reinterpret_cast<const double*>(data+1));
+			ai_assert(t.end() - data == sizeof(double) + 1);
+			
+			// Same
+			double out_double;
+			::memcpy(&out_double, data+1, sizeof(double));
+			return out_double;
 		}
 	}