Bug 715074 - SIGBUS on unaligned access in Key::EncodeNumber. r=sicking
authorJan Varga <jan.varga@gmail.com>
Fri, 06 Jan 2012 10:56:52 +0100
changeset 85095 8ae16e346bd0c2c93711884b2a2e5db10060512d
parent 85094 c7e27452a143c834a4d1d7acf8c202261504210c
child 85118 fcc32e70c95fdbb491100259f35742d1b45c0cd9
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs715074
milestone12.0a1
Bug 715074 - SIGBUS on unaligned access in Key::EncodeNumber. r=sicking
dom/indexedDB/Key.cpp
--- a/dom/indexedDB/Key.cpp
+++ b/dom/indexedDB/Key.cpp
@@ -35,16 +35,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "Key.h"
 #include "nsIStreamBufferAccess.h"
 #include "jsdate.h"
+#include "nsAlgorithm.h"
 #include "nsContentUtils.h"
 #include "nsJSUtils.h"
 #include "xpcpublic.h"
 
 USING_INDEXEDDB_NAMESPACE
 
 /*
  Here's how we encode keys:
@@ -406,38 +407,34 @@ Key::EncodeNumber(double aFloat, PRUint8
   *(buffer++) = aType;
 
   Float64Union pun;
   pun.d = aFloat;
   PRUint64 number = pun.u & PR_UINT64(0x8000000000000000) ?
                     -pun.u :
                     (pun.u | PR_UINT64(0x8000000000000000));
 
-  *reinterpret_cast<PRUint64*>(buffer) = NS_SWAP64(number);
+  number = NS_SWAP64(number);
+  memcpy(buffer, &number, sizeof(number));
 }
 
 // static
 double
 Key::DecodeNumber(const unsigned char*& aPos, const unsigned char* aEnd)
 {
   NS_ASSERTION(*aPos % eMaxType == eFloat ||
                *aPos % eMaxType == eDate, "Don't call me!");
 
   ++aPos;
+
   PRUint64 number = 0;
-  for (PRInt32 n = 7; n >= 0; --n) {
-    number <<= 8;
-    if (aPos < aEnd) {
-      number |= *(aPos++);
-    }
-    else {
-      number <<= 8 * n;
-      break;
-    }
-  }
+  memcpy(&number, aPos, NS_MIN<size_t>(sizeof(number), aEnd - aPos));
+  number = NS_SWAP64(number);
+
+  aPos += sizeof(number);
 
   Float64Union pun;
   pun.u = number & PR_UINT64(0x8000000000000000) ?
           (number & ~PR_UINT64(0x8000000000000000)) :
           -number;
 
   return pun.d;
 }