github-actions[bot] commented on code in PR #67013:
URL: https://github.com/apache/doris/pull/67013#discussion_r3828553386
##########
cloud/test/blob_message_test.cpp:
##########
@@ -259,6 +358,32 @@ TEST(BlobMessageTest, GetRangeWithTxnKv) {
}
}
+TEST(BlobMessageTest, BlobIteratorRejectsMalformedChunks) {
Review Comment:
[P2] Apply malformed-fragment validation to ordinary blob_get
These new checks exercise only `BlobIterator`. `ValueBuf::get` still decodes
the first suffix and then retains every KV in the range without validating
later versions or sequences, so `(v0, seq0)` plus `(v0, seq2)` or `(v1, seq1)`
returns `TXN_OK` and concatenates corrupted data. Please share the
origin/version/contiguous-sequence validation with `blob_get` and add
equivalent ordinary-reader cases.
##########
cloud/src/meta-store/blob_message.cpp:
##########
@@ -40,6 +42,15 @@ static std::vector<std::string_view> split_string(const
std::string_view& str, i
return substrings;
}
+std::string encode_blob_key(std::string_view origin_key, uint8_t version,
size_t sequence) {
+ std::string split_key(origin_key);
+ int64_t suffix = version;
+ suffix <<= 56;
Review Comment:
[P2] Preserve sequence order for high blob versions
The API now advertises the full `uint8_t` version range, but versions
129-255 produce negative suffixes. `encode_int64` stores a negative value as
tag `0x11` plus its absolute magnitude, so for version 255 sequence 1 sorts
before sequence 0. FDB therefore feeds `ValueBuf` chunks in reverse order,
while `BlobIterator` starts at the highest sequence and rejects the next lower
one. This remains after special-casing the existing version-128/`INT64_MIN`
overflow, so please either reject versions above 127 or use an order-preserving
suffix representation, with a multi-chunk high-version test through both
readers.
##########
cloud/test/blob_message_test.cpp:
##########
@@ -259,6 +358,32 @@ TEST(BlobMessageTest, GetRangeWithTxnKv) {
}
}
+TEST(BlobMessageTest, BlobIteratorRejectsMalformedChunks) {
+ auto expect_invalid = [](std::string_view origin_key,
+ const std::vector<std::string>& raw_keys) {
+ auto txn_kv = std::make_shared<MemTxnKv>();
+ ASSERT_EQ(txn_kv->init(), 0);
+ std::unique_ptr<Transaction> txn;
+ ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
+ for (const auto& raw_key : raw_keys) {
+ txn->put(raw_key, "value");
+ }
+ ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
+
+ auto iter = blob_get_range(txn_kv, origin_key, std::string(origin_key)
+ "\xff");
+ EXPECT_FALSE(iter->valid());
+ EXPECT_EQ(iter->error_code(), TxnErrorCode::TXN_INVALID_DATA);
+ };
+
+ expect_invalid("sequence_gap",
Review Comment:
[P2] Reject blobs whose first available chunk is not sequence zero
`load_current_blob` seeds `next_sequence` from the first persisted key, so a
range containing only `encode_blob_key("missing_prefix", 0, 1)` passes the
first comparison and is exposed as a complete blob with `TXN_OK`. The new `0,2`
case catches an internal gap but not loss of the leading chunk. Please require
the first decoded sequence to be zero and add this missing-prefix negative case.
##########
cloud/src/meta-store/blob_message.cpp:
##########
@@ -150,13 +161,10 @@ void blob_put(Transaction* txn, std::string_view key,
const google::protobuf::Me
void blob_put(Transaction* txn, std::string_view key, std::string_view value,
uint8_t ver,
size_t split_size) {
+ split_size = std::max(split_size, MIN_BLOB_SPLIT_SIZE);
auto split_vec = split_string(value, split_size);
- int64_t suffix_base = ver;
- suffix_base <<= 56;
for (size_t i = 0; i < split_vec.size(); ++i) {
- std::string k(key);
- encode_int64(suffix_base + i, &k);
- txn->put(k, split_vec[i]);
+ txn->put(encode_blob_key(key, ver, i), split_vec[i]);
Review Comment:
[P2] Remove old chunks before same-versionstamp rewrites
This loop only overwrites sequences emitted by the replacement value.
`convert_tmp_rowsets` reads an existing operation log, lowers its protobuf
`min_timestamp`, and calls the specified-versionstamp `blob_put` for the same
key without removing `log_value`. Because a lower uint64 varint can make a
large log cross from N chunks to N-1 at the 90 KB boundary, the old final chunk
survives and remains a contiguous same-version sequence, so both readers accept
corrupted protobuf bytes. Please have that caller retain and remove the loaded
`log_value` keys in the same transaction before rewriting, and add a shrinking
same-versionstamp test.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]