This commit is contained in:
Christopher Jeffrey (JJ) 2025-02-06 19:43:05 +08:00 committed by GitHub
commit e046de32e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 23 additions and 2 deletions

View File

@ -96,6 +96,10 @@ void InternalKeyComparator::FindShortSuccessor(std::string* key) const {
}
}
bool InternalKeyComparator::IsInternal() const {
return true;
}
const char* InternalFilterPolicy::Name() const { return user_policy_->Name(); }
void InternalFilterPolicy::CreateFilter(const Slice* keys, int n,

View File

@ -110,6 +110,7 @@ class InternalKeyComparator : public Comparator {
void FindShortestSeparator(std::string* start,
const Slice& limit) const override;
void FindShortSuccessor(std::string* key) const override;
bool IsInternal() const override;
const Comparator* user_comparator() const { return user_comparator_; }

View File

@ -87,6 +87,7 @@ void VersionEdit::EncodeTo(std::string* dst) const {
static bool GetInternalKey(Slice* input, InternalKey* dst) {
Slice str;
if (GetLengthPrefixedSlice(input, &str)) {
if (str.size() < 8) return false;
return dst->DecodeFrom(str);
} else {
return false;

View File

@ -52,6 +52,9 @@ class LEVELDB_EXPORT Comparator {
// Simple comparator implementations may return with *key unchanged,
// i.e., an implementation of this method that does nothing is correct.
virtual void FindShortSuccessor(std::string* key) const = 0;
// For internal usage only.
virtual bool IsInternal() const;
};
// Return a builtin comparator that uses lexicographic byte-wise

View File

@ -162,6 +162,11 @@ class Block::Iter : public Iterator {
}
void Seek(const Slice& target) override {
if (comparator_->IsInternal() && target.size() < 8) {
CorruptionError();
return;
}
// Binary search in restart array to find the last restart point
// with a key < target
uint32_t left = 0;
@ -191,7 +196,8 @@ class Block::Iter : public Iterator {
const char* key_ptr =
DecodeEntry(data_ + region_offset, data_ + restarts_, &shared,
&non_shared, &value_length);
if (key_ptr == nullptr || (shared != 0)) {
if (key_ptr == nullptr || (shared != 0) ||
(comparator_->IsInternal() && non_shared < 8)) {
CorruptionError();
return;
}
@ -261,7 +267,9 @@ class Block::Iter : public Iterator {
// Decode next entry
uint32_t shared, non_shared, value_length;
p = DecodeEntry(p, limit, &shared, &non_shared, &value_length);
if (p == nullptr || key_.size() < shared) {
if (p == nullptr || key_.size() < shared ||
(comparator_->IsInternal() &&
static_cast<uint64_t>(shared) + non_shared < 8)) {
CorruptionError();
return false;
} else {

View File

@ -17,6 +17,10 @@ namespace leveldb {
Comparator::~Comparator() = default;
bool Comparator::IsInternal() const {
return false;
}
namespace {
class BytewiseComparatorImpl : public Comparator {
public: