mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-28 13:04:07 +08:00
修复mp4异常视频尺寸可能导致的未定义行为 (#4785)
libmov 的 `mov_add_video()` 接收 `int` 类型的视频宽高,并直接执行: ```c track->tkhd.width = width << 16; track->tkhd.height = height << 16; ``` 这是为了生成 MP4 Track Header 使用的 16.16 定点数。 当输入轨道包含异常视频尺寸,例如负数或在 32 位 int 平台上大于 32767 的值时,左移操作会产生有符号整数溢出,构成未定义行为,可能导致程序异常终止或生成错误的 MP4 轨道信息。
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
|
||||
#if defined(ENABLE_MP4)
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "MP4Muxer.h"
|
||||
#include "Common/config.h"
|
||||
|
||||
@@ -18,6 +20,15 @@ using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
static constexpr int kMaxMovVideoDimension = (std::numeric_limits<int>::max)() >> 16;
|
||||
|
||||
static bool isMovVideoDimensionSafe(int width, int height) {
|
||||
// libmov 将有符号 int 类型的视频宽高左移 16 位写入 16.16 定点数字段,超出此范围会触发未定义行为。
|
||||
// libmov shifts signed int video dimensions left by 16 for a 16.16 fixed-point field; values outside this range cause undefined behavior.
|
||||
return width >= 0 && height >= 0 &&
|
||||
width <= kMaxMovVideoDimension && height <= kMaxMovVideoDimension;
|
||||
}
|
||||
|
||||
MP4Muxer::~MP4Muxer() {
|
||||
try {
|
||||
closeMP4();
|
||||
@@ -182,7 +193,14 @@ bool MP4MuxerInterface::addTrack(const Track::Ptr &track) {
|
||||
if (track->getTrackType() == TrackVideo) {
|
||||
auto video_track = dynamic_pointer_cast<VideoTrack>(track);
|
||||
CHECK(video_track);
|
||||
auto track_id = mp4_writer_add_video(_mov_writter.get(), mp4_object, video_track->getVideoWidth(), video_track->getVideoHeight(), extra_data, extra_size);
|
||||
auto width = video_track->getVideoWidth();
|
||||
auto height = video_track->getVideoHeight();
|
||||
if (!isMovVideoDimensionSafe(width, height)) {
|
||||
WarnL << "Unsafe MP4 video dimensions: " << width << "x" << height
|
||||
<< ", safe range for each dimension: [0, " << kMaxMovVideoDimension << "]";
|
||||
return false;
|
||||
}
|
||||
auto track_id = mp4_writer_add_video(_mov_writter.get(), mp4_object, width, height, extra_data, extra_size);
|
||||
if (track_id < 0) {
|
||||
WarnL << "mp4_writer_add_video failed: " << video_track->getCodecName();
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user