From 96ad341b1e4ed5b5466308ef61f891c0245c4732 Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Fri, 31 May 2024 06:39:04 +0800 Subject: [PATCH] [action] [PR:836] add support for binary data read for Table::get() (#836) In the current implementation, the data from redis is passed directly to the std::string(char*) constructor which truncates the data on the null byte. To support binary data that can contain null bytes, the redis reply *str* is passed along with its *len* into the std::string(char*,size_t) constructor that supports the input size. Co-authored-by: Yakiv Huryk <62013282+Yakiv-Huryk@users.noreply.github.com> Co-authored-by: Ze Gan --- common/table.cpp | 2 +- tests/redis_ut.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/common/table.cpp b/common/table.cpp index ca39b4f97..ec93b3373 100644 --- a/common/table.cpp +++ b/common/table.cpp @@ -82,7 +82,7 @@ bool Table::get(const string &key, vector &values) for (unsigned int i = 0; i < reply->elements; i += 2) { values.emplace_back(stripSpecialSym(reply->element[i]->str), - reply->element[i + 1]->str); + string(reply->element[i + 1]->str, reply->element[i + 1]->len)); } return true; diff --git a/tests/redis_ut.cpp b/tests/redis_ut.cpp index 16384c0d7..c8532ff55 100644 --- a/tests/redis_ut.cpp +++ b/tests/redis_ut.cpp @@ -16,6 +16,7 @@ #include "common/table.h" #include "common/dbinterface.h" #include "common/sonicv2connector.h" +#include "common/redisutility.h" using namespace std; using namespace swss; @@ -845,6 +846,34 @@ TEST(Table, ttl_test) cout << "Done." << endl; } +TEST(Table, binary_data_get) +{ + DBConnector db("TEST_DB", 0, true); + Table table(&db, "binary_data"); + + const char* bindata1 = "\x11\x00\x22\x33\x44"; + const char* bindata2 = "\x11\x22\x33\x00\x44"; + auto v1 = std::string(bindata1, sizeof(bindata1)); + auto v2 = std::string(bindata2, sizeof(bindata2)); + vector values_set = { + {"f1", v1}, + {"f2", v2}, + }; + + table.set("k1", values_set); + + vector values_get; + EXPECT_TRUE(table.get("k1", values_get)); + + auto f1 = swss::fvsGetValue(values_get, "f1"); + auto f2 = swss::fvsGetValue(values_get, "f2"); + EXPECT_TRUE(f1); + EXPECT_TRUE(f2); + + EXPECT_EQ(*f1, v1); + EXPECT_EQ(*f2, v2); +} + TEST(ProducerConsumer, Prefix) { std::string tableName = "tableName";