Possible memory leak of logLevelStr in logging (never freed on any path)
I found a possible per-operation heap leak in the logging N-API method. When called with a
string argument (to set the libav log level), the function mallocs a buffer to hold a UTF-8
copy of the argument, but that buffer is never freed on any path — neither the error path
(unrecognised level throws and returns) nor the normal success path. Every call to
beamcoder.logging('<level>') leaks the allocation.
File: src/log.cc
Function: logging
status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &strLen);
CHECK_STATUS;
logLevelStr = (char*) malloc(sizeof(char) * (strLen + 1));
CHECK_STATUS;
status = napi_get_value_string_utf8(env, args[0], logLevelStr, strLen + 1, &strLen);
CHECK_STATUS;
logLevel = beam_lookup_enum(beam_logging_level->inverse, logLevelStr);
if (logLevel == BEAM_ENUM_UNKNOWN) {
NAPI_THROW_ERROR("Logging level string unrecognised"); // returns, logLevelStr leaked
}
av_log_set_level(logLevel);
status = napi_get_undefined(env, &result);
CHECK_STATUS;
}
return result; // success path also returns without free(logLevelStr)
logLevelStr = (char*) malloc(strLen + 1) allocates a heap buffer holding the argument string.
- If the string is not a known level,
NAPI_THROW_ERROR(...) expands to napi_throw_error(...); return nullptr; — it does not free logLevelStr, so the buffer leaks on the error path.
- On the normal path, after
av_log_set_level(logLevel), the function falls through to
return result;. There is no free(logLevelStr) anywhere in the function (confirmed: the only
references to logLevelStr in log.cc are the declaration, the malloc, the fill, and the
lookup). So the buffer leaks on the success path too.
This is a per-operation leak: it happens on every invocation with a string, not just a one-time
init, and the amount leaked scales with the argument length.
JS trigger (if applicable):
const beamcoder = require('beamcoder');
for (let i = 0; i < 1e6; i++) beamcoder.logging('debug'); // leaks a buffer each call
beamcoder.logging('not-a-level'); // also leaks (and throws)
Suggested fix: free(logLevelStr) before both the NAPI_THROW_ERROR return and the final
return result; (or use a small RAII/std::string holder for the copied string).
Possible memory leak of
logLevelStrinlogging(never freed on any path)I found a possible per-operation heap leak in the
loggingN-API method. When called with astring argument (to set the libav log level), the function
mallocs a buffer to hold a UTF-8copy of the argument, but that buffer is never
freed on any path — neither the error path(unrecognised level throws and returns) nor the normal success path. Every call to
beamcoder.logging('<level>')leaks the allocation.File:
src/log.ccFunction:
logginglogLevelStr = (char*) malloc(strLen + 1)allocates a heap buffer holding the argument string.NAPI_THROW_ERROR(...)expands tonapi_throw_error(...); return nullptr;— it does not freelogLevelStr, so the buffer leaks on the error path.av_log_set_level(logLevel), the function falls through toreturn result;. There is nofree(logLevelStr)anywhere in the function (confirmed: the onlyreferences to
logLevelStrinlog.ccare the declaration, themalloc, the fill, and thelookup). So the buffer leaks on the success path too.
This is a per-operation leak: it happens on every invocation with a string, not just a one-time
init, and the amount leaked scales with the argument length.
JS trigger (if applicable):
Suggested fix:
free(logLevelStr)before both theNAPI_THROW_ERRORreturn and the finalreturn result;(or use a small RAII/std::stringholder for the copied string).