Группа :: Разработка/Perl
Пакет: perl-RPM
Главная Изменения Спек Патчи Загрузить Bugs and FR
Патч: perl-RPM-0.40-alt-fix-memleaks.patch
--- Perl-RPM-0.40/t/09_leaks.t- 2005-04-02 19:07:11 +0400
+++ Perl-RPM-0.40/t/09_leaks.t 2005-04-02 19:11:46 +0400
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+use strict;
+use Devel::Leak;
+use Test::More tests => 8;
+
+sub test_leak (&$;$) {
+ my ($code, $descr, $maxleak) = (@_, 0);
+ my $n1 = Devel::Leak::NoteSV(my $handle);
+ $code->() for 0..3;
+ my $n2 = Devel::Leak::CheckSV($handle);
+ cmp_ok($n1 + $maxleak, '>=', $n2, $descr);
+}
+
+use RPM::Database;
+
+test1: test_leak { my $db = RPM::Database->new or die }
+ "rpmdb_TIEHASH", 1; # XXX
+
+test2: test_leak { my $db = RPM::Database->new(root => "/dev/null") }
+ "rpmdb_TIEHASH w/ invalid args (errSV set OK)", 1;
+
+test3: test_leak { my $db = RPM::Database->new or die;
+ for (0..3) { my $hdr = $$db{rpm} or die; } }
+ "rpmdb_FETCH";
+
+test4: test_leak { my $db = RPM::Database->new or die;
+ for (0..3) { my $hdr = $$db{rpm} or die;
+ for (0..3) {
+ my $name = $$hdr{NAME} or die;
+ my $summary = $$hdr{SUMMARY} or die; } } }
+ "rpmhdr_FETCH";
+
+test5: test_leak { my $db = RPM::Database->new or die;
+ for (0..3) { $db->find_by_file("/usr/bin/perl") or die; } }
+ "find_by_file";
+
+test6: test_leak { my $db = RPM::Database->new or die;
+ for (0..3) { $db->find_what_provides("libc.so.6") or die; } }
+ "find_what_provides";
+
+# expensive tests
+test7: test_leak { my $db = RPM::Database->new or die;
+ for (0..3) { $db->find_what_requires("libc.so.6") or die; } }
+ "find_what_requires";
+
+test8: test_leak { my $db = RPM::Database->new or die;
+ while (my ($k, $v) = each %$db) { die if $k eq $v; } }
+ "rpmdb_NEXTKEY";
--- Perl-RPM-0.40/RPM/Database.xs- 2002-05-10 09:53:48 +0400
+++ Perl-RPM-0.40/RPM/Database.xs 2005-04-02 19:16:53 +0400
@@ -56,8 +56,11 @@
/* The retvalp is used for the C-level rpmlib information on databases */
Newz(0, retvalp, 1, RPM_Database);
if (rpmdbOpen(root, &retvalp->dbp, mode, perms) != 0)
+ {
+ Safefree(retvalp);
/* rpm lib will have set the error already */
return (Null(RPM__Database));
+ }
else
{
retvalp->current_rec = 0;
@@ -100,11 +103,13 @@
{
name = SvPV(key, namelen);
+#if 0
/* Step 1: Check to see if this has already been requested and is
thus cached on the hash itself */
svp = hv_fetch(dbstruct->storage, (char *)name, namelen, FALSE);
if (svp && SvROK(*svp))
return newSVsv(*svp);
+#endif
offset = -1;
lasthdr = NULL;
@@ -155,14 +160,18 @@
FETCHp = rpmhdr_TIEHASH(aTHX_ "RPM::Header",
sv_2mortal(newSViv((unsigned)hdr)),
RPM_HEADER_FROM_REF | RPM_HEADER_READONLY);
+#if 0
if (name == Null(const char *))
name = SvPV(rpmhdr_FETCH(aTHX_ FETCHp,
- sv_2mortal(newSVpv("NAME", 4)),
+ sv_2mortal(newSVpvn("NAME", 4)),
Null(const char *), 0, 0), namelen);
+#endif
FETCH = sv_bless(newRV_noinc((SV*)FETCHp),
gv_stashpv("RPM::Header", TRUE));
+#if 0
hv_store(dbstruct->storage, (char *)name, namelen, newSVsv(FETCH),
FALSE);
+#endif
}
rpmdbFreeIterator(mi);
@@ -173,7 +182,7 @@
{
SV* tmp;
- tmp = rpmdb_FETCH(aTHX_ self, key);
+ tmp = sv_2mortal(rpmdb_FETCH(aTHX_ self, key));
return (tmp != &PL_sv_undef);
}
@@ -194,14 +203,14 @@
Header h;
if (dbstruct->offsets)
- free(dbstruct->offsets);
+ free(dbstruct->offsets); /* realloc */
dbstruct->offsets = NULL;
dbstruct->noffs = 0;
mi = rpmdbInitIterator(dbstruct->dbp, RPMDBI_PACKAGES, NULL, 0);
while ((h = rpmdbNextIterator(mi)) != NULL)
{
dbstruct->noffs++;
- dbstruct->offsets =
+ dbstruct->offsets = /* XXX realloc? */
realloc(dbstruct->offsets,
dbstruct->noffs * sizeof(dbstruct->offsets[0]));
dbstruct->offsets[dbstruct->noffs-1] = rpmdbGetIteratorOffset(mi);
@@ -215,8 +224,8 @@
dbstruct->offx = 0;
dbstruct->current_rec = dbstruct->offsets[dbstruct->offx++];
- *value = rpmdb_FETCH(aTHX_ self, newSViv(dbstruct->current_rec));
- *key = rpmhdr_FETCH(aTHX_ (RPM__Header)SvRV(*value), newSVpv("name", 4),
+ *value = rpmdb_FETCH(aTHX_ self, sv_2mortal(newSViv(dbstruct->current_rec)));
+ *key = rpmhdr_FETCH(aTHX_ (RPM__Header)SvRV(*value), sv_2mortal(newSVpvn("name", 4)),
Nullch, 0, 0);
return 1;
@@ -236,9 +245,9 @@
dbstruct->current_rec = dbstruct->offsets[dbstruct->offx++];
- *nextvalue = rpmdb_FETCH(aTHX_ self, newSViv(dbstruct->current_rec));
+ *nextvalue = rpmdb_FETCH(aTHX_ self, sv_2mortal(newSViv(dbstruct->current_rec)));
*nextkey = rpmhdr_FETCH(aTHX_ (RPM__Header)SvRV(*nextvalue),
- newSVpv("name", 4), Nullch, 0, 0);
+ sv_2mortal(newSVpvn("name", 4)), Nullch, 0, 0);
return 1;
}
@@ -251,11 +260,13 @@
rpmdbClose(dbstruct->dbp);
if (dbstruct->offsets)
- Safefree(dbstruct->offsets);
+ free(dbstruct->offsets); /* realloc */
hv_undef(dbstruct->storage);
+ sv_free((SV*) dbstruct->storage);
Safefree(dbstruct);
- hv_undef(self);
+/* CLEAR: operation not permitted
+ hv_undef(self); */
}
int rpmdb_init(SV* class, const char* root, int perms)
@@ -312,7 +323,7 @@
{
idx = rpmdbGetIteratorOffset(mi);
tmp_hdr = rpmdb_FETCH(aTHX_ self, sv_2mortal(newSViv(idx)));
- av_store(return_val, loop++, sv_2mortal(newSVsv(tmp_hdr)));
+ av_store(return_val, loop++, newSVsv(sv_2mortal(tmp_hdr)));
}
}
rpmdbFreeIterator(mi);
@@ -410,7 +421,7 @@
EXTEND(SP, 2);
PUSHs(sv_2mortal(value));
- PUSHs(sv_2mortal(newSVsv(key)));
+ PUSHs(sv_2mortal(key));
}
void
@@ -431,7 +442,7 @@
EXTEND(SP, 2);
PUSHs(sv_2mortal(nextvalue));
- PUSHs(sv_2mortal(newSVsv(nextkey)));
+ PUSHs(sv_2mortal(nextkey));
}
void
@@ -503,5 +514,7 @@
else
size = 0;
+ av_undef(matches);
+ sv_free((SV*) matches);
XSRETURN(size);
}
--- Perl-RPM-0.40/RPM/Header.xs- 2002-05-10 11:37:08 +0400
+++ Perl-RPM-0.40/RPM/Header.xs 2005-04-02 18:39:16 +0400
@@ -203,6 +203,7 @@
{
new_item = newSVsv(*av_fetch(new_list, 0, FALSE));
av_undef(new_list);
+ sv_free((SV *) new_list);
}
else
new_item = newRV_noinc((SV *)new_list);
@@ -368,6 +370,8 @@
return FETCH;
}
+ sv_free(FETCH);
+
/* Check the three keys that are cached directly on the struct itself: */
if (! strcmp(uc_name, "NAME"))
FETCH = newSVpv((char *)hdr->name, 0);
@@ -409,6 +413,7 @@
"RPM::Header::FETCH: no tag '%s' in header", uc_name);
rpm_error(aTHX_ RPMERR_BADARG, errmsg);
Safefree(uc_name);
+ FETCH = newSVsv(&PL_sv_undef);
return FETCH;
}
FETCH = rpmhdr_create(aTHX_ new_item_p, new_item_type, size,
@@ -954,10 +959,12 @@
headerFree(hdr->hdr);
hv_undef(hdr->storage);
+ sv_free((SV *) hdr->storage);
if (hdr->source_name)
Safefree(hdr->source_name);
Safefree(hdr);
- hv_undef(self);
+/* CLEAR: operation not permitted
+ hv_undef(self); */
}
unsigned int rpmhdr_size(pTHX_ RPM__Header self)
@@ -1382,10 +1389,9 @@
snprintf(errmsg, 256,
"RPM::Header::scalar_tag: unknown tag %s", uc_name);
rpm_error(aTHX_ RPMERR_BADARG, errmsg);
- Safefree(uc_name);
RETVAL = 0;
}
-
+ Safefree(uc_name);
RETVAL = scalar_tag(aTHX_ self, tag_value);
}
}
--- Perl-RPM-0.40/typemap- 2000-11-10 11:49:57 +0300
+++ Perl-RPM-0.40/typemap 2005-04-02 15:16:17 +0400
@@ -18,7 +18,7 @@
}
else
{
- $arg = newSVsv(&PL_sv_undef);
+ $arg = &PL_sv_undef;
}
O_RPM_Blessed
@@ -29,7 +29,7 @@
}
else
{
- $arg = newSVsv(&PL_sv_undef);
+ $arg = &PL_sv_undef;
}
INPUT
@@ -54,4 +54,4 @@
rpm_error(aTHX_ RPMERR_BADARG,
\"$var is not of type ${ntype}\");
XSRETURN_UNDEF;
- }
\ No newline at end of file
+ }