Bug 1493292 - GetStringSize instead of aDataLen. r=mats
authorTom Schuster <evilpies@gmail.com>
Tue, 20 Nov 2018 16:59:39 +0000
changeset 506464 29b3f0dfc6bb418b73a9cd519241b4ec38d0efbc
parent 506463 8f7476054232c929476c1a5112bb855f6ba7612f
child 506465 a58e50deefdc260cef3514c1552e4355ea5a6024
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs1493292
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1493292 - GetStringSize instead of aDataLen. r=mats Differential Revision: https://phabricator.services.mozilla.com/D11200
widget/nsTransferable.cpp
widget/nsTransferable.h
--- a/widget/nsTransferable.cpp
+++ b/widget/nsTransferable.cpp
@@ -53,32 +53,42 @@ DataStruct::DataStruct(DataStruct&& aRHS
 DataStruct::~DataStruct()
 {
   if (mCacheFD) {
     PR_Close(mCacheFD);
   }
 }
 
 //-------------------------------------------------------------------------
+
 void
 DataStruct::SetData(nsISupports* aData, uint32_t aDataLen, bool aIsPrivateData)
 {
   // Now, check to see if we consider the data to be "too large"
-  // as well as ensuring that private browsing mode is disabled
-  if (aDataLen > kLargeDatasetSize && !aIsPrivateData &&
-      // File IO is not allowed in content processes.
-      XRE_IsParentProcess()) {
-    // if so, cache it to disk instead of memory
-    if (NS_SUCCEEDED(WriteCache(aData, aDataLen))) {
-      // Clear previously set small data.
-      mData = nullptr;
-      mDataLen = 0;
-      return;
+  // as well as ensuring that private browsing mode is disabled.
+  // File IO is not allowed in content processes.
+  if (!aIsPrivateData && XRE_IsParentProcess()) {
+    void* data = nullptr;
+    uint32_t dataLen = 0;
+    nsPrimitiveHelpers::CreateDataFromPrimitive(mFlavor, aData, &data, &dataLen);
+
+    if (dataLen > kLargeDatasetSize) {
+      // Too large, cache it to disk instead of memory.
+      if (NS_SUCCEEDED(WriteCache(data, dataLen))) {
+        free(data);
+        // Clear previously set small data.
+        mData = nullptr;
+        mDataLen = 0;
+        return;
+      }
+
+      NS_WARNING("Oh no, couldn't write data to the cache file");
     }
-    NS_WARNING("Oh no, couldn't write data to the cache file");
+
+    free(data);
   }
 
   if (mCacheFD) {
     // Clear previously set big data.
     PR_Close(mCacheFD);
     mCacheFD = nullptr;
   }
 
@@ -109,39 +119,38 @@ DataStruct::GetData(nsISupports** aData,
 
   nsCOMPtr<nsISupports> data = mData;
   data.forget(aData);
   *aDataLen = mDataLen;
 }
 
 //-------------------------------------------------------------------------
 nsresult
-DataStruct::WriteCache(nsISupports* aData, uint32_t aDataLen)
+DataStruct::WriteCache(void* aData, uint32_t aDataLen)
 {
+  MOZ_ASSERT(aData && aDataLen);
+  MOZ_ASSERT(aDataLen <= uint32_t(std::numeric_limits<int32_t>::max()),
+             "too large size for PR_Write");
+
   nsresult rv;
   if (!mCacheFD) {
     rv = NS_OpenAnonymousTemporaryFile(&mCacheFD);
     if (NS_FAILED(rv)) {
       return NS_ERROR_FAILURE;
     }
   } else if (PR_Seek64(mCacheFD, 0, PR_SEEK_SET) == -1) {
     return NS_ERROR_FAILURE;
   }
 
-  // write out the contents of the clipboard to the file
-  void* buff = nullptr;
-  uint32_t dataLen = 0;
-  nsPrimitiveHelpers::CreateDataFromPrimitive(mFlavor, aData, &buff, &dataLen);
-  if (buff) {
-    int32_t written = PR_Write(mCacheFD, buff, dataLen);
-    free(buff);
-    if (written) {
-      return NS_OK;
-    }
+  // Write out the contents of the clipboard to the file.
+  int32_t written = PR_Write(mCacheFD, aData, aDataLen);
+  if (written == int32_t(aDataLen)) {
+    return NS_OK;
   }
+
   PR_Close(mCacheFD);
   mCacheFD = nullptr;
   return NS_ERROR_FAILURE;
 }
 
 //-------------------------------------------------------------------------
 nsresult
 DataStruct::ReadCache(nsISupports** aData, uint32_t* aDataLen)
--- a/widget/nsTransferable.h
+++ b/widget/nsTransferable.h
@@ -37,17 +37,17 @@ struct DataStruct
 protected:
 
   enum {
     // The size of data over which we write the data to disk rather than
     // keep it around in memory.
     kLargeDatasetSize = 1000000        // 1 million bytes
   };
   
-  nsresult WriteCache(nsISupports* aData, uint32_t aDataLen );
+  nsresult WriteCache(void* aData, uint32_t aDataLen);
   nsresult ReadCache(nsISupports** aData, uint32_t* aDataLen );
   
   // mData + mDataLen OR mCacheFD should be used, not both.
   nsCOMPtr<nsISupports> mData;   // OWNER - some varient of primitive wrapper
   uint32_t mDataLen;
   PRFileDesc* mCacheFD;
   const nsCString mFlavor;