Merge pull request #1724 from abhijeetk:windows-stdout-macro-conflict

PiperOrigin-RevId: 767136403
diff --git a/.github/workflows/bazel_test.yml b/.github/workflows/bazel_test.yml
index 62048e0..5918f8a 100644
--- a/.github/workflows/bazel_test.yml
+++ b/.github/workflows/bazel_test.yml
@@ -47,7 +47,7 @@
             clang
       - name: Setup --config=fuzztest for Bazel
         run: |
-          bazel run //bazel:setup_configs > fuzztest.bazelrc
+          EXTRA_CONFIGS=libfuzzer bazel run //bazel:setup_configs > fuzztest.bazelrc
       - name: Restore latest cache
         uses: actions/cache/restore@v4
         with:
@@ -59,11 +59,6 @@
         run: |
           bazel test --build_tests_only --test_output=errors \
             -c ${{ matrix.compilation_mode }} -- //... -//centipede/...
-      - name: Build test for the compatibility mode
-        if: matrix.config == 'default'
-        run: |
-          bazel build -c ${{ matrix.compilation_mode }} \
-            --copt=-DFUZZTEST_COMPATIBILITY_MODE -- //fuzztest/internal:compatibility_mode
       - name: Run end-to-end tests with --config=fuzztest
         if: matrix.config == 'fuzztest'
         run: |
@@ -77,6 +72,13 @@
             --config=fuzztest-experimental --config=asan \
             --platform_suffix=fuzztest-experimental-asan \
             //e2e_tests:corpus_database_test
+      - name: Run end-to-end tests with --config=libfuzzer
+        if: matrix.config == 'fuzztest'
+        run: |
+          bazel test --build_tests_only --test_output=errors \
+            -c ${{ matrix.compilation_mode }} --config=libfuzzer \
+            --platform_suffix=fuzztest-libfuzzer \
+            //e2e_tests:compatibility_mode_test
       - name: Save new cache based on main
         if: github.ref == 'refs/heads/main'
         uses: actions/cache/save@v4
diff --git a/cmake/FuzzTestHelpers.cmake b/cmake/FuzzTestHelpers.cmake
index 0448aa9..31a7db4 100644
--- a/cmake/FuzzTestHelpers.cmake
+++ b/cmake/FuzzTestHelpers.cmake
@@ -268,3 +268,74 @@
   add_test(NAME ${_NAME} COMMAND ${_NAME})
 
 endfunction()
+
+# fuzztest_proto_library()
+#
+# CMake function to imitate Bazel's proto_library rule.
+#
+# Parameters:
+#
+#   NAME: Name of target (see Note)
+#   SRCS: List of source files for the proto library
+#   PUBLIC: Add this so that this library will be exported under fuzztest::
+#   TESTONLY: When added, this target will only be built if both
+#             BUILD_TESTING=ON and FUZZTEST_BUILD_TESTING=ON.
+#
+# Usage:
+#
+#   fuzztest_proto_library(
+#     NAME
+#       awesome_proto
+#     SRCS
+#       "awesome.proto"
+#   )
+#
+# Reference:
+#
+#   https://github.com/protocolbuffers/protobuf/blob/main/docs/cmake_protobuf_generate.md
+#
+function(fuzztest_proto_library)
+  cmake_parse_arguments(
+    FUZZTEST_PROTO_LIB
+    "PUBLIC;TESTONLY"
+    "NAME"
+    "SRCS"
+    ${ARGN}
+  )
+
+  if(FUZZTEST_PROTO_LIB_TESTONLY AND NOT (BUILD_TESTING AND FUZZTEST_BUILD_TESTING))
+    return()
+  endif()
+
+  set(_NAME "fuzztest_${FUZZTEST_PROTO_LIB_NAME}")
+
+  add_library(
+    ${_NAME}
+    OBJECT
+    ${FUZZTEST_PROTO_LIB_SRCS}
+  )
+
+  target_link_libraries(
+    ${_NAME}
+    PUBLIC
+    protobuf::libprotobuf
+  )
+
+  target_include_directories(
+    ${_NAME}
+    PUBLIC
+    "$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}>"
+  )
+
+  protobuf_generate(
+    TARGET
+    ${_NAME}
+    IMPORT_DIRS
+    ${CMAKE_CURRENT_LIST_DIR}
+    PROTOC_OUT_DIR
+    ${CMAKE_CURRENT_BINARY_DIR}
+  )
+
+  add_library(fuzztest::${FUZZTEST_PROTO_LIB_NAME} ALIAS ${_NAME})
+
+endfunction()
\ No newline at end of file
diff --git a/domain_tests/CMakeLists.txt b/domain_tests/CMakeLists.txt
index e963ffd..4a858b0 100644
--- a/domain_tests/CMakeLists.txt
+++ b/domain_tests/CMakeLists.txt
@@ -30,7 +30,7 @@
     absl::random_bit_gen_ref
     absl::strings
     fuzztest::domain
-    test_protobuf
+    fuzztest::test_protobuf_cc_proto
     GTest::gmock_main
     protobuf::libprotobuf
 )
@@ -49,7 +49,7 @@
     absl::time
     fuzztest::domain_core
     fuzztest::serialization
-    test_protobuf
+    fuzztest::test_protobuf_cc_proto
     fuzztest::type_support
     GTest::gmock_main
 )
@@ -101,7 +101,7 @@
     fuzztest::logging
     fuzztest::meta
     fuzztest::serialization
-    test_protobuf
+    fuzztest::test_protobuf_cc_proto
     fuzztest::type_support
     GTest::gtest
     protobuf::libprotobuf
diff --git a/domain_tests/container_test.cc b/domain_tests/container_test.cc
index d27bdd9..08fd0dc 100644
--- a/domain_tests/container_test.cc
+++ b/domain_tests/container_test.cc
@@ -41,6 +41,7 @@
 
 using ::testing::Contains;
 using ::testing::Gt;
+using ::testing::Not;
 using ::testing::SizeIs;
 using ::testing::UnorderedElementsAre;
 
@@ -262,5 +263,40 @@
                        }));
 }
 
+TEST(Container, ValidatesMemoryDictionaryMutationForInnerDomain) {
+  auto domain = VectorOf(InRange<uint8_t>(10, 128));
+  internal::TablesOfRecentCompares cmp_tables;
+  std::vector<std::vector<uint8_t>> cmp_entries = {{10, 11, 12, 13},
+                                                   {129, 129, 129, 129},
+                                                   {10, 11, 12, 13},
+                                                   {17, 31, 113, 71}};
+  // Fill the table with the same entries repeatly.
+  for (int i = 0; i < cmp_tables.GetMutable<0>().kTableSize; ++i) {
+    cmp_tables.GetMutable<0>().Insert(cmp_entries[0].data(),
+                                      cmp_entries[1].data(), 4);
+    cmp_tables.GetMutable<0>().Insert(cmp_entries[2].data(),
+                                      cmp_entries[3].data(), 4);
+  }
+
+  absl::BitGen bitgen;
+  std::vector<std::vector<uint8_t>> mutants;
+  const double hit_probability =  //
+      1.0 / 4                     // to use dictionaries
+      * 1.0 / 4                   // to use cmp tables
+      * 1.0 / 2                   // to pick the memcmp table
+      * 1.0 / 2                   // to pick one of the entries
+      * 1.0 / 2                   // to apply replacement
+      ;
+  for (int i = 0; i < 1 * IterationsToHitAll(/*num_cases=*/2, hit_probability);
+       ++i) {
+    std::vector<uint8_t> mutant = {10, 11, 12, 13};
+    domain.Mutate(mutant, bitgen, {/*cmp_tables=*/&cmp_tables}, false);
+    mutants.push_back(std::move(mutant));
+  }
+
+  EXPECT_THAT(mutants, Contains(std::vector<uint8_t>{17, 31, 113, 71}));
+  EXPECT_THAT(mutants, Not(Contains(std::vector<uint8_t>{129, 129, 129, 129})));
+}
+
 }  // namespace
 }  // namespace fuzztest
diff --git a/e2e_tests/BUILD b/e2e_tests/BUILD
index 9f85b8d..78cb11b 100644
--- a/e2e_tests/BUILD
+++ b/e2e_tests/BUILD
@@ -97,6 +97,32 @@
     ],
 )
 
+# Must be run with `--config=libfuzzer`
+cc_test(
+    name = "compatibility_mode_test",
+    timeout = "long",
+    srcs = ["compatibility_mode_test.cc"],
+    data = [
+        "@com_google_fuzztest//e2e_tests/testdata:fuzz_tests_for_functional_testing.stripped",
+    ],
+    tags = [
+        # Don't cache the results.
+        "external",
+        # Don't include in wildcard expansions (:..., :all).
+        "manual",
+    ],
+    deps = [
+        ":test_binary_util",
+        "@abseil-cpp//absl/container:flat_hash_map",
+        "@abseil-cpp//absl/strings",
+        "@abseil-cpp//absl/time",
+        "@com_google_fuzztest//common:temp_dir",
+        "@com_google_fuzztest//fuzztest/internal:io",
+        "@com_google_fuzztest//fuzztest/internal:subprocess",
+        "@googletest//:gtest_main",
+    ],
+)
+
 # Must be run with `--config=fuzztest-experimental --config=asan`.
 cc_test(
     name = "corpus_database_test",
diff --git a/e2e_tests/compatibility_mode_test.cc b/e2e_tests/compatibility_mode_test.cc
new file mode 100644
index 0000000..f575157
--- /dev/null
+++ b/e2e_tests/compatibility_mode_test.cc
@@ -0,0 +1,112 @@
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/container/flat_hash_map.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/time/time.h"
+#include "./common/temp_dir.h"
+#include "./e2e_tests/test_binary_util.h"
+#include "./fuzztest/internal/io.h"
+#include "./fuzztest/internal/subprocess.h"
+
+namespace fuzztest::internal {
+namespace {
+
+using testing::AllOf;
+using testing::Eq;
+using testing::HasSubstr;
+using testing::IsEmpty;
+using testing::Not;
+using testing::SizeIs;
+
+constexpr absl::string_view kDefaultTargetBinary =
+    "testdata/fuzz_tests_for_functional_testing";
+
+absl::flat_hash_map<std::string, std::string> WithTestSanitizerOptions(
+    absl::flat_hash_map<std::string, std::string> env) {
+  if (!env.contains("ASAN_OPTIONS")) {
+    // Let both FuzzTest and sanitizer to handle abort to check
+    // information from both sides. Use a random exitcode 111 for
+    // sanitizer-caught crashes.
+    env["ASAN_OPTIONS"] = "handle_abort=1:exitcode=111";
+  }
+  return env;
+}
+
+RunResults RunBinary(
+    absl::flat_hash_map<std::string, std::string> fuzztest_flags,
+    std::vector<std::string> binary_args = {},
+    const absl::flat_hash_map<std::string, std::string>& env = {},
+    absl::string_view target_binary = kDefaultTargetBinary) {
+  RunOptions run_options;
+  run_options.fuzztest_flags = std::move(fuzztest_flags);
+  // Skip slow stacktrace symbolization, which could cause unexpected timeouts
+  // in the tests.
+  run_options.flags["symbolize_stacktrace"] = "0";
+  run_options.raw_args = std::move(binary_args);
+  run_options.env = WithTestSanitizerOptions(env);
+  run_options.timeout = absl::Seconds(10);
+  return RunBinary(BinaryPath(target_binary), run_options);
+}
+
+TEST(CompatibilityModeTest, RunsFuzzing) {
+  const auto [status, stdout, stderr] = RunBinary(
+      /*fuzztest_flags=*/{{"fuzz", "MySuite.PassesWithPositiveInput"}});
+  SCOPED_TRACE(stderr);
+  ASSERT_THAT(status, Eq(ExitCode(0)));
+  // Check if fuzzing stats exist
+  EXPECT_THAT(stderr, HasSubstr("Total runs:"));
+}
+
+TEST(CompatibilityModeTest, FindsAndReplaysCrash) {
+  TempDir out_dir;
+  std::string crash_path;
+  {
+    const auto [status, stdout, stderr] = RunBinary(
+        /*fuzztest_flags=*/{{"fuzz", "MySuite.EnumValue"}}, /*binary_args=*/{
+            {"--",
+             absl::StrCat("-artifact_prefix=", out_dir.path().string(), "/")}});
+    SCOPED_TRACE(stderr);
+    ASSERT_THAT(status, Eq(ExitCode(111)));
+    EXPECT_THAT(stderr, AllOf(HasSubstr("argument 0: Color{0}"),
+                              HasSubstr("argument 1: Color{1}"),
+                              HasSubstr("argument 2: Color{2}")));
+    auto crash_files = ReadFileOrDirectory(out_dir.path().string());
+    ASSERT_THAT(crash_files, SizeIs(1));
+    crash_path = crash_files[0].path;
+    ASSERT_THAT(crash_path, Not(IsEmpty()));
+  }
+  {
+    const auto [status, stdout, stderr] =
+        RunBinary(/*fuzztest_flags=*/{{"fuzz", "MySuite.EnumValue"}},
+                  /*binary_args=*/{{"--", crash_path}});
+    SCOPED_TRACE(stderr);
+    ASSERT_THAT(status, Eq(ExitCode(111)));
+    EXPECT_THAT(stderr, HasSubstr(absl::StrCat("Running: ", crash_path)));
+    EXPECT_THAT(stderr, AllOf(HasSubstr("argument 0: Color{0}"),
+                              HasSubstr("argument 1: Color{1}"),
+                              HasSubstr("argument 2: Color{2}")));
+    EXPECT_THAT(stderr, HasSubstr("Total runs: 1\n"));
+  }
+}
+
+}  // namespace
+}  // namespace fuzztest::internal
diff --git a/e2e_tests/functional_test.cc b/e2e_tests/functional_test.cc
index e26128a..4dc7432 100644
--- a/e2e_tests/functional_test.cc
+++ b/e2e_tests/functional_test.cc
@@ -639,6 +639,7 @@
     return RunBinary(BinaryPath(binary),
                      RunOptions{/*flags=*/non_fuzztest_flags,
                                 /*fuzztest_flags=*/flags,
+                                /*raw_args=*/{},
                                 /*env=*/WithTestSanitizerOptions(env),
                                 /*timeout=*/timeout});
   }
@@ -1103,32 +1104,6 @@
 }
 
 TEST_F(FuzzingModeCommandLineInterfaceTest,
-       ConfiguresStackLimitByEnvVarWithWarning) {
-  auto [status, std_out, std_err] =
-      RunWith({{"fuzz", "MySuite.DataDependentStackOverflow"}},
-              {{"FUZZTEST_STACK_LIMIT", "512000"}});
-  EXPECT_THAT(std_err, HasSubstr("argument 0: "));
-  EXPECT_THAT(std_err,
-              HasSubstr(absl::StrCat(
-                  "Stack limit is set by FUZZTEST_STACK_LIMIT env var - this "
-                  "is going to be deprecated soon. Consider switching to ",
-                  CreateFuzzTestFlag("stack_limit_kb", ""), " flag.")));
-  ExpectStackLimitExceededMessage(std_err, 512000);
-  ExpectTargetAbort(status, std_err);
-}
-
-TEST_F(FuzzingModeCommandLineInterfaceTest,
-       ConfiguresStackLimitByEnvVarAndOverridesFlag) {
-  auto [status, std_out, std_err] =
-      RunWith({{"fuzz", "MySuite.DataDependentStackOverflow"},
-               {"stack_limit_kb", "1000"}},
-              {{"FUZZTEST_STACK_LIMIT", "512000"}});
-  EXPECT_THAT(std_err, HasSubstr("argument 0: "));
-  ExpectStackLimitExceededMessage(std_err, 512000);
-  ExpectTargetAbort(status, std_err);
-}
-
-TEST_F(FuzzingModeCommandLineInterfaceTest,
        DoesNotPrintWarningForDisabledLimitFlagsByDefault) {
   auto [status, std_out, std_err] = RunWith(
       {{"fuzz", "MySuite.PassesWithPositiveInput"}, {"fuzz_for", "10s"}},
diff --git a/e2e_tests/test_binary_util.cc b/e2e_tests/test_binary_util.cc
index fade808..7aac989 100644
--- a/e2e_tests/test_binary_util.cc
+++ b/e2e_tests/test_binary_util.cc
@@ -66,7 +66,8 @@
 
 RunResults RunBinary(absl::string_view binary_path, const RunOptions& options) {
   std::vector<std::string> args;
-  args.reserve(1 + options.fuzztest_flags.size() + options.flags.size());
+  args.reserve(1 + options.fuzztest_flags.size() + options.flags.size() +
+               options.raw_args.size());
   args.push_back(std::string(binary_path));
   for (const auto& [key, value] : options.fuzztest_flags) {
     args.push_back(CreateFuzzTestFlag(key, value));
@@ -74,6 +75,7 @@
   for (const auto& [key, value] : options.flags) {
     args.push_back(absl::StrCat("--", key, "=", value));
   }
+  args.insert(args.end(), options.raw_args.begin(), options.raw_args.end());
   return RunCommand(args, options.env, options.timeout);
 }
 
diff --git a/e2e_tests/test_binary_util.h b/e2e_tests/test_binary_util.h
index 70d8d9d..4e44e8b 100644
--- a/e2e_tests/test_binary_util.h
+++ b/e2e_tests/test_binary_util.h
@@ -41,11 +41,15 @@
 
 struct RunOptions {
   // General flags to pass to the binary. Useful when passing flags to
-  // binaries like Centipede.
+  // binaries like Centipede, e.g., {"binary", SOME_BINARY_PATH}
   absl::flat_hash_map<std::string, std::string> flags;
   // Flags to pass to a FuzzTest binary. These should be given without the
   // internal flag prefix, e.g., just ("fuzz_for", "1s").
   absl::flat_hash_map<std::string, std::string> fuzztest_flags;
+  // Raw args to append after `fuzztest_flags` and `flags`. Useful when passing
+  // positional arguments or non-standard flags, e.g. "--" for ending absl flag
+  // processing, and `-NAME=VALUE` for libFuzzer flags.
+  std::vector<std::string> raw_args;
   // Environment variables to pass to the binary.
   absl::flat_hash_map<std::string, std::string> env;
   // Duration after which the binary will be terminated.
diff --git a/e2e_tests/testdata/CMakeLists.txt b/e2e_tests/testdata/CMakeLists.txt
index 3931793..4e802b1 100644
--- a/e2e_tests/testdata/CMakeLists.txt
+++ b/e2e_tests/testdata/CMakeLists.txt
@@ -7,7 +7,7 @@
   PUBLIC
   fuzztest_status
   protobuf::libprotobuf
-  test_protobuf
+  fuzztest::test_protobuf_cc_proto
   absl::random_bit_gen_ref
   absl::random_distributions
   absl::str_format
@@ -26,7 +26,7 @@
   fuzz_tests_for_functional_testing.stripped
   PUBLIC
   protobuf::libprotobuf
-  test_protobuf
+  fuzztest::test_protobuf_cc_proto
   absl::algorithm_container
   absl::check
   absl::flat_hash_map
diff --git a/fuzztest/internal/CMakeLists.txt b/fuzztest/internal/CMakeLists.txt
index 57360ff..8fd2e4e 100644
--- a/fuzztest/internal/CMakeLists.txt
+++ b/fuzztest/internal/CMakeLists.txt
@@ -486,6 +486,14 @@
     GTest::gmock_main
 )
 
+fuzztest_proto_library(
+  NAME
+    test_protobuf_cc_proto
+  SRCS
+    test_protobuf.proto
+  TESTONLY
+)
+
 fuzztest_cc_library(
   NAME
     type_support
@@ -524,40 +532,3 @@
     protobuf::libprotobuf
 )
 
-if (FUZZTEST_BUILD_TESTING)
-
-  include_directories(${PROTOBUF_INCLUDE_DIR})
-
-  add_library(
-      test_protobuf
-    OBJECT
-      "${CMAKE_CURRENT_LIST_DIR}/test_protobuf.proto"
-  )
-
-  target_link_libraries(
-      test_protobuf
-    PUBLIC
-      protobuf::libprotobuf
-  )
-
-  # The output dir might not be created by `protobuf_generate`.
-  file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
-  protobuf_generate(
-    TARGET
-      test_protobuf
-    IMPORT_DIRS
-      ${CMAKE_CURRENT_LIST_DIR}
-    PROTOC_OUT_DIR
-      ${CMAKE_CURRENT_BINARY_DIR}
-  )
-
-  target_include_directories(
-      test_protobuf
-    PUBLIC
-      "${CMAKE_CURRENT_BINARY_DIR}/../.."
-  )
-
-  add_library(fuzztest::test_protobuf_cc_proto ALIAS test_protobuf)
-
-endif ()
diff --git a/fuzztest/internal/centipede_adaptor.cc b/fuzztest/internal/centipede_adaptor.cc
index 7eb0e87..7fa42bd 100644
--- a/fuzztest/internal/centipede_adaptor.cc
+++ b/fuzztest/internal/centipede_adaptor.cc
@@ -191,7 +191,7 @@
     const Configuration& configuration, absl::string_view workdir,
     absl::string_view test_name, RunMode run_mode) {
   fuzztest::internal::Environment env = CreateDefaultCentipedeEnvironment();
-  constexpr absl::Duration kUnitTestDefaultDuration = absl::Seconds(3);
+  constexpr absl::Duration kUnitTestDefaultDuration = absl::Seconds(1);
   env.fuzztest_single_test_mode = true;
   if (configuration.time_limit_per_input < absl::InfiniteDuration()) {
     const int64_t time_limit_seconds =
@@ -559,9 +559,7 @@
 namespace {
 
 void PopulateTestLimitsToCentipedeRunner(const Configuration& configuration) {
-  if (const size_t stack_limit =
-          GetStackLimitFromEnvOrConfiguration(configuration);
-      stack_limit > 0) {
+  if (const size_t stack_limit = configuration.stack_limit; stack_limit > 0) {
     absl::FPrintF(GetStderr(), "[.] Stack limit set to: %zu\n", stack_limit);
     CentipedeSetStackLimit(/*stack_limit_kb=*/stack_limit >> 10);
   }
diff --git a/fuzztest/internal/domains/container_of_impl.h b/fuzztest/internal/domains/container_of_impl.h
index 11af47d..1db432c 100644
--- a/fuzztest/internal/domains/container_of_impl.h
+++ b/fuzztest/internal/domains/container_of_impl.h
@@ -172,9 +172,16 @@
     if constexpr (container_has_memory_dict) {
       if (can_use_memory_dict) {
         if (action-- == 0) {
+          auto old_val = val;
           bool mutated = MemoryDictionaryMutation(
               val, prng, metadata.cmp_tables, temporary_dict_, GetManualDict(),
               permanent_dict_, permanent_dict_candidate_, max_size());
+          // Applying memory dictionary may violate the inner domain - fail the
+          // mutation if so.
+          if (mutated && !ValidateCorpusValue(val).ok()) {
+            val = std::move(old_val);
+            mutated = false;
+          }
           // If dict failed, fall back to changing an element.
           if (!mutated) {
             Self().MutateElement(val, prng, metadata, only_shrink,
diff --git a/fuzztest/internal/domains/domain.h b/fuzztest/internal/domains/domain.h
index a384e8a..1d38319 100644
--- a/fuzztest/internal/domains/domain.h
+++ b/fuzztest/internal/domains/domain.h
@@ -183,6 +183,12 @@
     return Mutate(corpus_value, prng, {}, only_shrink);
   }
 
+  // See the important notes on GetRandomValue() above on caveats of getting
+  // random values.
+  corpus_type GetRandomCorpusValue(absl::BitGenRef prng) {
+    return inner_->UntypedGetRandomCorpusValue(prng);
+  }
+
   // The methods below are responsible for transforming between the above
   // described three types that domains deal with. Here's a quick overview:
   //
diff --git a/fuzztest/internal/domains/domain_base.h b/fuzztest/internal/domains/domain_base.h
index 4243dcf..28faefd 100644
--- a/fuzztest/internal/domains/domain_base.h
+++ b/fuzztest/internal/domains/domain_base.h
@@ -203,21 +203,6 @@
     return derived();
   }
 
- protected:
-  // `Derived::Init()` can use this to sample seeds for this domain.
-  std::optional<CorpusType> MaybeGetRandomSeed(absl::BitGenRef prng) {
-    if (seed_provider_ != nullptr) {
-      WithSeeds(std::invoke(seed_provider_));
-      seed_provider_ = nullptr;
-    }
-
-    static constexpr double kProbabilityToReturnSeed = 0.5;
-    if (seeds_.empty() || !absl::Bernoulli(prng, kProbabilityToReturnSeed)) {
-      return std::nullopt;
-    }
-    return seeds_[fuzztest::internal::ChooseOffset(seeds_.size(), prng)];
-  }
-
   // Default implementation of GetRandomCorpusValue() without guarantees on the
   // distribution of the returned values. If possible, the derived domain should
   // override this with a better implementation.
@@ -235,6 +220,21 @@
     return corpus_val;
   }
 
+ protected:
+  // `Derived::Init()` can use this to sample seeds for this domain.
+  std::optional<CorpusType> MaybeGetRandomSeed(absl::BitGenRef prng) {
+    if (seed_provider_ != nullptr) {
+      WithSeeds(std::invoke(seed_provider_));
+      seed_provider_ = nullptr;
+    }
+
+    static constexpr double kProbabilityToReturnSeed = 0.5;
+    if (seeds_.empty() || !absl::Bernoulli(prng, kProbabilityToReturnSeed)) {
+      return std::nullopt;
+    }
+    return seeds_[absl::Uniform(prng, 0u, seeds_.size())];
+  }
+
  private:
   Derived& derived() { return static_cast<Derived&>(*this); }
   const Derived& derived() const { return static_cast<const Derived&>(*this); }
diff --git a/fuzztest/internal/domains/domain_type_erasure.h b/fuzztest/internal/domains/domain_type_erasure.h
index 2c38c3f..2dd3b08 100644
--- a/fuzztest/internal/domains/domain_type_erasure.h
+++ b/fuzztest/internal/domains/domain_type_erasure.h
@@ -74,6 +74,8 @@
   virtual uint64_t UntypedMutateSelectedField(
       GenericDomainCorpusType&, absl::BitGenRef,
       const domain_implementor::MutationMetadata&, bool, uint64_t) = 0;
+  virtual GenericDomainCorpusType UntypedGetRandomCorpusValue(
+      absl::BitGenRef prng) = 0;
   virtual GenericDomainValueType UntypedGetValue(
       const GenericDomainCorpusType& v) const = 0;
   virtual void UntypedPrintCorpusValue(
@@ -167,6 +169,12 @@
     }
   }
 
+  GenericDomainCorpusType UntypedGetRandomCorpusValue(
+      absl::BitGenRef prng) final {
+    return GenericDomainCorpusType(std::in_place_type<CorpusType>,
+                                   domain_.GetRandomCorpusValue(prng));
+  }
+
   std::optional<GenericDomainCorpusType> UntypedParseCorpus(
       const IRObject& obj) const final {
     if (auto res = domain_.ParseCorpus(obj)) {
diff --git a/fuzztest/internal/runtime.cc b/fuzztest/internal/runtime.cc
index 243b27e..6bb21fe 100644
--- a/fuzztest/internal/runtime.cc
+++ b/fuzztest/internal/runtime.cc
@@ -1010,30 +1010,12 @@
                });
 }
 
-size_t GetStackLimitFromEnvOrConfiguration(const Configuration& configuration) {
-  size_t env_stack_limit;
-  if (const char* env = getenv("FUZZTEST_STACK_LIMIT");
-      (env != nullptr && absl::SimpleAtoi(env, &env_stack_limit))) {
-    absl::FPrintF(
-        GetStderr(),
-        "[!] Stack limit is set by FUZZTEST_STACK_LIMIT env var - this is "
-        "going to be deprecated soon. Consider switching to "
-        "--" FUZZTEST_FLAG_PREFIX "stack_limit_kb flag.\n");
-    return env_stack_limit;
-  }
-  return configuration.stack_limit;
-}
-
 void PopulateLimits(const Configuration& configuration,
                     ExecutionCoverage* execution_coverage) {
   // centipede_adaptor would populate the limits to Centipede.
 #ifndef FUZZTEST_USE_CENTIPEDE
-  // TODO(b/273276918): For now, let existing FUZZTEST_STACK_LIMIT overwrite the
-  // stack limit. So that the existing targets that set the env var could still
-  // work.
   if (execution_coverage)
-    execution_coverage->SetStackLimit(
-        GetStackLimitFromEnvOrConfiguration(configuration));
+    execution_coverage->SetStackLimit(configuration.stack_limit);
 #endif
 }
 
diff --git a/fuzztest/internal/runtime.h b/fuzztest/internal/runtime.h
index f4e4a8a..520b72f 100644
--- a/fuzztest/internal/runtime.h
+++ b/fuzztest/internal/runtime.h
@@ -431,8 +431,6 @@
   friend class CentipedeAdaptorEngineCallbacks;
 };
 
-size_t GetStackLimitFromEnvOrConfiguration(const Configuration& configuration);
-
 // A reproduction command template will include these placeholders. These
 // placeholders then will be replaced by the proper test filter when creating
 // the final reproduction command from the template.
diff --git a/rust/.rustfmt.toml b/rust/.rustfmt.toml
deleted file mode 100644
index 33b356d..0000000
--- a/rust/.rustfmt.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-use_field_init_shorthand = true
-use_try_shorthand = true
-edition = "2021"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
deleted file mode 100644
index addd553..0000000
--- a/rust/Cargo.toml
+++ /dev/null
@@ -1,23 +0,0 @@
-[package]
-name = "fuzztest"
-version = "0.1.0"
-edition = "2021"
-default-run = "fuzztest"
-
-[[test]]
-name = "trybuild"
-path = "tests/trybuild.rs"
-
-[dependencies]
-fuzztest-macro = { path = "impl" }
-
-[dev-dependencies.trybuild]
-version = "1.0.103"
-features = ["diff"]
-
-[profile.fuzztest]
-inherits = 'release'
-panic = 'abort'
-opt-level = "s"
-debug = true
-split-debuginfo = "packed"
diff --git a/rust/README.md b/rust/README.md
deleted file mode 100644
index 7d154ad..0000000
--- a/rust/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# FuzzTest Rust
-
-This is the repository containing the FuzzTest framework for Rust.
-
-**Important note:** Please do not forget to run `cargo clean` before committing
-your change. That will avoid committing libraries files downloaded when
-`cargo build` and `cargo test`.
diff --git a/rust/impl/.rustfmt.toml b/rust/impl/.rustfmt.toml
deleted file mode 100644
index 33b356d..0000000
--- a/rust/impl/.rustfmt.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-use_field_init_shorthand = true
-use_try_shorthand = true
-edition = "2021"
diff --git a/rust/impl/Cargo.toml b/rust/impl/Cargo.toml
deleted file mode 100644
index 556a2cb..0000000
--- a/rust/impl/Cargo.toml
+++ /dev/null
@@ -1,7 +0,0 @@
-[package]
-name = "fuzztest-macro"
-version = "0.1.0"
-edition = "2021"
-
-[lib]
-proc-macro = true
diff --git a/rust/impl/src/lib.rs b/rust/impl/src/lib.rs
deleted file mode 100644
index 0e3d461..0000000
--- a/rust/impl/src/lib.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use proc_macro::TokenStream;
-
-#[proc_macro_attribute]
-pub fn fuzztest(_args: TokenStream, _input: TokenStream) -> TokenStream {
-    todo!("Not implemented yet.")
-}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
deleted file mode 100644
index 0df3ad0..0000000
--- a/rust/src/lib.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub use fuzztest_macro::fuzztest;
diff --git a/rust/tests/macro_compiles.rs b/rust/tests/macro_compiles.rs
deleted file mode 100644
index 95b76cd..0000000
--- a/rust/tests/macro_compiles.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use fuzztest::fuzztest;
-
-#[fuzztest()]
-fn fuzztest_macro_compiles() {}
-
-fn main() {}
diff --git a/rust/tests/trybuild.rs b/rust/tests/trybuild.rs
deleted file mode 100644
index c2d9ebd..0000000
--- a/rust/tests/trybuild.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#[test]
-fn fuzztest() {
-    let t = trybuild::TestCases::new();
-    t.pass("tests/macro_compiles.rs");
-}