**breaking** IBLT: make encoding endian safe
refs: #5076
Change-Id: I0bbe2c321d971128733b87acbdf06bcaaa8b0571
diff --git a/PSync/detail/iblt.cpp b/PSync/detail/iblt.cpp
index 5315f2a..61e8211 100644
--- a/PSync/detail/iblt.cpp
+++ b/PSync/detail/iblt.cpp
@@ -47,6 +47,8 @@
namespace psync {
+namespace be = boost::endian;
+
const size_t N_HASH(3);
const size_t N_HASHCHECK(11);
@@ -87,7 +89,7 @@
const auto& values = extractValueFromName(ibltName);
if (3 * m_hashTable.size() != values.size()) {
- BOOST_THROW_EXCEPTION(Error("Received IBF cannot be decoded!"));
+ NDN_THROW(Error("Received IBF cannot be decoded!"));
}
for (size_t i = 0; i < m_hashTable.size(); i++) {
@@ -221,34 +223,21 @@
void
IBLT::appendToName(ndn::Name& name) const
{
- constexpr size_t unitSize = (sizeof(m_hashTable[0].count) +
- sizeof(m_hashTable[0].keySum) +
- sizeof(m_hashTable[0].keyCheck));
+ constexpr size_t unitSize = sizeof(m_hashTable[0].count) +
+ sizeof(m_hashTable[0].keySum) +
+ sizeof(m_hashTable[0].keyCheck);
size_t tableSize = unitSize * m_hashTable.size();
std::vector<uint8_t> table(tableSize);
for (size_t i = 0; i < m_hashTable.size(); i++) {
- // table[i*12], table[i*12+1], table[i*12+2], table[i*12+3] --> hashTable[i].count
+ uint32_t count = be::native_to_big(static_cast<uint32_t>(m_hashTable[i].count));
+ uint32_t keySum = be::native_to_big(static_cast<uint32_t>(m_hashTable[i].keySum));
+ uint32_t keyCheck = be::native_to_big(static_cast<uint32_t>(m_hashTable[i].keyCheck));
- table[(i * unitSize)] = 0xFF & m_hashTable[i].count;
- table[(i * unitSize) + 1] = 0xFF & (m_hashTable[i].count >> 8);
- table[(i * unitSize) + 2] = 0xFF & (m_hashTable[i].count >> 16);
- table[(i * unitSize) + 3] = 0xFF & (m_hashTable[i].count >> 24);
-
- // table[i*12+4], table[i*12+5], table[i*12+6], table[i*12+7] --> hashTable[i].keySum
-
- table[(i * unitSize) + 4] = 0xFF & m_hashTable[i].keySum;
- table[(i * unitSize) + 5] = 0xFF & (m_hashTable[i].keySum >> 8);
- table[(i * unitSize) + 6] = 0xFF & (m_hashTable[i].keySum >> 16);
- table[(i * unitSize) + 7] = 0xFF & (m_hashTable[i].keySum >> 24);
-
- // table[i*12+8], table[i*12+9], table[i*12+10], table[i*12+11] --> hashTable[i].keyCheck
-
- table[(i * unitSize) + 8] = 0xFF & m_hashTable[i].keyCheck;
- table[(i * unitSize) + 9] = 0xFF & (m_hashTable[i].keyCheck >> 8);
- table[(i * unitSize) + 10] = 0xFF & (m_hashTable[i].keyCheck >> 16);
- table[(i * unitSize) + 11] = 0xFF & (m_hashTable[i].keyCheck >> 24);
+ std::memcpy(&table[i * unitSize], &count, sizeof(count));
+ std::memcpy(&table[(i * unitSize) + 4], &keySum, sizeof(keySum));
+ std::memcpy(&table[(i * unitSize) + 8], &keyCheck, sizeof(keyCheck));
}
auto compressed = compress(m_compressionScheme, table.data(), table.size());
@@ -260,16 +249,18 @@
{
auto decompressedBuf = decompress(m_compressionScheme, ibltName.value(), ibltName.value_size());
+ if (decompressedBuf->size() % 4 != 0) {
+ NDN_THROW(Error("Received IBF cannot be decompressed correctly!"));
+ }
+
size_t n = decompressedBuf->size() / 4;
std::vector<uint32_t> values(n, 0);
- for (size_t i = 0; i < 4 * n; i += 4) {
- uint32_t t = ((*decompressedBuf)[i + 3] << 24) +
- ((*decompressedBuf)[i + 2] << 16) +
- ((*decompressedBuf)[i + 1] << 8) +
- (*decompressedBuf)[i];
- values[i / 4] = t;
+ for (size_t i = 0; i < n; i++) {
+ uint32_t t;
+ std::memcpy(&t, &(*decompressedBuf)[i * 4], sizeof(t));
+ values[i] = be::big_to_native(t);
}
return values;
diff --git a/tests/test-iblt.cpp b/tests/test-iblt.cpp
index e99bf6e..a2bb449 100644
--- a/tests/test-iblt.cpp
+++ b/tests/test-iblt.cpp
@@ -51,6 +51,24 @@
BOOST_CHECK_EQUAL(ibfName1, ibfName2);
}
+static const uint8_t IBF[] = {
+ // Header
+ 0x08, 0xB4,
+ // Uncompressed IBF
+ 0x00, 0x00, 0x00, 0x01, 0xF6, 0xA7, 0x7A, 0xBA, 0x6B, 0xA3, 0x4D, 0x63, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF6, 0xA7, 0x7A, 0xBA,
+ 0x6B, 0xA3, 0x4D, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xF6, 0xA7, 0x7A, 0xBA, 0x6B, 0xA3, 0x4D, 0x63, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
BOOST_AUTO_TEST_CASE(NameAppendAndExtract)
{
int size = 10;
@@ -69,7 +87,24 @@
BOOST_CHECK_EQUAL(iblt, rcvd);
IBLT rcvdDiffSize(20, CompressionScheme::DEFAULT);
- BOOST_CHECK_THROW(rcvdDiffSize.initialize(ibltName.get(-1)), std::runtime_error);
+ BOOST_CHECK_THROW(rcvdDiffSize.initialize(ibltName.get(-1)), IBLT::Error);
+
+ Name malformedName("test");
+ auto compressed = compress(CompressionScheme::DEFAULT,
+ malformedName.wireEncode().value(),
+ malformedName.wireEncode().value_size());
+ IBLT rcvdDiffSize1(size, CompressionScheme::DEFAULT);
+ malformedName.append(compressed->data(), compressed->size());
+ BOOST_CHECK_THROW(rcvdDiffSize1.initialize(malformedName.get(-1)), IBLT::Error);
+
+ IBLT iblt2(size, CompressionScheme::NONE);
+ iblt2.insert(newHash);
+ Name ibltName2("sync");
+ iblt2.appendToName(ibltName2);
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(IBF, IBF + sizeof(IBF),
+ ibltName2.get(-1).wireEncode().begin(),
+ ibltName2.get(-1).wireEncode().end());
}
BOOST_AUTO_TEST_CASE(CopyInsertErase)