Skip to content

Commit 5bde20d

Browse files
committed
dnn: Fix dangling pointers returned by GetLayerNames
'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.
1 parent 8fe4fc7 commit 5bde20d

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

dnn.cpp

+27-3
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,34 @@ void Net_GetUnconnectedOutLayers(Net net, IntVector* res) {
111111

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

116-
for (size_t i = 0; i < cstrs.size(); ++i) {
117-
strs[i] = cstrs[i].c_str();
115+
size_t totalStrLen = 0;
116+
for (cv::String str : cstrs) {
117+
totalStrLen += str.size();
118+
}
119+
120+
// Compute 1D buffer size required to store
121+
// 2D array of null-terminated strings
122+
size_t numStrings = cstrs.size();
123+
size_t bufferLen = numStrings * sizeof(char*) + (totalStrLen + numStrings) * sizeof(char);
124+
125+
const char **strs = (const char**)new char[bufferLen];
126+
memset(strs, 0, bufferLen);
127+
128+
char* it = (char*)(strs + cstrs.size());
129+
const char* end = (char*)(strs) + bufferLen;
130+
131+
for (size_t i = 0; i < numStrings; ++i, ++it) {
132+
strs[i] = it;
133+
size_t strlen = cstrs[i].size();
134+
135+
// Avoid buffer overrun
136+
if(end < it + strlen + 1) {
137+
break;
138+
}
139+
140+
memcpy(it, cstrs[i].c_str(), strlen);
141+
it += strlen;
118142
}
119143

120144
names->length = cstrs.size();

0 commit comments

Comments
 (0)