fuzzers: Fix use-after-free

Diagnostics hold a pointer to the source, used for printing the source in the error message.
Because of this, the source must live at least as long as the diag::list.

Fixed: chromium:1232097
Change-Id: Iad8b30a2bd69f505dd8bb0eadc5a35115400d047
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59360
Auto-Submit: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/fuzzers/tint_common_fuzzer.cc b/fuzzers/tint_common_fuzzer.cc
index acc6f1d..49e770e 100644
--- a/fuzzers/tint_common_fuzzer.cc
+++ b/fuzzers/tint_common_fuzzer.cc
@@ -197,10 +197,6 @@
 
   Program program;
 
-#if TINT_BUILD_WGSL_READER
-  std::unique_ptr<Source::File> file;
-#endif  // TINT_BUILD_WGSL_READER
-
 #if TINT_BUILD_SPV_READER
   std::vector<uint32_t> spirv_input(size / sizeof(uint32_t));
 
@@ -209,9 +205,12 @@
   switch (input_) {
 #if TINT_BUILD_WGSL_READER
     case InputFormat::kWGSL: {
+      // Clear any existing diagnostics, as these will hold pointers to file_,
+      // which we are about to release.
+      diagnostics_ = {};
       std::string str(reinterpret_cast<const char*>(data), size);
-      file = std::make_unique<Source::File>("test.wgsl", str);
-      program = reader::wgsl::Parse(file.get());
+      file_ = std::make_unique<Source::File>("test.wgsl", str);
+      program = reader::wgsl::Parse(file_.get());
       break;
     }
 #endif  // TINT_BUILD_WGSL_READER
diff --git a/fuzzers/tint_common_fuzzer.h b/fuzzers/tint_common_fuzzer.h
index af90ee8..90c73e9 100644
--- a/fuzzers/tint_common_fuzzer.h
+++ b/fuzzers/tint_common_fuzzer.h
@@ -16,6 +16,7 @@
 #define FUZZERS_TINT_COMMON_FUZZER_H_
 
 #include <cstring>
+#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -169,6 +170,11 @@
   writer::wgsl::Options options_wgsl_;
   writer::hlsl::Options options_hlsl_;
   writer::msl::Options options_msl_;
+
+#if TINT_BUILD_WGSL_READER
+  /// The source file needs to live at least as long as #diagnostics_
+  std::unique_ptr<Source::File> file_;
+#endif  // TINT_BUILD_WGSL_READER
 };
 
 }  // namespace fuzzers