Skip to content

Commit

Permalink
dnn: Fix dangling pointers returned by GetLayerNames
Browse files Browse the repository at this point in the history
'GetLayerNames' returns an array of 'char' pointers to cstrings
in a 'vector<string>'; unfortunately, once the vector is out of
scope, the strings are destroyed. 'GetLayerNames' callers are then
left with dangling pointers.

This change fixes the problem by expanding the 'strs' buffer
returned by 'GetLayerNames' and copying the vector's cstrings into it.
  • Loading branch information
deradiri committed Jan 25, 2022
1 parent 8fe4fc7 commit 5bde20d
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions dnn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,34 @@ void Net_GetUnconnectedOutLayers(Net net, IntVector* res) {

void Net_GetLayerNames(Net net, CStrings* names) {
std::vector< cv::String > cstrs(net->getLayerNames());
const char **strs = new const char*[cstrs.size()];

for (size_t i = 0; i < cstrs.size(); ++i) {
strs[i] = cstrs[i].c_str();
size_t totalStrLen = 0;
for (cv::String str : cstrs) {
totalStrLen += str.size();
}

// Compute 1D buffer size required to store
// 2D array of null-terminated strings
size_t numStrings = cstrs.size();
size_t bufferLen = numStrings * sizeof(char*) + (totalStrLen + numStrings) * sizeof(char);

const char **strs = (const char**)new char[bufferLen];
memset(strs, 0, bufferLen);

char* it = (char*)(strs + cstrs.size());
const char* end = (char*)(strs) + bufferLen;

for (size_t i = 0; i < numStrings; ++i, ++it) {
strs[i] = it;
size_t strlen = cstrs[i].size();

// Avoid buffer overrun
if(end < it + strlen + 1) {
break;
}

memcpy(it, cstrs[i].c_str(), strlen);
it += strlen;
}

names->length = cstrs.size();
Expand Down

0 comments on commit 5bde20d

Please sign in to comment.