Репозиторий ALT Linux backports/2.4
Последнее обновление: 9 июля 2008 | Пакетов: 497 | Посещений: 1583568
 поиск   регистрация   авторизация 
 
Группа :: Разработка/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
+        }
 
design & coding: Vladimir Lettiev aka crux © 2004-2005