Browse Source

fix: -Wunsafe-buffer-usage warnings when read()ing and write()ing integers (#44208)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <[email protected]>
trop[bot] 6 months ago
parent
commit
7887395e92
1 changed files with 35 additions and 24 deletions
  1. 35 24
      shell/browser/electron_browser_main_parts_posix.cc

+ 35 - 24
shell/browser/electron_browser_main_parts_posix.cc

@@ -25,6 +25,18 @@ namespace electron {
 
 namespace {
 
+// write |ref|'s raw bytes to |fd|.
+template <typename T>
+void WriteValToFd(int fd, const T& ref) {
+  base::span<const uint8_t> bytes = base::byte_span_from_ref(ref);
+  while (!bytes.empty()) {
+    const ssize_t rv = HANDLE_EINTR(write(fd, bytes.data(), bytes.size()));
+    RAW_CHECK(rv >= 0);
+    const size_t n_bytes_written = rv >= 0 ? static_cast<size_t>(rv) : 0U;
+    bytes = bytes.subspan(n_bytes_written);
+  }
+}
+
 // See comment in |PreEarlyInitialization()|, where sigaction is called.
 void SIGCHLDHandler(int signal) {}
 
@@ -49,15 +61,7 @@ void GracefulShutdownHandler(int signal) {
   RAW_CHECK(g_pipe_pid == getpid());
   RAW_CHECK(g_shutdown_pipe_write_fd != -1);
   RAW_CHECK(g_shutdown_pipe_read_fd != -1);
-  size_t bytes_written = 0;
-  do {
-    int rv = HANDLE_EINTR(
-        write(g_shutdown_pipe_write_fd,
-              reinterpret_cast<const char*>(&signal) + bytes_written,
-              sizeof(signal) - bytes_written));
-    RAW_CHECK(rv >= 0);
-    bytes_written += rv;
-  } while (bytes_written < sizeof(signal));
+  WriteValToFd(g_shutdown_pipe_write_fd, signal);
 }
 
 // See comment in |PostCreateMainMessageLoop()|, where sigaction is called.
@@ -130,26 +134,33 @@ NOINLINE void ExitPosted() {
   sleep(UINT_MAX);
 }
 
-void ShutdownDetector::ThreadMain() {
-  base::PlatformThread::SetName("CrShutdownDetector");
-
-  int signal;
-  size_t bytes_read = 0;
-  do {
-    const ssize_t ret = HANDLE_EINTR(
-        read(shutdown_fd_, reinterpret_cast<char*>(&signal) + bytes_read,
-             sizeof(signal) - bytes_read));
-    if (ret < 0) {
+// read |sizeof(T)| raw bytes from |fd| and return the result
+template <typename T>
+[[nodiscard]] std::optional<T> ReadValFromFd(int fd) {
+  auto val = T{};
+  base::span<uint8_t> bytes = base::byte_span_from_ref(val);
+  while (!bytes.empty()) {
+    const ssize_t rv = HANDLE_EINTR(read(fd, bytes.data(), bytes.size()));
+    if (rv < 0) {
       NOTREACHED_IN_MIGRATION() << "Unexpected error: " << strerror(errno);
       ShutdownFDReadError();
-      break;
-    } else if (ret == 0) {
+      return {};
+    }
+    if (rv == 0) {
       NOTREACHED_IN_MIGRATION() << "Unexpected closure of shutdown pipe.";
       ShutdownFDClosedError();
-      break;
+      return {};
     }
-    bytes_read += ret;
-  } while (bytes_read < sizeof(signal));
+    const size_t n_bytes_read = static_cast<size_t>(rv);
+    bytes = bytes.subspan(n_bytes_read);
+  }
+  return val;
+}
+
+void ShutdownDetector::ThreadMain() {
+  base::PlatformThread::SetName("CrShutdownDetector");
+
+  const int signal = ReadValFromFd<int>(shutdown_fd_).value_or(0);
   VLOG(1) << "Handling shutdown for signal " << signal << ".";
 
   if (!task_runner_->PostTask(FROM_HERE,