# HG changeset patch
# User t_mrc-ct@users.sourceforge.jp
# Date 1382166306 -32400
# Branch GECKO2460_2014060612_RELBRANCH
# Node ID ce87d5cfab4f78d05e835cb2a89c2da465bc6613
# Parent  91b123e752741c41e72d3f4e2fbc6f081ec6f05b
M882130 fix bad endian-swap

diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -7,16 +7,17 @@
 #include "base/basictypes.h"
 
 #include "IDBObjectStore.h"
 
 #include "mozilla/dom/ipc/nsIRemoteBlob.h"
 #include "nsIOutputStream.h"
 
 #include "jsfriendapi.h"
+#include "mozilla/Endian.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/FileHandleBinding.h"
 #include "mozilla/dom/StructuredCloneTags.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "mozilla/dom/quota/FileStreams.h"
 #include "mozilla/storage.h"
 #include "nsContentUtils.h"
@@ -46,16 +47,17 @@
 
 #include "IndexedDatabaseInlines.h"
 
 #define FILE_COPY_BUFFER_SIZE 32768
 
 USING_INDEXEDDB_NAMESPACE
 using namespace mozilla::dom;
 using namespace mozilla::dom::indexedDB::ipc;
+using mozilla::NativeEndian;
 using mozilla::dom::quota::FileOutputStream;
 
 BEGIN_INDEXEDDB_NAMESPACE
 
 struct FileHandleData
 {
   nsString type;
   nsString name;
@@ -1266,56 +1268,26 @@
     nullptr
   };
 
   JSAutoStructuredCloneBuffer& buffer = aCloneWriteInfo.mCloneBuffer;
 
   return buffer.write(aCx, aValue, &callbacks, &aCloneWriteInfo);
 }
 
-static inline uint32_t
-SwapBytes(uint32_t u)
-{
-#ifdef IS_BIG_ENDIAN
-  return ((u & 0x000000ffU) << 24) |
-         ((u & 0x0000ff00U) << 8) |
-         ((u & 0x00ff0000U) >> 8) |
-         ((u & 0xff000000U) >> 24);
-#else
-  return u;
-#endif
-}
-
-static inline double
-SwapBytes(uint64_t u)
-{
-#ifdef IS_BIG_ENDIAN
-  return ((u & 0x00000000000000ffLLU) << 56) |
-         ((u & 0x000000000000ff00LLU) << 40) |
-         ((u & 0x0000000000ff0000LLU) << 24) |
-         ((u & 0x00000000ff000000LLU) << 8) |
-         ((u & 0x000000ff00000000LLU) >> 8) |
-         ((u & 0x0000ff0000000000LLU) >> 24) |
-         ((u & 0x00ff000000000000LLU) >> 40) |
-         ((u & 0xff00000000000000LLU) >> 56);
-#else
-  return double(u);
-#endif
-}
-
 static inline bool
 StructuredCloneReadString(JSStructuredCloneReader* aReader,
                           nsCString& aString)
 {
   uint32_t length;
   if (!JS_ReadBytes(aReader, &length, sizeof(uint32_t))) {
     NS_WARNING("Failed to read length!");
     return false;
   }
-  length = SwapBytes(length);
+  length = NativeEndian::swapFromLittleEndian(length);
 
   if (!aString.SetLength(length, mozilla::fallible_t())) {
     NS_WARNING("Out of memory?");
     return false;
   }
   char* buffer = aString.BeginWriting();
 
   if (!JS_ReadBytes(aReader, buffer, length)) {
@@ -1368,37 +1340,42 @@
   aRetval->tag = aTag;
 
   // If it's not a FileHandle, it's a Blob or a File.
   uint64_t size;
   if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
     NS_WARNING("Failed to read size!");
     return false;
   }
-  aRetval->size = SwapBytes(size);
+  aRetval->size = NativeEndian::swapFromLittleEndian(size);
 
   nsCString type;
   if (!StructuredCloneReadString(aReader, type)) {
     return false;
   }
   CopyUTF8toUTF16(type, aRetval->type);
 
   // Blobs are done.
   if (aTag == SCTAG_DOM_BLOB) {
     return true;
   }
 
   NS_ASSERTION(aTag == SCTAG_DOM_FILE ||
                aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE, "Huh?!");
 
-  uint64_t lastModifiedDate = UINT64_MAX;
-  if (aTag != SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE &&
-      !JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
-    NS_WARNING("Failed to read lastModifiedDate");
-    return false;
+  uint64_t lastModifiedDate;
+  if (aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE) {
+    lastModifiedDate = UINT64_MAX;
+  }
+  else {
+    if (!JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
+      NS_WARNING("Failed to read lastModifiedDate");
+      return false;
+    }
+    lastModifiedDate = NativeEndian::swapFromLittleEndian(lastModifiedDate);
   }
   aRetval->lastModifiedDate = lastModifiedDate;
 
   nsCString name;
   if (!StructuredCloneReadString(aReader, name)) {
     return false;
   }
   CopyUTF8toUTF16(name, aRetval->name);
@@ -1479,16 +1456,17 @@
     reinterpret_cast<StructuredCloneWriteInfo*>(aClosure);
 
   if (JS_GetClass(aObj) == &sDummyPropJSClass) {
     NS_ASSERTION(cloneWriteInfo->mOffsetToKeyProp == 0,
                  "We should not have been here before!");
     cloneWriteInfo->mOffsetToKeyProp = js_GetSCOffset(aWriter);
 
     uint64_t value = 0;
+    // omit endian swap
     return JS_WriteBytes(aWriter, &value, sizeof(value));
   }
 
   IDBTransaction* transaction = cloneWriteInfo->mTransaction;
   FileManager* fileManager = transaction->Database()->Manager();
 
   file::FileHandle* fileHandle = nullptr;
   if (NS_SUCCEEDED(UnwrapObject<file::FileHandle>(aCx, aObj, fileHandle))) {
@@ -1496,20 +1474,20 @@
 
     // Throw when trying to store non IDB file handles or IDB file handles
     // across databases.
     if (!fileInfo || fileInfo->Manager() != fileManager) {
       return false;
     }
 
     NS_ConvertUTF16toUTF8 convType(fileHandle->Type());
-    uint32_t convTypeLength = SwapBytes(convType.Length());
+    uint32_t convTypeLength = NativeEndian::swapToLittleEndian(convType.Length());
 
     NS_ConvertUTF16toUTF8 convName(fileHandle->Name());
-    uint32_t convNameLength = SwapBytes(convName.Length());
+    uint32_t convNameLength = NativeEndian::swapToLittleEndian(convName.Length());
 
     if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_FILEHANDLE,
                             cloneWriteInfo->mFiles.Length()) ||
         !JS_WriteBytes(aWriter, &convTypeLength, sizeof(uint32_t)) ||
         !JS_WriteBytes(aWriter, convType.get(), convType.Length()) ||
         !JS_WriteBytes(aWriter, &convNameLength, sizeof(uint32_t)) ||
         !JS_WriteBytes(aWriter, convName.get(), convName.Length())) {
       return false;
@@ -1554,25 +1532,25 @@
         }
       }
 
       uint64_t size;
       if (NS_FAILED(blob->GetSize(&size))) {
         NS_WARNING("Failed to get size!");
         return false;
       }
-      size = SwapBytes(size);
+      size = NativeEndian::swapToLittleEndian(size);
 
       nsString type;
       if (NS_FAILED(blob->GetType(type))) {
         NS_WARNING("Failed to get type!");
         return false;
       }
       NS_ConvertUTF16toUTF8 convType(type);
-      uint32_t convTypeLength = SwapBytes(convType.Length());
+      uint32_t convTypeLength = NativeEndian::swapToLittleEndian(convType.Length());
 
       nsCOMPtr<nsIDOMFile> file = do_QueryInterface(blob);
 
       if (!JS_WriteUint32Pair(aWriter, file ? SCTAG_DOM_FILE : SCTAG_DOM_BLOB,
                               cloneWriteInfo->mFiles.Length()) ||
           !JS_WriteBytes(aWriter, &size, sizeof(size)) ||
           !JS_WriteBytes(aWriter, &convTypeLength, sizeof(convTypeLength)) ||
           !JS_WriteBytes(aWriter, convType.get(), convType.Length())) {
@@ -1581,25 +1559,25 @@
 
       if (file) {
         uint64_t lastModifiedDate = 0;
         if (NS_FAILED(file->GetMozLastModifiedDate(&lastModifiedDate))) {
           NS_WARNING("Failed to get last modified date!");
           return false;
         }
 
-        lastModifiedDate = SwapBytes(lastModifiedDate);
+        lastModifiedDate = NativeEndian::swapToLittleEndian(lastModifiedDate);
 
         nsString name;
         if (NS_FAILED(file->GetName(name))) {
           NS_WARNING("Failed to get name!");
           return false;
         }
         NS_ConvertUTF16toUTF8 convName(name);
-        uint32_t convNameLength = SwapBytes(convName.Length());
+        uint32_t convNameLength = NativeEndian::swapToLittleEndian(convName.Length());
 
         if (!JS_WriteBytes(aWriter, &lastModifiedDate, sizeof(lastModifiedDate)) || 
             !JS_WriteBytes(aWriter, &convNameLength, sizeof(convNameLength)) ||
             !JS_WriteBytes(aWriter, convName.get(), convName.Length())) {
           return false;
         }
       }
 
@@ -3010,17 +2988,20 @@
       // which row id we would get above before we could set that properly.
 
       // This is a duplicate of the js engine's byte munging here
       union {
         double d;
         uint64_t u;
       } pun;
     
-      pun.d = SwapBytes(static_cast<uint64_t>(autoIncrementNum));
+      NS_ASSERTION(autoIncrementNum > 0,
+                   "Generated key is always a positive integer");
+      pun.d = static_cast<double>(autoIncrementNum);
+      pun.u = NativeEndian::swapToLittleEndian(pun.u);
 
       JSAutoStructuredCloneBuffer& buffer = mCloneWriteInfo.mCloneBuffer;
       uint64_t offsetToKeyProp = mCloneWriteInfo.mOffsetToKeyProp;
 
       memcpy((char*)buffer.data() + offsetToKeyProp, &pun.u, sizeof(uint64_t));
     }
   }
 
