@@ -224,21 +224,41 @@ class cpp_function : public function {
224
224
}
225
225
}
226
226
227
+ class strdup_guard {
228
+ public:
229
+ ~strdup_guard () {
230
+ for (auto s : strings)
231
+ std::free (s);
232
+ }
233
+ char *operator ()(const char *s) {
234
+ auto t = strdup (s);
235
+ strings.emplace_back (t);
236
+ return t;
237
+ }
238
+ void release () {
239
+ strings.clear ();
240
+ }
241
+ private:
242
+ std::vector<char *> strings;
243
+ };
244
+
227
245
// / Register a function call with Python (generic non-templated code goes here)
228
246
void initialize_generic (std::unique_ptr<detail::function_record> &&unique_rec, const char *text,
229
247
const std::type_info *const *types, size_t args) {
230
248
auto rec = unique_rec.get ();
231
249
250
+ strdup_guard guarded_strdup;
251
+
232
252
/* Create copies of all referenced C-style strings */
233
- rec->name = strdup (rec->name ? rec->name : " " );
234
- if (rec->doc ) rec->doc = strdup (rec->doc );
253
+ rec->name = guarded_strdup (rec->name ? rec->name : " " );
254
+ if (rec->doc ) rec->doc = guarded_strdup (rec->doc );
235
255
for (auto &a: rec->args ) {
236
256
if (a.name )
237
- a.name = strdup (a.name );
257
+ a.name = guarded_strdup (a.name );
238
258
if (a.descr )
239
- a.descr = strdup (a.descr );
259
+ a.descr = guarded_strdup (a.descr );
240
260
else if (a.value )
241
- a.descr = strdup (repr (a.value ).cast <std::string>().c_str ());
261
+ a.descr = guarded_strdup (repr (a.value ).cast <std::string>().c_str ());
242
262
}
243
263
244
264
rec->is_constructor = !strcmp (rec->name , " __init__" ) || !strcmp (rec->name , " __setstate__" );
@@ -321,13 +341,13 @@ class cpp_function : public function {
321
341
#if PY_MAJOR_VERSION < 3
322
342
if (strcmp (rec->name , " __next__" ) == 0 ) {
323
343
std::free (rec->name );
324
- rec->name = strdup (" next" );
344
+ rec->name = guarded_strdup (" next" );
325
345
} else if (strcmp (rec->name , " __bool__" ) == 0 ) {
326
346
std::free (rec->name );
327
- rec->name = strdup (" __nonzero__" );
347
+ rec->name = guarded_strdup (" __nonzero__" );
328
348
}
329
349
#endif
330
- rec->signature = strdup (signature.c_str ());
350
+ rec->signature = guarded_strdup (signature.c_str ());
331
351
rec->args .shrink_to_fit ();
332
352
rec->nargs = (std::uint16_t ) args;
333
353
@@ -361,6 +381,7 @@ class cpp_function : public function {
361
381
capsule rec_capsule (unique_rec.release (), [](void *ptr) {
362
382
destruct ((detail::function_record *) ptr);
363
383
});
384
+ guarded_strdup.release ();
364
385
365
386
object scope_module;
366
387
if (rec->scope ) {
@@ -396,12 +417,14 @@ class cpp_function : public function {
396
417
rec->next = chain;
397
418
auto rec_capsule = reinterpret_borrow<capsule>(((PyCFunctionObject *) m_ptr)->m_self );
398
419
rec_capsule.set_pointer (unique_rec.release ());
420
+ guarded_strdup.release ();
399
421
} else {
400
422
// Or end of chain (normal behavior)
401
423
chain_start = chain;
402
424
while (chain->next )
403
425
chain = chain->next ;
404
426
chain->next = unique_rec.release ();
427
+ guarded_strdup.release ();
405
428
}
406
429
}
407
430
0 commit comments