Bug 1389160 - use NSPR IO instead of raw fopen r?kmag draft
authorRobert Helmer <rhelmer@mozilla.com>
Wed, 16 Aug 2017 00:58:20 -0700
changeset 648426 6bc91e1a57c01bd041c979445ffed03bb6448676
parent 647460 6ebc251bd288c268b020815025b05854ccde5c08
child 726832 576f788fb3ae96c5230a9b4a7f27f440900fe506
push id74764
push userbmo:rhelmer@mozilla.com
push dateThu, 17 Aug 2017 19:47:28 +0000
reviewerskmag
bugs1389160
milestone57.0a1
Bug 1389160 - use NSPR IO instead of raw fopen r?kmag MozReview-Commit-ID: 6pJx1o2uboA
toolkit/mozapps/extensions/AddonManagerStartup.cpp
--- a/toolkit/mozapps/extensions/AddonManagerStartup.cpp
+++ b/toolkit/mozapps/extensions/AddonManagerStartup.cpp
@@ -132,41 +132,33 @@ CloneAndAppend(nsIFile* aFile, const cha
 
 static bool
 IsNormalFile(nsIFile* file)
 {
   bool result;
   return NS_SUCCEEDED(file->IsFile(&result)) && result;
 }
 
-static nsCString
-ReadFile(const char* path)
+static Result<nsCString, nsresult>
+ReadFile(nsIFile* file)
 {
   nsCString result;
 
-  FILE* fd = fopen(path, READ_BINARYMODE);
-  if (!fd) {
-    return result;
-  }
-  auto cleanup = MakeScopeExit([&] () {
-    fclose(fd);
-  });
+  AutoFDClose fd;
+  NS_TRY(file->OpenNSPRFileDesc(PR_RDONLY, 0, &fd.rwget()));
+
+  auto size = PR_Seek64(fd, 0, PR_SEEK_END);
+  PR_Seek64(fd, 0, PR_SEEK_SET);
 
-  if (fseek(fd, 0, SEEK_END) != 0) {
-    return result;
-  }
-  size_t len = ftell(fd);
-  if (len <= 0 || fseek(fd, 0, SEEK_SET) != 0) {
-    return result;
-  }
+  result.SetLength(size);
 
-  result.SetLength(len);
-  size_t rd = fread(result.BeginWriting(), sizeof(char), len, fd);
-  if (rd != len) {
-    result.Truncate();
+  auto len = PR_Read(fd, result.BeginWriting(), size);
+
+  if (size != len) {
+    return Err(NS_ERROR_FAILURE);
   }
 
   return result;
 }
 
 static const char STRUCTURED_CLONE_MAGIC[] = "mozJSSCLz40v001";
 
 template <typename T>
@@ -230,25 +222,27 @@ static_assert(sizeof STRUCTURED_CLONE_MA
 /**
  * Reads the contents of a LZ4-compressed file, as stored by the OS.File
  * module, and returns the decompressed contents on success.
  *
  * A nonexistent or empty file is treated as success. A corrupt or non-LZ4
  * file is treated as failure.
  */
 static Result<nsCString, nsresult>
-ReadFileLZ4(const char* path)
+ReadFileLZ4(nsIFile* file)
 {
   static const char MAGIC_NUMBER[] = "mozLz40";
 
   nsCString result;
 
-  nsCString lz4 = ReadFile(path);
+  nsCString lz4;
+  MOZ_TRY_VAR(lz4, ReadFile(file));
+
   if (lz4.IsEmpty()) {
-    return result;
+    return lz4;
   }
 
   return DecodeLZ4(lz4, MAGIC_NUMBER);
 }
 
 static bool
 ParseJSON(JSContext* cx, nsACString& jsonData, JS::MutableHandleValue result)
 {
@@ -619,21 +613,18 @@ AddonManagerStartup::AddInstallLocation(
 
 nsresult
 AddonManagerStartup::ReadStartupData(JSContext* cx, JS::MutableHandleValue locations)
 {
   locations.set(JS::UndefinedValue());
 
   nsCOMPtr<nsIFile> file = CloneAndAppend(ProfileDir(), "addonStartup.json.lz4");
 
-  nsCString path;
-  NS_TRY(file->GetNativePath(path));
-
   nsCString data;
-  MOZ_TRY_VAR(data, ReadFileLZ4(path.get()));
+  MOZ_TRY_VAR(data, ReadFileLZ4(file));
 
   if (data.IsEmpty() || !ParseJSON(cx, data, locations)) {
     return NS_OK;
   }
 
   if (!locations.isObject()) {
     return NS_ERROR_UNEXPECTED;
   }