What
CBitcoinLevelDBLogger::Logv in src/dbwrapper.cpp allocates its 30 KiB fallback buffer with a raw new char[] and frees it with a matching delete[] at the bottom of the loop. This change replaces the raw new[]/delete[] pair with a std::unique_ptr<char[]> and clamps negative vsnprintf returns to zero so the rest of the function cannot perform negative pointer arithmetic on base.
Why
Two small issues with the current code:
Exception leak. Any exception thrown between the
new char[30000]and the matchingdelete[] baseleaks the buffer. TheLogDebug(...)call near the end of the loop dispatches throughtfm::formatand the logging backend, both of which can throwstd::bad_alloc. Theif (base != buffer) delete[] base;cleanup is unreachable in that case.vsnprintfnegative return. The loop adds the return value ofvsnprintfto achar*(p += vsnprintf(...)).vsnprintfmay return a negative value on encoding errors. When that happens,pends up pointing before the beginning ofbase, after whichp[-1](the trailing-newline check, current line 100) is an out-of-bounds read and the subsequentbase[std::min(bufsize - 1, (int)(p - base))] = '\0'writes through a negative index.
What changed
- The heap buffer is now owned by
std::unique_ptr<char[]>allocated viastd::make_unique. The buffer is released automatically on every exit path of the loop, including exception unwinding. - The result of
vsnprintfis read into a localintandpis only advanced if it is positive, so subsequentp[-1]reads and(int)(p - base)arithmetic stay withinbase. - Behaviour in the normal case (successful format, no exception) is unchanged.
Test plan
cmake --build build --target bitcoin_nodesucceeds with the patch applied.- No behaviour change for callers; this is purely a local cleanup of one logger function.