Repository: electron/electron
Pull request: fix: -Wunsafe-buffer-usage warnings in asar file IO

#### Description of Change

Part 3 in a [series](https://github.com/electron/electron/pull/43477) to fix `-Wunsafe-buffer-usage` warnings in electron `shell/`.

This PR fixes warnings in `asar::Archive::Init()` and `ScopedTemporaryFile::InitFromFile()` by replacing `base::File` API calls marked `UNSAFE_BUFFER_USAGE` (examples: [1](https://chromium.googlesource.com/chromium/src/+/main/base/files/file.h#224), [2](https://chromium.googlesource.com/chromium/src/+/main/base/files/file.h#228)) with their safer counterparts. See also #43592, which was a prerequisite for this PR.

Warnings fixed by this PR:

```
../../electron/shell/common/asar/archive.cc:210:11: error: function introduces unsafe buffer manipulation [-Werror,-Wunsafe-buffer-usage]
  210 |     len = file_.ReadAtCurrentPos(buf.data(), buf.size());
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../electron/shell/common/asar/archive.cc:210:11: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions

../../electron/shell/common/asar/archive.cc:227:11: error: function introduces unsafe buffer manipulation [-Werror,-Wunsafe-buffer-usage]
  227 |     len = file_.ReadAtCurrentPos(buf.data(), buf.size());
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../electron/shell/common/asar/archive.cc:227:11: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions

../../electron/shell/common/asar/scoped_temporary_file.cc:66:13: error: function introduces unsafe buffer manipulation [-Werror,-Wunsafe-buffer-usage]
   66 |   int len = src->Read(offset, buf.data(), buf.size());
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../electron/shell/common/asar/scoped_temporary_file.cc:66:13: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions

../../electron/shell/common/asar/scoped_temporary_file.cc:77:10: error: function introduces unsafe buffer manipulation [-Werror,-Wunsafe-buffer-usage]
   77 |   return dest.WriteAtCurrentPos(buf.data(), buf.size()) ==
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../electron/shell/common/asar/scoped_temporary_file.cc:77:10: note: pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions
```


#### Checklist

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: none.

Changed files:
filename: shell/common/asar/archive.cc
patch: @@ -201,39 +201,34 @@ bool Archive::Init() {
     return false;
   }
 
-  std::vector<char> buf;
-  int len;
+  std::vector<uint8_t> buf;
 
   buf.resize(8);
   {
     electron::ScopedAllowBlockingForElectron allow_blocking;
-    len = file_.ReadAtCurrentPos(buf.data(), buf.size());
-  }
-  if (len != static_cast<int>(buf.size())) {
-    PLOG(ERROR) << "Failed to read header size from " << path_.value();
-    return false;
+    if (!file_.ReadAtCurrentPosAndCheck(buf)) {
+      PLOG(ERROR) << "Failed to read header size from " << path_.value();
+      return false;
+    }
   }
 
   uint32_t size;
-  if (!base::PickleIterator(base::Pickle::WithData(base::as_byte_span(buf)))
-           .ReadUInt32(&size)) {
+  if (!base::PickleIterator(base::Pickle::WithData(buf)).ReadUInt32(&size)) {
     LOG(ERROR) << "Failed to parse header size from " << path_.value();
     return false;
   }
 
   buf.resize(size);
   {
     electron::ScopedAllowBlockingForElectron allow_blocking;
-    len = file_.ReadAtCurrentPos(buf.data(), buf.size());
-  }
-  if (len != static_cast<int>(buf.size())) {
-    PLOG(ERROR) << "Failed to read header from " << path_.value();
-    return false;
+    if (!file_.ReadAtCurrentPosAndCheck(buf)) {
+      PLOG(ERROR) << "Failed to read header from " << path_.value();
+      return false;
+    }
   }
 
   std::string header;
-  if (!base::PickleIterator(base::Pickle::WithData(base::as_byte_span(buf)))
-           .ReadString(&header)) {
+  if (!base::PickleIterator(base::Pickle::WithData(buf)).ReadString(&header)) {
     LOG(ERROR) << "Failed to parse header from " << path_.value();
     return false;
   }

filename: shell/common/asar/scoped_temporary_file.cc
patch: @@ -62,20 +62,15 @@ bool ScopedTemporaryFile::InitFromFile(
     return false;
 
   electron::ScopedAllowBlockingForElectron allow_blocking;
-  std::vector<char> buf(size);
-  int len = src->Read(offset, buf.data(), buf.size());
-  if (len != static_cast<int>(size))
+  std::vector<uint8_t> buf(size);
+  if (!src->ReadAndCheck(offset, buf))
     return false;
 
   if (integrity)
-    ValidateIntegrityOrDie(base::as_byte_span(buf), *integrity);
+    ValidateIntegrityOrDie(buf, *integrity);
 
   base::File dest(path_, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
-  if (!dest.IsValid())
-    return false;
-
-  return dest.WriteAtCurrentPos(buf.data(), buf.size()) ==
-         static_cast<int>(size);
+  return dest.IsValid() && dest.WriteAtCurrentPosAndCheck(buf);
 }
 
 }  // namespace asar