Possible AVFormatContext leak in MediaInfoWorker::Execute
I found a possible per-operation resource leak in MediaInfoWorker::Execute. The worker allocates and
opens an AVFormatContext (which owns an open file/IO handle and demuxer state). If
avformat_find_stream_info fails, the worker only calls SetError and returns — it never closes the
already-opened context. MediaInfoWorker has no destructor and OnError just rejects the promise, so
on this path the opened AVFormatContext (and its file/socket handle) is leaked for every failed call.
Ownership is only transferred to a self-freeing wrapper on the success path (OnOK), never on error.
File: src/media-info-worker.cc
Function: MediaInfoWorker::Execute (and MediaInfoWorker::OnError)
void MediaInfoWorker::Execute() {
avFormatContext = avformat_alloc_context();
if (!avFormatContext) { SetError("..."); return; }
int openStatus = avformat_open_input(&avFormatContext, fileName.c_str(), NULL, options);
if (openStatus < 0) { SetError("filePath could not be opened"); return; } // ffmpeg frees ctx here
if (avformat_find_stream_info(avFormatContext, NULL) < 0) {
Napi::AsyncWorker::SetError("could not get stream info");
// <-- returns with avFormatContext still OPEN and never closed
}
}
void MediaInfoWorker::OnError(const Napi::Error& error) {
deferred.Reject(error.Value()); // avFormatContext is never closed on the error path
}
avformat_alloc_context() + a successful avformat_open_input leave avFormatContext pointing at
an opened input (file/IO handle + demuxer). (On avformat_open_input failure FFmpeg frees the
context itself, so that branch is fine.)
- When
avformat_find_stream_info returns < 0 — reachable with a truncated/corrupt but openable
media file — Execute sets the error and returns without calling avformat_close_input.
MediaInfoWorker has no destructor and OnError only rejects the promise. The success path
(OnOK) is the only place that hands the pointer to an AvFormatContext ObjectWrap whose
~AvFormatContext calls avformat_close_input. On the error path that handoff never happens, so
the context and its underlying handle leak once per failed getFileInfo call.
JS trigger:
const { getFileInfo } = require('@alex8088/node-ffprobe');
// a file that opens but whose stream info cannot be parsed (corrupt/truncated) rejects,
// leaking one AVFormatContext + file handle each time:
for (let i = 0; i < 10000; i++) {
getFileInfo('./corrupt-but-openable.bin').catch(() => {});
}
Suggested fix: close the context on the failure path, e.g. call
avformat_close_input(&avFormatContext) when avformat_find_stream_info fails (or add a
MediaInfoWorker destructor / OnError cleanup that closes avFormatContext if it is still owned by
the worker).
Possible AVFormatContext leak in
MediaInfoWorker::ExecuteI found a possible per-operation resource leak in
MediaInfoWorker::Execute. The worker allocates andopens an
AVFormatContext(which owns an open file/IO handle and demuxer state). Ifavformat_find_stream_infofails, the worker only callsSetErrorand returns — it never closes thealready-opened context.
MediaInfoWorkerhas no destructor andOnErrorjust rejects the promise, soon this path the opened
AVFormatContext(and its file/socket handle) is leaked for every failed call.Ownership is only transferred to a self-freeing wrapper on the success path (
OnOK), never on error.File:
src/media-info-worker.ccFunction:
MediaInfoWorker::Execute(andMediaInfoWorker::OnError)avformat_alloc_context()+ a successfulavformat_open_inputleaveavFormatContextpointing atan opened input (file/IO handle + demuxer). (On
avformat_open_inputfailure FFmpeg frees thecontext itself, so that branch is fine.)
avformat_find_stream_inforeturns< 0— reachable with a truncated/corrupt but openablemedia file —
Executesets the error and returns without callingavformat_close_input.MediaInfoWorkerhas no destructor andOnErroronly rejects the promise. The success path(
OnOK) is the only place that hands the pointer to anAvFormatContextObjectWrap whose~AvFormatContextcallsavformat_close_input. On the error path that handoff never happens, sothe context and its underlying handle leak once per failed
getFileInfocall.JS trigger:
Suggested fix: close the context on the failure path, e.g. call
avformat_close_input(&avFormatContext)whenavformat_find_stream_infofails (or add aMediaInfoWorkerdestructor /OnErrorcleanup that closesavFormatContextif it is still owned bythe worker).