1515
1616#include " include/proxy-wasm/pairs_util.h"
1717
18+ #include < cstdint>
1819#include < cstring>
1920#include < string_view>
2021#include < vector>
2526
2627namespace proxy_wasm {
2728
29+ namespace {
30+
31+ // Read trivially copyable type from char buffer and return value. Does not
32+ // check if char buffer is large enough to contain instance of `T`.
33+ template <typename T> inline T unalignedLoad (const char *buffer) {
34+ // Checking for undefined behaviour wrt std::memcpy.
35+ static_assert (std::is_trivially_copyable_v<T>,
36+ " type must be trivially copyable to use std::memcpy" );
37+ T result;
38+ // Use std::memcpy to get around strict type aliasing rules.
39+ std::memcpy (&result, buffer, sizeof (T));
40+
41+ return result;
42+ }
43+
44+ } // namespace
45+
2846using Sizes = std::vector<std::pair<uint32_t , uint32_t >>;
2947
3048size_t PairsUtil::pairsSize (const Pairs &pairs) {
@@ -113,10 +131,13 @@ Pairs PairsUtil::toPairs(std::string_view buffer) {
113131 if (pos + sizeof (uint32_t ) > end) {
114132 return {};
115133 }
116- uint32_t num_pairs = wasmtoh (*reinterpret_cast <const uint32_t *>(pos),
117- contextOrEffectiveContext () != nullptr
118- ? contextOrEffectiveContext ()->wasmVm ()->usesWasmByteOrder ()
119- : false );
134+
135+ // clang complains that this is unused when the wasmtoh macro drops its
136+ // second argument on non-big-endian platforms.
137+ [[maybe_unused]] const bool uses_wasm_byte_order =
138+ contextOrEffectiveContext () != nullptr &&
139+ contextOrEffectiveContext ()->wasmVm ()->usesWasmByteOrder ();
140+ uint32_t num_pairs = wasmtoh (unalignedLoad<uint32_t >(pos), uses_wasm_byte_order);
120141 pos += sizeof (uint32_t );
121142
122143 // Check if we're not going to exceed the limit.
@@ -135,20 +156,14 @@ Pairs PairsUtil::toPairs(std::string_view buffer) {
135156 if (pos + sizeof (uint32_t ) > end) {
136157 return {};
137158 }
138- s.first = wasmtoh (*reinterpret_cast <const uint32_t *>(pos),
139- contextOrEffectiveContext () != nullptr
140- ? contextOrEffectiveContext ()->wasmVm ()->usesWasmByteOrder ()
141- : false );
159+ s.first = wasmtoh (unalignedLoad<uint32_t >(pos), uses_wasm_byte_order);
142160 pos += sizeof (uint32_t );
143161
144162 // Read value length.
145163 if (pos + sizeof (uint32_t ) > end) {
146164 return {};
147165 }
148- s.second = wasmtoh (*reinterpret_cast <const uint32_t *>(pos),
149- contextOrEffectiveContext () != nullptr
150- ? contextOrEffectiveContext ()->wasmVm ()->usesWasmByteOrder ()
151- : false );
166+ s.second = wasmtoh (unalignedLoad<uint32_t >(pos), uses_wasm_byte_order);
152167 pos += sizeof (uint32_t );
153168 }
154169
0 commit comments