Backed out changeset dff1e1774422 (bug 335545) for failing clipboard mochitest widget/tests/test_bug1123480.xul on Linux x64 asan. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 21 Sep 2017 00:00:52 +0200
changeset 382062 6694f4b93826511dd254dd36a7044891329beaf2
parent 382061 e8f4ef8801fbe8013a7cb0eeb5a7fae23db19edf
child 382063 e0d1b299d389229ca7d5f66dcb13663824314583
push id32546
push userarchaeopteryx@coole-files.de
push dateThu, 21 Sep 2017 13:14:27 +0000
treeherdermozilla-central@9caeafcec998 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs335545, 1123480
milestone57.0a1
backs outdff1e1774422c12aacff69538936e88f0ff95c85
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
Backed out changeset dff1e1774422 (bug 335545) for failing clipboard mochitest widget/tests/test_bug1123480.xul on Linux x64 asan. r=backout
widget/nsTransferable.cpp
widget/nsTransferable.h
--- a/widget/nsTransferable.cpp
+++ b/widget/nsTransferable.cpp
@@ -9,17 +9,16 @@ Notes to self:
 - at some point, strings will be accessible from JS, so we won't have to wrap
    flavors in an nsISupportsCString. Until then, we're kinda stuck with
    this crappy API of nsIArrays.
 
 */
 
 
 #include "nsTransferable.h"
-#include "nsAnonymousTemporaryFile.h"
 #include "nsArray.h"
 #include "nsArrayUtils.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsTArray.h"
 #include "nsIFormatConverter.h"
 #include "nsIContentPolicy.h"
 #include "nsIComponentManager.h"
@@ -31,16 +30,17 @@ Notes to self:
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryService.h"
 #include "nsCRT.h"
 #include "nsNetUtil.h"
 #include "nsIDOMNode.h"
 #include "nsIOutputStream.h"
 #include "nsIInputStream.h"
 #include "nsIWeakReferenceUtils.h"
+#include "nsIFile.h"
 #include "nsILoadContext.h"
 #include "mozilla/UniquePtr.h"
 
 NS_IMPL_ISUPPORTS(nsTransferable, nsITransferable)
 
 size_t GetDataForFlavor (const nsTArray<DataStruct>& aArray,
                            const char* aDataFlavor)
 {
@@ -50,19 +50,17 @@ size_t GetDataForFlavor (const nsTArray<
   }
 
   return aArray.NoIndex;
 }
 
 //-------------------------------------------------------------------------
 DataStruct::~DataStruct()
 {
-  if (mCacheFD) {
-    PR_Close(mCacheFD);
-  }
+  if (mCacheFileName) free(mCacheFileName);
 }
 
 //-------------------------------------------------------------------------
 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
@@ -79,17 +77,17 @@ DataStruct::SetData ( nsISupports* aData
 }
 
 
 //-------------------------------------------------------------------------
 void
 DataStruct::GetData ( nsISupports** aData, uint32_t *aDataLen )
 {
   // check here to see if the data is cached on disk
-  if ( !mData && mCacheFD ) {
+  if ( !mData && mCacheFileName ) {
     // if so, read it in and pass it back
     // ReadCache creates memory and copies the data into it.
     if ( NS_SUCCEEDED(ReadCache(aData, aDataLen)) )
       return;
     else {
       // oh shit, something went horribly wrong here.
       NS_WARNING("Oh no, couldn't read data in from the cache file");
       *aData = nullptr;
@@ -101,68 +99,125 @@ DataStruct::GetData ( nsISupports** aDat
   *aData = mData;
   if ( mData )
     NS_ADDREF(*aData);
   *aDataLen = mDataLen;
 }
 
 
 //-------------------------------------------------------------------------
+already_AddRefed<nsIFile>
+DataStruct::GetFileSpec(const char* aFileName)
+{
+  nsCOMPtr<nsIFile> cacheFile;
+  NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(cacheFile));
+
+  if (!cacheFile)
+    return nullptr;
+
+  // if the param aFileName contains a name we should use that
+  // because the file probably already exists
+  // otherwise create a unique name
+  if (!aFileName) {
+    cacheFile->AppendNative(NS_LITERAL_CSTRING("clipboardcache"));
+    nsresult rv = cacheFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
+    if (NS_FAILED(rv))
+      return nullptr;
+  } else {
+    cacheFile->AppendNative(nsDependentCString(aFileName));
+  }
+
+  return cacheFile.forget();
+}
+
+
+//-------------------------------------------------------------------------
 nsresult
 DataStruct::WriteCache(nsISupports* aData, uint32_t aDataLen)
 {
-  nsresult rv;
-  if (!mCacheFD) {
-    rv = NS_OpenAnonymousTemporaryFile(&mCacheFD);
-    if (NS_FAILED(rv)) {
-      return NS_ERROR_FAILURE;
+  // Get a new path and file to the temp directory
+  nsCOMPtr<nsIFile> cacheFile = GetFileSpec(mCacheFileName);
+  if (cacheFile) {
+    // remember the file name
+    if (!mCacheFileName) {
+      nsCString fName;
+      cacheFile->GetNativeLeafName(fName);
+      mCacheFileName = strdup(fName.get());
     }
-  }
 
-  // write out the contents of the clipboard to the file
-  void* buff = nullptr;
-  nsPrimitiveHelpers::CreateDataFromPrimitive(mFlavor, aData, &buff, aDataLen);
-  if (buff) {
-    int32_t written = PR_Write(mCacheFD, buff, aDataLen);
-    free(buff);
-    if (written) {
+    // write out the contents of the clipboard
+    // to the file
+    //uint32_t bytes;
+    nsCOMPtr<nsIOutputStream> outStr;
+
+    NS_NewLocalFileOutputStream(getter_AddRefs(outStr),
+                                cacheFile);
+
+    if (!outStr) return NS_ERROR_FAILURE;
+
+    void* buff = nullptr;
+    nsPrimitiveHelpers::CreateDataFromPrimitive ( mFlavor, aData, &buff, aDataLen );
+    if ( buff ) {
+      uint32_t ignored;
+      outStr->Write(reinterpret_cast<char*>(buff), aDataLen, &ignored);
+      free(buff);
       return NS_OK;
     }
   }
   return NS_ERROR_FAILURE;
 }
 
 
 //-------------------------------------------------------------------------
 nsresult
 DataStruct::ReadCache(nsISupports** aData, uint32_t* aDataLen)
 {
-  if (!mCacheFD) {
+  // if we don't have a cache filename we are out of luck
+  if (!mCacheFileName)
     return NS_ERROR_FAILURE;
+
+  // get the path and file name
+  nsCOMPtr<nsIFile> cacheFile = GetFileSpec(mCacheFileName);
+  bool exists;
+  if ( cacheFile && NS_SUCCEEDED(cacheFile->Exists(&exists)) && exists ) {
+    // get the size of the file
+    int64_t fileSize;
+    int64_t max32 = 0xFFFFFFFF;
+    cacheFile->GetFileSize(&fileSize);
+    if (fileSize > max32)
+      return NS_ERROR_OUT_OF_MEMORY;
+
+    uint32_t size = uint32_t(fileSize);
+    // create new memory for the large clipboard data
+    auto data = mozilla::MakeUnique<char[]>(size);
+    if ( !data )
+      return NS_ERROR_OUT_OF_MEMORY;
+
+    // now read it all in
+    nsCOMPtr<nsIInputStream> inStr;
+    NS_NewLocalFileInputStream( getter_AddRefs(inStr),
+                                cacheFile);
+
+    if (!cacheFile) return NS_ERROR_FAILURE;
+
+    nsresult rv = inStr->Read(data.get(), fileSize, aDataLen);
+
+    // make sure we got all the data ok
+    if (NS_SUCCEEDED(rv) && *aDataLen == size) {
+      nsPrimitiveHelpers::CreatePrimitiveForData(mFlavor, data.get(),
+                                                 fileSize, aData);
+      return *aData ? NS_OK : NS_ERROR_FAILURE;
+    }
+
+    // zero the return params
+    *aData    = nullptr;
+    *aDataLen = 0;
   }
 
-  PRFileInfo fileInfo;
-  if (PR_GetOpenFileInfo(mCacheFD, &fileInfo) != PR_SUCCESS) {
-    return NS_ERROR_FAILURE;
-  }
-  uint32_t fileSize = fileInfo.size;
-
-  auto data = mozilla::MakeUnique<char[]>(fileSize);
-  if (!data) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  uint32_t actual = PR_Read(mCacheFD, data.get(), fileSize);
-  // actual = 0 means end of file.
-  if (actual != 0 && actual != fileSize) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsPrimitiveHelpers::CreatePrimitiveForData(mFlavor, data.get(), fileSize, aData);
-  return NS_OK;
+  return NS_ERROR_FAILURE;
 }
 
 
 //-------------------------------------------------------------------------
 //
 // Transferable constructor
 //
 //-------------------------------------------------------------------------
--- a/widget/nsTransferable.h
+++ b/widget/nsTransferable.h
@@ -7,51 +7,51 @@
 #define nsTransferable_h__
 
 #include "nsIFormatConverter.h"
 #include "nsITransferable.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsIPrincipal.h"
-#include "prio.h"
 
 class nsIMutableArray;
 
 //
 // DataStruct
 //
 // Holds a flavor (a mime type) that describes the data and the associated data.
 //
 struct DataStruct
 {
   explicit DataStruct ( const char* aFlavor )
-    : mDataLen(0), mCacheFD(nullptr), mFlavor(aFlavor) { }
+    : mDataLen(0), mFlavor(aFlavor), mCacheFileName(nullptr) { }
   ~DataStruct();
   
   const nsCString& GetFlavor() const { return mFlavor; }
   void SetData( nsISupports* inData, uint32_t inDataLen, bool aIsPrivateData );
   void GetData( nsISupports** outData, uint32_t *outDataLen );
-  bool IsDataAvailable() const { return mData ? mDataLen > 0 : mCacheFD != nullptr; }
+  already_AddRefed<nsIFile> GetFileSpec(const char* aFileName);
+  bool IsDataAvailable() const { return (mData && mDataLen > 0) || (!mData && mCacheFileName); }
   
 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 ReadCache(nsISupports** aData, uint32_t* aDataLen );
   
   nsCOMPtr<nsISupports> mData;   // OWNER - some varient of primitive wrapper
   uint32_t mDataLen;
-  PRFileDesc* mCacheFD;
   const nsCString mFlavor;
+  char *   mCacheFileName;
 
 };
 
 /**
  * XP Transferable wrapper
  */
 
 class nsTransferable : public nsITransferable