Skip to content

Commit 59a347d

Browse files
authored
fix: bitops_family crash fixed (#4989)
fixed: #4988
1 parent 6d30baa commit 59a347d

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

src/server/bitops_family.cc

+15-6
Original file line numberDiff line numberDiff line change
@@ -728,17 +728,25 @@ ResultType Get::ApplyTo(Overflow ov, const string* bitfield) {
728728
const size_t offset = attr_.offset;
729729
auto last_byte_offset = GetByteIndex(attr_.offset + attr_.encoding_bit_size - 1);
730730

731+
if (GetByteIndex(offset) >= total_bytes) {
732+
return 0;
733+
}
734+
735+
const string* result_str = bitfield;
736+
string buff;
731737
uint32_t lsb = attr_.offset + attr_.encoding_bit_size - 1;
732-
if (last_byte_offset > total_bytes) {
733-
return {};
738+
if (last_byte_offset >= total_bytes) {
739+
buff = *bitfield;
740+
buff.resize(last_byte_offset + 1, 0);
741+
result_str = &buff;
734742
}
735743

736744
const bool is_negative =
737745
CheckBitStatus(GetByteValue(bytes, offset), GetNormalizedBitIndex(offset));
738746

739747
int64_t result = 0;
740748
for (size_t i = 0; i < attr_.encoding_bit_size; ++i) {
741-
uint8_t byte{GetByteValue(bytes, lsb)};
749+
uint8_t byte{GetByteValue(*result_str, lsb)};
742750
int32_t index = GetNormalizedBitIndex(lsb);
743751
int64_t old_bit = CheckBitStatus(byte, index);
744752
result |= old_bit << i;
@@ -830,10 +838,11 @@ ResultType IncrBy::ApplyTo(Overflow ov, string* bitfield) {
830838
string& bytes = *bitfield;
831839
Get get(attr_);
832840
auto res = get.ApplyTo(ov, &bytes);
841+
const int32_t total_bytes = static_cast<int32_t>(bytes.size());
842+
auto last_byte_offset = GetByteIndex(attr_.offset + attr_.encoding_bit_size - 1);
833843

834-
if (!res) {
835-
Set set(attr_, incr_value_);
836-
return set.ApplyTo(ov, &bytes);
844+
if (last_byte_offset >= total_bytes) {
845+
bytes.resize(last_byte_offset + 1, 0);
837846
}
838847

839848
if (!HandleOverflow(ov, &*res)) {

src/server/bitops_family_test.cc

+17
Original file line numberDiff line numberDiff line change
@@ -805,4 +805,21 @@ TEST_F(BitOpsFamilyTest, BitFieldOperations) {
805805
ASSERT_THAT(Run({"bitfield", "foo", "get", "u1", "15"}), IntArg(1));
806806
}
807807

808+
TEST_F(BitOpsFamilyTest, BitFieldLargeOffset) {
809+
Run({"set", "foo", "bar"});
810+
811+
auto resp = Run({"bitfield", "foo", "get", "u32", "0", "overflow", "fail", "incrby", "u32", "0",
812+
"4294967295"});
813+
EXPECT_THAT(resp, RespArray(ElementsAre(IntArg(1650553344), ArgType(RespExpr::NIL))));
814+
815+
resp = Run({"strlen", "foo"});
816+
EXPECT_THAT(resp, 4);
817+
818+
resp = Run({"get", "foo"});
819+
EXPECT_THAT(ToSV(resp.GetBuf()), Eq(std::string_view("bar\0", 4)));
820+
821+
resp = Run({"bitfield", "foo", "get", "u32", "4294967295"});
822+
EXPECT_THAT(resp, 0);
823+
}
824+
808825
} // end of namespace dfly

0 commit comments

Comments
 (0)