Skip to content

Commit 2f1ed44

Browse files
author
ldx
committed
Fix memory leak in Target.
Move freeing of Target._target_buf to another class, thus getting rid of __del__() in Target. This enables Python to garbage collect Target objects - before this gcing Target was not possible because of the circular reference between Rule and Target.
1 parent 26c8ae1 commit 2f1ed44

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

iptc/ip4tc.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,20 @@ def _set_rule(self, rule):
390390
"""The rule this target or match belong to."""
391391

392392

393+
class _Buffer(object):
394+
def __init__(self, size=0):
395+
if size > 0:
396+
self.buffer = _malloc(size)
397+
if self.buffer is None:
398+
raise Exception("Can't allocate buffer")
399+
else:
400+
self.buffer = None
401+
402+
def __del__(self):
403+
if self.buffer is not None:
404+
_free(self.buffer)
405+
406+
393407
class Match(IPTCModule):
394408
"""Matches are extensions which can match for special header fields or
395409
other attributes of a packet.
@@ -556,15 +570,11 @@ def __init__(self, rule, name=None, target=None, revision=None):
556570
else:
557571
self._revision = self._module.revision
558572

559-
self._allocate_buffer(target)
573+
self._create_buffer(target)
560574

561575
if self._is_standard_target():
562576
self.standard_target = name
563577

564-
def __del__(self):
565-
if getattr(self, "_target_buf", None) and self._target_buf is not None:
566-
_free(self._target_buf)
567-
568578
def __eq__(self, targ):
569579
basesz = ct.sizeof(xt_entry_target)
570580
if (self.target.u.target_size != targ.target.u.target_size or
@@ -586,10 +596,9 @@ def __eq__(self, targ):
586596
def __ne__(self, target):
587597
return not self.__eq__(target)
588598

589-
def _allocate_buffer(self, target):
590-
self._target_buf = _malloc(self.size)
591-
if self._target_buf is None:
592-
raise Exception("Can't allocate target buffer")
599+
def _create_buffer(self, target):
600+
self._buffer = _Buffer(self.size)
601+
self._target_buf = self._buffer.buffer
593602
if target:
594603
ct.memmove(self._target_buf, ct.byref(target), self.size)
595604
self._update_pointers()
@@ -610,6 +619,7 @@ def _parse(self, argv, inv, entry):
610619
self._xt.parse_target(argv, inv, self._module, entry,
611620
ct.cast(self._ptrptr, ct.POINTER(ct.c_void_p)))
612621
self._target_buf = ct.cast(self._module.t, ct.POINTER(ct.c_ubyte))
622+
self._buffer.buffer = self._target_buf
613623
self._update_pointers()
614624

615625
def _get_size(self):

0 commit comments

Comments
 (0)