diff --git a/Core/Util/VideoPlayer.cpp b/Core/Util/VideoPlayer.cpp index 87444ed89e..7d5b14034e 100644 --- a/Core/Util/VideoPlayer.cpp +++ b/Core/Util/VideoPlayer.cpp @@ -141,6 +141,14 @@ int pmf_init(PMFPlayer* ps, const uint8_t* data, size_t size, int* out_w, int* o AVCodec* codec = avcodec_find_decoder(ps->video_ctx->codec_id); if (!codec || avcodec_open2(ps->video_ctx, codec, nullptr) < 0) return -1; + // Reject absurd dimensions: PMF video on PSP never exceeds 720x480, and + // larger values could overflow the caller's frame buffer allocation + // (width * height * 4) and drive huge sws_scale writes. + if (ps->video_ctx->width <= 0 || ps->video_ctx->height <= 0 || + ps->video_ctx->width > 720 || ps->video_ctx->height > 480) { + return -1; + } + ps->frame = av_frame_alloc(); ps->rgb_frame = av_frame_alloc(); ps->last_pts = -1.0; diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index d7c55d218c..a7c4584e2a 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -113,7 +113,9 @@ public: Draw::DrawContext *draw = dc.GetDrawContext(); - std::vector frame(width_ * height_ * 4); + // Dimensions are capped by pmf_init, but use size_t arithmetic anyway + // so a regression can't overflow the allocation. + std::vector frame((size_t)width_ * (size_t)height_ * 4); if (pmf_update(player_, startTime_.ElapsedSeconds(), frame.data())) { if (curFrame_) { curFrame_->Release();