Fix UB in ffi scope function.

GetCurrentScopeValues returns a map from identifiers to *copies* of
values.
So when we take a pointer to them in ffi/scope.cc, when the function
ends, those pointers dangle.

Change-Id: I6169e03d89151f1530fda54a143a2aef6a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/24480
Commit-Queue: Matt Stark <msta@google.com>
Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/ffi/scope.cc b/src/gn/ffi/scope.cc
index 84abed9..b564226 100644
--- a/src/gn/ffi/scope.cc
+++ b/src/gn/ffi/scope.cc
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "gn/ffi/scope.h"
+#include <ranges>
+#include <vector>
+
 #include "gn/ffi/bridge.h"
+#include "gn/ffi/scope.h"
 #include "gn/ffi/slice.h"
 #include "gn/scope.h"
 #include "gn/value.h"
@@ -54,16 +57,12 @@
 // * my_macro would complain that it got an unexpected parameter "foo"
 // * my_struct.srcs would also be accessible.
 SliceAny GetScopeItems(const Scope& scope) {
-  Scope::KeyValueMap scope_values;
-  scope.GetCurrentScopeValues(&scope_values);
-
-  std::vector<KeyValue> vec;
-  vec.reserve(scope_values.size());
-  for (const auto& pair : scope_values) {
-    vec.push_back(
-        KeyValue{rust::Str(pair.first.data(), pair.first.size()), pair.second});
-  }
-  return IntoSlice(std::move(vec));
+  auto range =
+      scope.GetCurrentScopeValues() | std::views::transform([](auto pair) {
+        return KeyValue{rust::Str(pair.first.data(), pair.first.size()),
+                        *pair.second};
+      });
+  return IntoSlice(std::vector<KeyValue>(range.begin(), range.end()));
 }
 
 const Value* GetValue(const Scope& scope, rust::Str ident) {
diff --git a/src/gn/scope.h b/src/gn/scope.h
index c9db294..9747ff3 100644
--- a/src/gn/scope.h
+++ b/src/gn/scope.h
@@ -7,6 +7,7 @@
 
 #include <map>
 #include <memory>
+#include <ranges>
 #include <set>
 #include <string>
 #include <string_view>
@@ -234,6 +235,14 @@
   // scopes.
   void GetCurrentScopeValues(KeyValueMap* output) const;
 
+  // Returns all values set in the current scope as a lazy view of
+  // std::pair<std::string_view, const Value*>.
+  auto GetCurrentScopeValues() const {
+    return values_ | std::views::transform([](const auto& pair) {
+             return std::make_pair(pair.first, &pair.second.value);
+           });
+  }
+
   // Returns true if the values in the current scope are the same as all
   // values in the given scope, without going to the parent scopes. Returns
   // false if not.