This is an automated email from the ASF dual-hosted git repository.
chenBright pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git
The following commit(s) were added to refs/heads/master by this push:
new cbb4ccdc Reject zero-datasize flv tag in FlvReader::Read (#3366)
cbb4ccdc is described below
commit cbb4ccdc0b2915a8f518c0be133ffdd60be0cc99
Author: sahvx655-wq <[email protected]>
AuthorDate: Sun Jul 12 20:23:01 2026 +0530
Reject zero-datasize flv tag in FlvReader::Read (#3366)
---
src/brpc/rtmp.cpp | 12 ++++++++++
test/brpc_rtmp_unittest.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+)
diff --git a/src/brpc/rtmp.cpp b/src/brpc/rtmp.cpp
index af8e2a72..31681239 100644
--- a/src/brpc/rtmp.cpp
+++ b/src/brpc/rtmp.cpp
@@ -237,6 +237,12 @@ butil::Status FlvReader::Read(RtmpVideoMessage* msg) {
uint32_t msg_size = policy::ReadBigEndian3Bytes(p + 1);
uint32_t timestamp = policy::ReadBigEndian3Bytes(p + 4);
timestamp |= (*(p + 7) << 24);
+ // The tag body carries at least the 1-byte VideoTagHeader consumed below.
+ // A DataSize of 0 makes `msg_size - 1' wrap to 0xFFFFFFFF and the cutn()
+ // then swallows the whole remaining buffer as one message.
+ if (msg_size < 1) {
+ return butil::Status(EINVAL, "Invalid FLV video tag with DataSize=0");
+ }
if (_buf->length() < 11 + msg_size + 4/*PreviousTagSize*/) {
return butil::Status(EAGAIN, "Fail to read, not enough data");
}
@@ -265,6 +271,12 @@ butil::Status FlvReader::Read(RtmpAudioMessage* msg) {
uint32_t msg_size = policy::ReadBigEndian3Bytes(p + 1);
uint32_t timestamp = policy::ReadBigEndian3Bytes(p + 4);
timestamp |= (*(p + 7) << 24);
+ // The tag body carries at least the 1-byte AudioTagHeader consumed below.
+ // A DataSize of 0 makes `msg_size - 1' wrap to 0xFFFFFFFF and the cutn()
+ // then swallows the whole remaining buffer as one message.
+ if (msg_size < 1) {
+ return butil::Status(EINVAL, "Invalid FLV audio tag with DataSize=0");
+ }
if (_buf->length() < 11 + msg_size + 4/*PreviousTagSize*/) {
return butil::Status(EAGAIN, "Fail to read, not enough data");
}
diff --git a/test/brpc_rtmp_unittest.cpp b/test/brpc_rtmp_unittest.cpp
index 8b8a59e7..61a63744 100644
--- a/test/brpc_rtmp_unittest.cpp
+++ b/test/brpc_rtmp_unittest.cpp
@@ -748,6 +748,63 @@ TEST(RtmpTest, avc_seq_header_sps_without_zero_byte) {
avc.Create(buf);
}
+static void AppendBigEndian3Bytes(std::string* s, uint32_t v) {
+ s->push_back((char)((v >> 16) & 0xFF));
+ s->push_back((char)((v >> 8) & 0xFF));
+ s->push_back((char)(v & 0xFF));
+}
+
+// Build an FLV stream header followed by a single tag of `tag_type' whose
+// DataSize field is set to `data_size'. No tag body is appended, so a valid
+// tag needs data_size==0 to be rejected before any body is consumed.
+static std::string MakeFlvTagWithDataSize(char tag_type, uint32_t data_size) {
+ std::string s;
+ const char header[] = { 'F', 'L', 'V', 0x01, 0x05, 0, 0, 0, 0x09 };
+ s.append(header, sizeof(header));
+ s.append(4, '\0'); // PreviousTagSize0
+ s.push_back(tag_type);
+ AppendBigEndian3Bytes(&s, data_size); // DataSize
+ s.append(3, '\0'); // Timestamp
+ s.push_back('\0'); // TimestampExtended
+ s.append(3, '\0'); // StreamID
+ s.append(4, '\0'); // PreviousTagSize
+ return s;
+}
+
+TEST(RtmpTest, flv_reader_rejects_zero_datasize_video_tag) {
+ std::string flv = MakeFlvTagWithDataSize((char)brpc::FLV_TAG_VIDEO, 0);
+ butil::IOBuf buf;
+ buf.append(flv);
+
+ brpc::FlvReader reader(&buf);
+ brpc::FlvTagType type;
+ ASSERT_TRUE(reader.PeekMessageType(&type).ok());
+ ASSERT_EQ(brpc::FLV_TAG_VIDEO, type);
+ const size_t before = buf.size();
+
+ brpc::RtmpVideoMessage vmsg;
+ // A DataSize of 0 used to underflow `msg_size - 1' and drain the whole
+ // buffer; it must now be rejected without consuming the tag.
+ ASSERT_FALSE(reader.Read(&vmsg).ok());
+ ASSERT_EQ(before, buf.size());
+}
+
+TEST(RtmpTest, flv_reader_rejects_zero_datasize_audio_tag) {
+ std::string flv = MakeFlvTagWithDataSize((char)brpc::FLV_TAG_AUDIO, 0);
+ butil::IOBuf buf;
+ buf.append(flv);
+
+ brpc::FlvReader reader(&buf);
+ brpc::FlvTagType type;
+ ASSERT_TRUE(reader.PeekMessageType(&type).ok());
+ ASSERT_EQ(brpc::FLV_TAG_AUDIO, type);
+ const size_t before = buf.size();
+
+ brpc::RtmpAudioMessage amsg;
+ ASSERT_FALSE(reader.Read(&amsg).ok());
+ ASSERT_EQ(before, buf.size());
+}
+
TEST(RtmpTest, successfully_play_streams) {
PlayingDummyService rtmp_service;
brpc::Server server;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]