in plugins/experimental/wasm/lib/src/pairs_util.cc [104:188]
Pairs PairsUtil::toPairs(std::string_view buffer) {
if (buffer.data() == nullptr || buffer.size() > PROXY_WASM_HOST_PAIRS_MAX_BYTES) {
return {};
}
const char *pos = buffer.data();
const char *end = buffer.data() + buffer.size();
// Read number of pairs.
if (pos + sizeof(uint32_t) > end) {
return {};
}
uint32_t num_pairs = wasmtoh(*reinterpret_cast<const uint32_t *>(pos),
contextOrEffectiveContext() != nullptr
? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder()
: false);
pos += sizeof(uint32_t);
// Check if we're not going to exceed the limit.
if (num_pairs > PROXY_WASM_HOST_PAIRS_MAX_COUNT) {
return {};
}
if (pos + num_pairs * 2 * sizeof(uint32_t) > end) {
return {};
}
Sizes sizes;
sizes.resize(num_pairs);
for (auto &s : sizes) {
// Read name length.
if (pos + sizeof(uint32_t) > end) {
return {};
}
s.first = wasmtoh(*reinterpret_cast<const uint32_t *>(pos),
contextOrEffectiveContext() != nullptr
? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder()
: false);
pos += sizeof(uint32_t);
// Read value length.
if (pos + sizeof(uint32_t) > end) {
return {};
}
s.second = wasmtoh(*reinterpret_cast<const uint32_t *>(pos),
contextOrEffectiveContext() != nullptr
? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder()
: false);
pos += sizeof(uint32_t);
}
Pairs pairs;
pairs.resize(num_pairs);
for (uint32_t i = 0; i < num_pairs; i++) {
auto &s = sizes[i];
auto &p = pairs[i];
// Don't overread.
if (pos + s.first + 1 > end) {
return {};
}
p.first = std::string_view(pos, s.first);
pos += s.first;
if (*pos++ != '\0') { // NULL-terminated string.
return {};
}
// Don't overread.
if (pos + s.second + 1 > end) {
return {};
}
p.second = std::string_view(pos, s.second);
pos += s.second;
if (*pos++ != '\0') { // NULL-terminated string.
return {};
}
}
if (pos != end) {
return {};
}
return pairs;
}