1414// limitations under the License.
1515//
1616#include " include/proxy-wasm/limits.h"
17+ #include " include/proxy-wasm/pairs_util.h"
1718#include " include/proxy-wasm/wasm.h"
1819
1920#include < openssl/rand.h>
@@ -58,55 +59,6 @@ RegisterForeignFunction::RegisterForeignFunction(const std::string &name, WasmFo
5859
5960namespace exports {
6061
61- namespace {
62-
63- Pairs toPairs (std::string_view buffer) {
64- Pairs result;
65- const char *b = buffer.data ();
66- if (buffer.size () < sizeof (uint32_t )) {
67- return {};
68- }
69- auto size = wasmtoh (*reinterpret_cast <const uint32_t *>(b));
70- b += sizeof (uint32_t );
71- if (sizeof (uint32_t ) + size * 2 * sizeof (uint32_t ) > buffer.size ()) {
72- return {};
73- }
74- result.resize (size);
75- for (uint32_t i = 0 ; i < size; i++) {
76- result[i].first = std::string_view (nullptr , wasmtoh (*reinterpret_cast <const uint32_t *>(b)));
77- b += sizeof (uint32_t );
78- result[i].second = std::string_view (nullptr , wasmtoh (*reinterpret_cast <const uint32_t *>(b)));
79- b += sizeof (uint32_t );
80- }
81- for (auto &p : result) {
82- p.first = std::string_view (b, p.first .size ());
83- b += p.first .size () + 1 ;
84- p.second = std::string_view (b, p.second .size ());
85- b += p.second .size () + 1 ;
86- }
87- return result;
88- }
89-
90- template <typename Pairs>
91- bool getPairs (ContextBase *context, const Pairs &result, uint64_t ptr_ptr, uint64_t size_ptr) {
92- if (result.empty ()) {
93- return context->wasm ()->copyToPointerSize (" " , ptr_ptr, size_ptr);
94- }
95- uint64_t size = pairsSize (result);
96- uint64_t ptr = 0 ;
97- char *buffer = static_cast <char *>(context->wasm ()->allocMemory (size, &ptr));
98- marshalPairs (result, buffer);
99- if (!context->wasmVm ()->setWord (ptr_ptr, Word (ptr))) {
100- return false ;
101- }
102- if (!context->wasmVm ()->setWord (size_ptr, Word (size))) {
103- return false ;
104- }
105- return true ;
106- }
107-
108- } // namespace
109-
11062// General ABI.
11163
11264Word set_property (Word key_ptr, Word key_size, Word value_ptr, Word value_size) {
@@ -200,7 +152,7 @@ Word send_local_response(Word response_code, Word response_code_details_ptr,
200152 if (!details || !body || !additional_response_header_pairs) {
201153 return WasmResult::InvalidMemoryAccess;
202154 }
203- auto additional_headers = toPairs (additional_response_header_pairs.value ());
155+ auto additional_headers = PairsUtil:: toPairs (additional_response_header_pairs.value ());
204156 context->sendLocalResponse (response_code, body.value (), std::move (additional_headers),
205157 grpc_status, details.value ());
206158 context->wasm ()->stopNextIteration (true );
@@ -435,7 +387,25 @@ Word get_header_map_pairs(Word type, Word ptr_ptr, Word size_ptr) {
435387 if (result != WasmResult::Ok) {
436388 return result;
437389 }
438- if (!getPairs (context, pairs, ptr_ptr, size_ptr)) {
390+ if (pairs.empty ()) {
391+ if (!context->wasm ()->copyToPointerSize (" " , ptr_ptr, size_ptr)) {
392+ return WasmResult::InvalidMemoryAccess;
393+ }
394+ return WasmResult::Ok;
395+ }
396+ uint64_t size = PairsUtil::pairsSize (pairs);
397+ uint64_t ptr = 0 ;
398+ char *buffer = static_cast <char *>(context->wasm ()->allocMemory (size, &ptr));
399+ if (buffer == nullptr ) {
400+ return WasmResult::InvalidMemoryAccess;
401+ }
402+ if (!PairsUtil::marshalPairs (pairs, buffer, size)) {
403+ return WasmResult::InvalidMemoryAccess;
404+ }
405+ if (!context->wasmVm ()->setWord (ptr_ptr, Word (ptr))) {
406+ return WasmResult::InvalidMemoryAccess;
407+ }
408+ if (!context->wasmVm ()->setWord (size_ptr, Word (size))) {
439409 return WasmResult::InvalidMemoryAccess;
440410 }
441411 return WasmResult::Ok;
@@ -451,7 +421,7 @@ Word set_header_map_pairs(Word type, Word ptr, Word size) {
451421 return WasmResult::InvalidMemoryAccess;
452422 }
453423 return context->setHeaderMapPairs (static_cast <WasmHeaderMapType>(type.u64_ ),
454- toPairs (data.value ()));
424+ PairsUtil:: toPairs (data.value ()));
455425}
456426
457427Word get_header_map_size (Word type, Word result_ptr) {
@@ -549,8 +519,8 @@ Word http_call(Word uri_ptr, Word uri_size, Word header_pairs_ptr, Word header_p
549519 if (!uri || !body || !header_pairs || !trailer_pairs) {
550520 return WasmResult::InvalidMemoryAccess;
551521 }
552- auto headers = toPairs (header_pairs.value ());
553- auto trailers = toPairs (trailer_pairs.value ());
522+ auto headers = PairsUtil:: toPairs (header_pairs.value ());
523+ auto trailers = PairsUtil:: toPairs (trailer_pairs.value ());
554524 uint32_t token = 0 ;
555525 // NB: try to write the token to verify the memory before starting the async
556526 // operation.
@@ -619,7 +589,7 @@ Word grpc_call(Word service_ptr, Word service_size, Word service_name_ptr, Word
619589 return WasmResult::InvalidMemoryAccess;
620590 }
621591 uint32_t token = 0 ;
622- auto initial_metadata = toPairs (initial_metadata_pairs.value ());
592+ auto initial_metadata = PairsUtil:: toPairs (initial_metadata_pairs.value ());
623593 auto result = context->grpcCall (service.value (), service_name.value (), method_name.value (),
624594 initial_metadata, request.value (),
625595 std::chrono::milliseconds (timeout_milliseconds), &token);
@@ -645,7 +615,7 @@ Word grpc_stream(Word service_ptr, Word service_size, Word service_name_ptr, Wor
645615 return WasmResult::InvalidMemoryAccess;
646616 }
647617 uint32_t token = 0 ;
648- auto initial_metadata = toPairs (initial_metadata_pairs.value ());
618+ auto initial_metadata = PairsUtil:: toPairs (initial_metadata_pairs.value ());
649619 auto result = context->grpcStream (service.value (), service_name.value (), method_name.value (),
650620 initial_metadata, &token);
651621 if (result != WasmResult::Ok) {
0 commit comments