15
15
16
16
#include " include/proxy-wasm/pairs_util.h"
17
17
18
+ #include < cstdint>
18
19
#include < cstring>
19
20
#include < string_view>
20
21
#include < vector>
25
26
26
27
namespace proxy_wasm {
27
28
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
+
28
46
using Sizes = std::vector<std::pair<uint32_t , uint32_t >>;
29
47
30
48
size_t PairsUtil::pairsSize (const Pairs &pairs) {
@@ -113,10 +131,13 @@ Pairs PairsUtil::toPairs(std::string_view buffer) {
113
131
if (pos + sizeof (uint32_t ) > end) {
114
132
return {};
115
133
}
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);
120
141
pos += sizeof (uint32_t );
121
142
122
143
// Check if we're not going to exceed the limit.
@@ -135,20 +156,14 @@ Pairs PairsUtil::toPairs(std::string_view buffer) {
135
156
if (pos + sizeof (uint32_t ) > end) {
136
157
return {};
137
158
}
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);
142
160
pos += sizeof (uint32_t );
143
161
144
162
// Read value length.
145
163
if (pos + sizeof (uint32_t ) > end) {
146
164
return {};
147
165
}
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);
152
167
pos += sizeof (uint32_t );
153
168
}
154
169
0 commit comments