diff --git a/source/extensions/common/wasm/context.cc b/source/extensions/common/wasm/context.cc index d979154d1ef8..c0ec8e2b826b 100644 --- a/source/extensions/common/wasm/context.cc +++ b/source/extensions/common/wasm/context.cc @@ -428,7 +428,7 @@ static absl::flat_hash_map property_tokens = {PROPER #undef _PARI absl::optional -Context::FindValue(absl::string_view name, Protobuf::Arena* arena) const { +Context::findValue(absl::string_view name, Protobuf::Arena* arena, bool last) const { using google::api::expr::runtime::CelValue; const StreamInfo::StreamInfo* info = getConstRequestStreamInfo(); @@ -442,11 +442,15 @@ Context::FindValue(absl::string_view name, Protobuf::Arena* arena) const { const WasmState* state; if (info->filterState().hasData(key)) { state = &info->filterState().getDataReadOnly(key); - } else if (info->upstreamFilterState()->hasData(key)) { + } else if (info->upstreamFilterState() && + info->upstreamFilterState()->hasData(key)) { state = &info->upstreamFilterState()->getDataReadOnly(key); } else { return {}; } + if (last) { + return CelValue::CreateBytes(&state->value()); + } return state->exprValue(arena); } return {}; @@ -573,7 +577,7 @@ WasmResult Context::getProperty(absl::string_view path, std::string* result) { if (first) { // top-level ident first = false; - auto top_value = FindValue(part, &arena); + auto top_value = findValue(part, &arena, start >= path.size()); if (!top_value.has_value()) { return WasmResult::NotFound; } @@ -1115,12 +1119,14 @@ WasmResult Context::setProperty(absl::string_view path, absl::string_view value) state = &stream_info->filterState()->getDataMutable(key); } else { const auto& it = rootContext()->state_prototypes_.find(path); - auto state_ptr = std::make_unique(it == rootContext()->state_prototypes_.end() - ? DefaultWasmStatePrototype::get() - : *it->second.get()); + const WasmStatePrototype& prototype = it == rootContext()->state_prototypes_.end() + ? DefaultWasmStatePrototype::get() + : *it->second.get(); + auto state_ptr = std::make_unique(prototype); state = state_ptr.get(); stream_info->filterState()->setData(key, std::move(state_ptr), - StreamInfo::FilterState::StateType::ReadOnly); + StreamInfo::FilterState::StateType::Mutable, + prototype.life_span_); } if (!state->setValue(value)) { return WasmResult::BadArgument; diff --git a/source/extensions/common/wasm/context.h b/source/extensions/common/wasm/context.h index 098e9ec95af7..1e89b21cb6cd 100644 --- a/source/extensions/common/wasm/context.h +++ b/source/extensions/common/wasm/context.h @@ -267,7 +267,11 @@ class Context : public proxy_wasm::ContextBase, return {}; } absl::optional - FindValue(absl::string_view name, Protobuf::Arena* arena) const override; + findValue(absl::string_view name, Protobuf::Arena* arena, bool last) const; + absl::optional + FindValue(absl::string_view name, Protobuf::Arena* arena) const override { + return findValue(name, arena, false); + } bool IsPathUnknown(absl::string_view) const override { return false; } const std::vector& unknown_attribute_patterns() const override {