ports/146125: [maintainer] archivers/libpar2 segfault fix and cancellation enhancement.

Jeff Burchell toxic at doobie.com
Wed Apr 28 21:10:02 UTC 2010


>Number:         146125
>Category:       ports
>Synopsis:       [maintainer] archivers/libpar2 segfault fix and cancellation enhancement.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          maintainer-update
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 28 21:10:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Jeff Burchell
>Release:        8.0-RELEASE-p2 i386
>Organization:
>Environment:
FreeBSD gazania 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 #0: Tue Jan  5 16:02:27 UTC 2010     root at i386-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
This update includes two patches submitted against libpar2 by Andrei Prygounkov, author of nzbget.

One of them is a bugfix that closes a memory leak triggered by corrupted PAR2 files. That fix is included in some linux vendors' libpar2 packages, and is well-tested.

The other adds additional functionality: a method to cancel a file repair in progress.  This patch can be disabled through a config option.  It is enabled by default because the only application in the ports tree that links against libpar2 is news/nzbget.  Nzbget makes use of this functionality if it is available.

It appears that libpar2 has been abandoned upstream (there's been no activity in the CVS tree since 2006).  If it were being maintained, both of these patches would likely be included.


>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff -udrN libpar2-orig/Makefile libpar2/Makefile
--- libpar2-orig/Makefile	2009-08-21 17:12:53.000000000 -0700
+++ libpar2/Makefile	2010-04-28 13:02:53.000000000 -0700
@@ -7,7 +7,7 @@
 
 PORTNAME=	libpar2
 PORTVERSION=	0.2
-PORTREVISION=	2
+PORTREVISION=	3
 CATEGORIES=	archivers
 MASTER_SITES=	SF/parchive/${PORTNAME}/${PORTVERSION}
 DISTNAME=	${PORTNAME}-${PORTVERSION}
@@ -24,10 +24,18 @@
 
 USE_LDCONFIG=	yes
 
+OPTIONS=	ENABLECANCEL "Enable graceful cancellation of repairs" On
+
+.include <bsd.port.pre.mk>
+
+.if defined(WITH_ENABLECANCEL)
+EXTRA_PATCHES+=	${FILESDIR}/xpatch-addcancel-par2repairer.cpp
+.endif
+
 post-install:
 .if !defined(NOPORTDOCS)
 	@${MKDIR} ${DOCSDIR}
 	${INSTALL_MAN} ${WRKSRC}/README ${DOCSDIR}
 .endif
 
-.include <bsd.port.mk>
+.include <bsd.port.post.mk>
diff -udrN libpar2-orig/files/patch-ChangeLog libpar2/files/patch-ChangeLog
--- libpar2-orig/files/patch-ChangeLog	2008-08-16 23:48:21.000000000 -0700
+++ libpar2/files/patch-ChangeLog	2010-04-28 12:18:17.000000000 -0700
@@ -1,6 +1,10 @@
---- ChangeLog.orig	2006-02-03 08:07:23.000000000 -0800
-+++ ChangeLog	2008-08-16 13:10:41.000000000 -0700
-@@ -1,3 +1,6 @@
+--- ChangeLog.orig	2010-04-28 12:17:05.000000000 -0700
++++ ChangeLog	2010-04-28 12:16:35.000000000 -0700
+@@ -1,3 +1,10 @@
++28 Apr 2010 FreeBSD Port
++	* Fix memory leak/segfault under certain circumstances.
++           http://sf.net/tracker/?func=detail&aid=2209433&group_id=30568&atid=399700
++
 +16 Aug 2008 FreeBSD Port
 +	* Fix 2G overflow for data_size (backported from vendor CVS)
 +
diff -udrN libpar2-orig/files/patch-par2repairer.cpp libpar2/files/patch-par2repairer.cpp
--- libpar2-orig/files/patch-par2repairer.cpp	1969-12-31 16:00:00.000000000 -0800
+++ libpar2/files/patch-par2repairer.cpp	2010-04-28 12:35:44.000000000 -0700
@@ -0,0 +1,36 @@
+#####
+# This patch is maintained by Andrei Prygounkov, author of news/nzbget
+# It fixes a memory leak and a segfault triggered by a corrupted par2 file.
+#
+# For more details, see:
+#       http://sf.net/tracker/?func=detail&aid=2209433&group_id=30568&atid=399700
+#####
+diff -aud ../libpar2-0.2-original/par2repairer.cpp ../libpar2-0.2/par2repairer.cpp
+--- ../libpar2-0.2-original/par2repairer.cpp	2006-01-20 18:25:20.000000000 +0100
++++ ../libpar2-0.2/par2repairer.cpp	2008-02-06 12:02:53.226050300 +0100
+@@ -78,6 +78,7 @@
+ 
+   delete mainpacket;
+   delete creatorpacket;
++  delete headers;
+ }
+ 
+ 
+@@ -1261,7 +1262,7 @@
+         DiskFile::SplitFilename(filename, path, name);
+ 
+         cout << "Target: \"" << name << "\" - missing." << endl;
+-	sig_done.emit(name, 0, sourcefile->GetVerificationPacket()->BlockCount());
++	sig_done.emit(name, 0, sourcefile->GetVerificationPacket() ? sourcefile->GetVerificationPacket()->BlockCount() : 0);
+       }
+     }
+ 
+@@ -1804,7 +1805,7 @@
+       }
+     }
+   }
+-  sig_done.emit(name,count,sourcefile->GetVerificationPacket()->BlockCount()); 
++  sig_done.emit(name,count, sourcefile->GetVerificationPacket() ? sourcefile->GetVerificationPacket()->BlockCount() : 0); 
+   sig_progress.emit(1000.0);
+   return true;
+ }
diff -udrN libpar2-orig/files/xpatch-addcancel-par2repairer.cpp libpar2/files/xpatch-addcancel-par2repairer.cpp
--- libpar2-orig/files/xpatch-addcancel-par2repairer.cpp	1969-12-31 16:00:00.000000000 -0800
+++ libpar2/files/xpatch-addcancel-par2repairer.cpp	2010-04-28 12:34:51.000000000 -0700
@@ -0,0 +1,194 @@
+#####
+# This patch is maintained by Andrei Prygounkov, author of news/nzbget
+# It adds a graceful method to cancel file repair operations in progress.
+#
+# For more details, see: 
+#	http://sf.net/tracker/?func=detail&aid=2209488&group_id=30568&atid=399700 
+#####
+diff -aud ../libpar2-0.2-original/par2repairer.cpp ../libpar2-0.2/par2repairer.cpp
+--- ../libpar2-0.2-original/par2repairer.cpp	2008-10-26 19:54:33.000000000 +0100
++++ ../libpar2-0.2/par2repairer.cpp	2008-10-29 10:24:48.000000000 +0100
+@@ -52,6 +52,8 @@
+   noiselevel = CommandLine::nlNormal;
+   headers = new ParHeaders;
+   alreadyloaded = false;
++
++  cancelled = false;
+ }
+ 
+ Par2Repairer::~Par2Repairer(void)
+@@ -406,6 +408,10 @@
+           progress = offset;
+ 	sig_progress.emit(newfraction);
+ 
++          if (cancelled)
++          {
++            break;
++          }
+         }
+       }
+ 
+@@ -584,6 +590,11 @@
+     delete diskfile;
+   }
+   
++  if (cancelled)
++  {
++    return false;
++  }
++
+   return true;
+ }
+ 
+@@ -833,9 +844,17 @@
+     for (list<string>::const_iterator s=files->begin(); s!=files->end(); ++s)
+     {
+       LoadPacketsFromFile(*s);
++      if (cancelled)
++      {
++        break;
++      }
+     }
+ 
+     delete files;
++    if (cancelled)
++    {
++      return false;
++    }
+   }
+ 
+   {
+@@ -846,9 +865,17 @@
+     for (list<string>::const_iterator s=files->begin(); s!=files->end(); ++s)
+     {
+       LoadPacketsFromFile(*s);
++      if (cancelled)
++      {
++        break;
++      }
+     }
+ 
+     delete files;
++    if (cancelled)
++    {
++      return false;
++    }
+   }
+ 
+   return true;
+@@ -866,9 +893,18 @@
+         string::npos != filename.find(".PAR2"))
+     {
+       LoadPacketsFromFile(filename);
++      if (cancelled)
++      {
++        break;
++      }
+     }
+   }
+ 
++  if (cancelled)
++  {
++    return false;
++  }
++
+   return true;
+ }
+ 
+@@ -1210,6 +1246,11 @@
+   sf = sortedfiles.begin();
+   while (sf != sortedfiles.end())
+   {
++    if (cancelled)
++    {
++      return false;
++    }
++
+     // Do we have a source file
+     Par2RepairerSourceFile *sourcefile = *sf;
+ 
+@@ -1562,6 +1603,10 @@
+         cout << "Scanning: \"" << shortname << "\": " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush;
+ 	sig_progress.emit(newfraction);
+ 
++        if (cancelled)
++        {
++          break;
++        }
+       }
+     }
+ 
+@@ -1651,6 +1696,11 @@
+     }
+   }
+ 
++  if (cancelled)
++  {
++    return false;
++  }
++
+   // Get the Full and 16k hash values of the file
+   filechecksummer.GetFileHashes(hashfull, hash16k);
+ 
+@@ -2291,10 +2341,19 @@
+             cout << "Repairing: " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush;
+ 	    sig_progress.emit(newfraction);
+ 
++            if (cancelled)
++            {
++              break;
++            }
+           }
+         }
+       }
+ 
++      if (cancelled)
++      {
++        break;
++      }
++
+       ++inputblock;
+       ++inputindex;
+     }
+@@ -2348,9 +2407,18 @@
+           cout << "Processing: " << newfraction/10 << '.' << newfraction%10 << "%\r" << flush;
+ 	sig_progress.emit(newfraction);
+ 
++          if (cancelled)
++          {
++            break;
++          }
+         }
+       }
+ 
++      if (cancelled)
++      {
++        break;
++      }
++
+       ++copyblock;
+       ++inputblock;
+     }
+@@ -2362,6 +2430,11 @@
+     lastopenfile->Close();
+   }
+ 
++  if (cancelled)
++  {
++    return false;
++  }
++
+   if (noiselevel > CommandLine::nlQuiet)
+     cout << "Writing recovered data\r";
+ 
+diff -aud ../libpar2-0.2-original/par2repairer.h ../libpar2-0.2/par2repairer.h
+--- ../libpar2-0.2-original/par2repairer.h	2006-01-20 00:38:27.000000000 +0100
++++ ../libpar2-0.2/par2repairer.h	2008-10-26 19:01:08.000000000 +0100
+@@ -183,6 +183,7 @@
+   u64                       totaldata;               // Total amount of data to be processed.
+   u64                       totalsize;               // Total data size
+ 
++  bool                      cancelled;               // repair cancelled
+ };
+ 
+ #endif // __PAR2REPAIRER_H__


>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list