import zziplib-0.13.68-7.el8

This commit is contained in:
CentOS Sources 2019-05-07 09:45:58 -04:00 committed by Andrew Lukoshko
commit 8a0cf4bd17
15 changed files with 1982 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/v0.13.68.tar.gz

1
.zziplib.metadata Normal file
View File

@ -0,0 +1 @@
bf62bf6138a7a5bddbad41d6c5dbb169e1528110 SOURCES/v0.13.68.tar.gz

View File

@ -0,0 +1,850 @@
From f04dd2918b15853e866d3941b72005696c8c3b8f Mon Sep 17 00:00:00 2001
From: Jakub Martisko <jamartis@redhat.com>
Date: Tue, 3 Jul 2018 09:33:07 +0200
Subject: [PATCH] FIX: port documentation scripts to python3
---
configure | 2 +-
configure.ac | 2 +-
docs/cpp2markdown-1.py | 9 ++++--
docs/cpp2markdown.py | 6 ++--
docs/make-doc.py | 56 ++++++++++++++++++-----------------
docs/makedocs.py | 26 ++++++++--------
docs/zzipdoc/commentmarkup.py | 5 ++--
docs/zzipdoc/dbk2htm.py | 5 ++--
docs/zzipdoc/docbookdocument.py | 34 +++++++++++----------
docs/zzipdoc/functionheader.py | 3 +-
docs/zzipdoc/functionlisthtmlpage.py | 14 +++++----
docs/zzipdoc/functionlistreference.py | 8 +++--
docs/zzipdoc/functionprototype.py | 3 +-
docs/zzipdoc/htm2dbk.py | 10 ++++---
docs/zzipdoc/htmldocument.py | 34 +++++++++++----------
docs/zzipdoc/match.py | 17 ++++++-----
docs/zzipdoc/options.py | 5 ++--
docs/zzipdoc/textfile.py | 6 ++--
docs/zzipdoc/textfileheader.py | 6 ++--
18 files changed, 140 insertions(+), 109 deletions(-)
diff --git a/configure b/configure
index 72a5b6c..6ff3ee4 100755
--- a/configure
+++ b/configure
@@ -12270,7 +12270,7 @@ fi
done
test -n "$PERL" || PERL="echo no perl found for"
-for ac_prog in python
+for ac_prog in python3
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
diff --git a/configure.ac b/configure.ac
index 4708f8d..68aeb73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,7 +87,7 @@ AX_CREATE_PKGCONFIG_INFO(dnl
AX_PAX_TAR_CREATE
AX_PAX_TAR_EXTRACT
AC_PATH_PROGS(PERL, perl5 perl, echo no perl found for)
-AC_PATH_PROGS(PYTHON, python, echo no python found for)
+AC_PATH_PROGS(PYTHON, python3, echo no python found for)
AC_PATH_PROGS(MKZIP, zip pkzip, :)
AC_PATH_PROGS(XMLTO, xmlto, :)
diff --git a/docs/cpp2markdown-1.py b/docs/cpp2markdown-1.py
index 60d28c4..1deaed9 100755
--- a/docs/cpp2markdown-1.py
+++ b/docs/cpp2markdown-1.py
@@ -1,9 +1,12 @@
#! /usr/bin/env python
+from __future__ import absolute_import
+from __future__ import print_function
import pygments.lexers.compiled as lexer
import optparse
import re
from pygments.token import Token
import logging
+from six.moves import range
logg = logging.getLogger(__name__)
@@ -39,7 +42,7 @@ class CppToMarkdown:
check2 = re.compile(r"^\s[*]\s+\b[Cc]opyright\b")
empty1 = re.compile(r"^\s[*]\s*$")
state = "intro"
- for i in xrange(1,len(lines)-1):
+ for i in range(1,len(lines)-1):
line = lines[i]
if state == "intro":
if empty1.match(line):
@@ -108,7 +111,7 @@ class CppToMarkdown:
def run(self, filename):
filetext = open(filename).read()
for line in self.process(filetext, filename):
- print line
+ print(line)
def process(self, filetext, filename=""):
section_ruler = "-----------------------------------------"
copyright = ""
@@ -136,7 +139,7 @@ class CppToMarkdown:
else:
if text:
yield "#### NOTES"
- print token, text.replace("\n", "\n ")
+ print(token, text.replace("\n", "\n "))
if copyright:
yield section_ruler
yield "### COPYRIGHT"
diff --git a/docs/cpp2markdown.py b/docs/cpp2markdown.py
index 710bbdc..b8fe11d 100644
--- a/docs/cpp2markdown.py
+++ b/docs/cpp2markdown.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+from __future__ import print_function
import pygments.lexers.compiled as lexer
import optparse
import re
@@ -62,7 +64,7 @@ class CppToMarkdown:
def run(self, filename):
filetext = open(filename).read()
for line in self.process(filetext, filename):
- print line
+ print(line)
def process(self, filetext, filename=""):
for token, text in self.parse(filetext):
if token == FileInclude:
@@ -86,7 +88,7 @@ class CppToMarkdown:
else:
if text:
yield "#### NOTES"
- print token, text.replace("\n", "\n ")
+ print(token, text.replace("\n", "\n "))
def isexported_function(self):
function = self.function_text.strip().replace("\n"," ")
logg.debug("@ --------------------------------------")
diff --git a/docs/make-doc.py b/docs/make-doc.py
index f12553f..22775ef 100644
--- a/docs/make-doc.py
+++ b/docs/make-doc.py
@@ -1,5 +1,7 @@
#! /usr/bin/python
# -*- coding: UTF-8 -*-
+from __future__ import absolute_import
+from __future__ import print_function
import sys
import re
import string
@@ -23,7 +25,7 @@ def s(string, pattern, repl, count=0):
def m(string, pattern):
return re.match(pattern, string)
def sorted_keys(dict):
- keys = dict.keys()
+ keys = list(dict.keys())
keys.sort()
return keys
@@ -59,18 +61,18 @@ def section2html(text):
"<para>" : "<p>", "</para>" : "</p>" ,
"<function>" : "<link>", "</function>" : "</link>" }
for str in mapping:
- text = string.replace(text, str, mapping[str])
+ text = text.replace(str, mapping[str])
return text
def html(text):
return section2html(paramdef2html(text))
def cdata1(text):
- return string.replace(text, "&", "&amp;")
+ return text.replace("&", "&amp;")
def cdata31(text):
- return string.replace(string.replace(text, "<","&lt;"), ">","&gt;")
+ return text.replace(text, "<","&lt;").replace( ">","&gt;")
def cdata3(text):
return cdata31(cdata1(text))
def cdata43(text):
- return string.replace(text,"\"", "&quot;")
+ return text.replace("\"", "&quot;")
def cdata41(text):
return cdata43(cdata31(text))
def cdata4(text):
@@ -126,7 +128,7 @@ def this_function_link(text, name):
class Options:
var = {}
def __getattr__(self, name):
- if not self.var.has_key(name): return None
+ if name not in self.var: return None
return self.var[name]
def __setattr__(self, name, value):
self.var[name] = value
@@ -158,7 +160,7 @@ class File:
self.copyright = ""
def __getattr__(self, name):
""" defend against program to break on uninited members """
- if self.__dict__.has_key(name): return self.__dict__[name]
+ if name in self.__dict__: return self.__dict__[name]
warn("no such member: "+name); return None
def set_author(self, text):
if self.authors:
@@ -215,7 +217,7 @@ def scan_options (options, list):
#else
try:
input = open(name, "r")
- except IOError, error:
+ except IOError as error:
warn(#...... (scan_options) ...............
"can not open input file: "+name, error)
continue
@@ -294,12 +296,12 @@ class Function:
# return ""
def __getattr__(self, name):
""" defend against program exit on members being not inited """
- if self.__dict__.has_key(name): return self.__dict__[name]
+ if name in self.__dict__: return self.__dict__[name]
warn("no such member: "+name); return None
def dict(self):
return self.__dict__
def dict_sorted_keys(self):
- keys = self.__dict__.keys()
+ keys = list(self.__dict__.keys())
keys.sort()
return keys
def parse(self, prototype):
@@ -376,7 +378,7 @@ def examine_head_anchors(func_list):
function.head = s(function.head, r"(.*)also:(.*)", lambda x
: set_seealso(function, x.group(2)) and x.group(1))
if function.seealso and None:
- print "function[",function.name,"].seealso=",function.seealso
+ print("function[",function.name,"].seealso=",function.seealso)
examine_head_anchors(function_list)
# =============================================================== HTML =====
@@ -455,7 +457,7 @@ def combined_html_pages(func_list):
s(ensure_name(this_function_link(section2html( func.body ),
func.name), func.name),
r"(?sx) (</?para>\s*) <br\s*\/>", r"\1"))
- return combined.values()
+ return list(combined.values())
html_pages = combined_html_pages(function_list)
def html_resolve_links_on_page(text, list):
@@ -495,7 +497,7 @@ class HtmlPage:
return T
def add_page_map(self, list):
""" generate the index-block at the start of the onepage-html file """
- keys = list.keys()
+ keys = list(list.keys())
keys.sort()
for name in keys:
self.toc += "<tr valign=\"top\">\n"+ \
@@ -524,11 +526,11 @@ html.add_page_list(html_pages)
# and finally print the html-formatted output
try:
F = open(o.libhtmlfile, "w")
-except IOError, error:
+except IOError as error:
warn(# ............. open(o.libhtmlfile, "w") ..............
"can not open html output file: "+o.libhtmlfile, error)
else:
- print >> F, html.page_text()
+ print(html.page_text(), file=F)
F.close()
#fi
@@ -987,40 +989,40 @@ doctype += '"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">'+"\n"
try:
F = open(o.docbookfile,"w")
-except IOError, error:
+except IOError as error:
warn("can not open docbook output file: "+o.docbookfile, error)
else:
- print >> F, doctype, '<reference><title>Manual Pages</title>'
+ print(doctype, '<reference><title>Manual Pages</title>', file=F)
for page in combined_pages:
- print >> F, page.refentry_text()
+ print(page.refentry_text(), file=F)
#od
for page in header_refpages.values():
if not page.refentry: continue
- print >> F, "\n<!-- _______ "+page.id+" _______ -->",
- print >> F, page.refentry_text()
+ print("\n<!-- _______ "+page.id+" _______ -->", end=' ', file=F)
+ print(page.refentry_text(), file=F)
#od
- print >> F, "\n",'</reference>',"\n"
+ print("\n",'</reference>',"\n", file=F)
F.close()
#fi
# _____________________________________________________________________
try:
F = open( o.dumpdocfile, "w")
-except IOError, error:
+except IOError as error:
warn ("can not open"+o.dumpdocfile,error)
else:
for func in function_list:
name = func.name
- print >> F, "<fn id=\""+name+"\">"+"<!-- FOR \""+name+"\" -->\n"
+ print("<fn id=\""+name+"\">"+"<!-- FOR \""+name+"\" -->\n", file=F)
for H in sorted_keys(func.dict()):
- print >> F, "<"+H+" name=\""+name+"\">",
- print >> F, str(func.dict()[H]),
- print >> F, "</"+H+">"
+ print("<"+H+" name=\""+name+"\">", end=' ', file=F)
+ print(str(func.dict()[H]), end=' ', file=F)
+ print("</"+H+">", file=F)
#od
- print >> F, "</fn><!-- END \""+name+"\" -->\n\n";
+ print("</fn><!-- END \""+name+"\" -->\n\n", file=F);
#od
F.close();
#fi
diff --git a/docs/makedocs.py b/docs/makedocs.py
index 1bc8f88..d987292 100644
--- a/docs/makedocs.py
+++ b/docs/makedocs.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+from __future__ import print_function
import sys
from zzipdoc.match import *
from zzipdoc.options import *
@@ -37,7 +39,7 @@ class PerFile:
return None
def print_list_mainheader(self):
for t_fileheader in self.headers:
- print t_fileheader.get_filename(), t_fileheader.src_mainheader()
+ print(t_fileheader.get_filename(), t_fileheader.src_mainheader())
class PerFunctionEntry:
def __init__(self, header, comment, prototype):
@@ -66,10 +68,10 @@ class PerFunction:
functionprototype) ]
def print_list_titleline(self):
for funcheader in self.headers:
- print funcheader.get_filename(), "[=>]", funcheader.get_titleline()
+ print(funcheader.get_filename(), "[=>]", funcheader.get_titleline())
def print_list_name(self):
for funcheader in self.prototypes:
- print funcheader.get_filename(), "[>>]", funcheader.get_name()
+ print(funcheader.get_filename(), "[>>]", funcheader.get_name())
class PerFunctionFamilyEntry:
def __init__(self, leader):
@@ -122,12 +124,12 @@ class PerFunctionFamily:
for name in self.retarget:
into = self.retarget[name]
if into not in name_list:
- print ("function '"+name+"' retarget into '"+into+
- "' does not exist - keep alone")
+ print(("function '"+name+"' retarget into '"+into+
+ "' does not exist - keep alone"))
if into in self.retarget:
other = self.retarget[into]
- print ("function '"+name+"' retarget into '"+into+
- "' which is itself a retarget into '"+other+"'")
+ print(("function '"+name+"' retarget into '"+into+
+ "' which is itself a retarget into '"+other+"'"))
if into not in lead_list:
lead_list += [ into ]
for func in self.functions:
@@ -141,7 +143,7 @@ class PerFunctionFamily:
entry.add(func) # the first
self.entries += [ entry ]
else:
- print "head function '"+name+" has no entry"
+ print("head function '"+name+" has no entry")
for func in self.functions:
name = func.get_name()
if name in self.retarget:
@@ -150,14 +152,14 @@ class PerFunctionFamily:
if entry is not None:
entry.add(func) # will not add duplicates
else:
- print "into function '"+name+" has no entry"
+ print("into function '"+name+" has no entry")
def print_list_name(self):
for family in self.entries:
name = family.get_name()
- print name, ":",
+ print(name, ":", end=' ')
for item in family.functions:
- print item.get_name(), ",",
- print ""
+ print(item.get_name(), ",", end=' ')
+ print("")
class HtmlManualPageAdapter:
def __init__(self, entry):
""" usually takes a PerFunctionEntry """
diff --git a/docs/zzipdoc/commentmarkup.py b/docs/zzipdoc/commentmarkup.py
index 3f605a7..31727a3 100644
--- a/docs/zzipdoc/commentmarkup.py
+++ b/docs/zzipdoc/commentmarkup.py
@@ -1,4 +1,5 @@
-from match import Match
+from __future__ import absolute_import
+from .match import Match
def markup_link_syntax(text):
""" markup the link-syntax ` => somewhere ` in the text block """
@@ -31,7 +32,7 @@ class CommentMarkup:
comment = self.header.comment
try:
comment = self.header.get_otherlines()
- except Exception, e:
+ except Exception as e:
pass
mode = ""
text = ""
diff --git a/docs/zzipdoc/dbk2htm.py b/docs/zzipdoc/dbk2htm.py
index f8593e6..2b68e95 100644
--- a/docs/zzipdoc/dbk2htm.py
+++ b/docs/zzipdoc/dbk2htm.py
@@ -1,4 +1,5 @@
-from match import Match
+from __future__ import absolute_import
+from .match import Match
import string
class dbk2htm_conversion:
@@ -9,7 +10,7 @@ class dbk2htm_conversion:
pass
def section2html(self, text):
for str in self.mapping:
- text = string.replace(text, str, self.mapping[str])
+ text = text.replace(str, self.mapping[str])
return text
def paramdef2html(self, text):
s = Match()
diff --git a/docs/zzipdoc/docbookdocument.py b/docs/zzipdoc/docbookdocument.py
index c4602ad..44a0b23 100644
--- a/docs/zzipdoc/docbookdocument.py
+++ b/docs/zzipdoc/docbookdocument.py
@@ -1,6 +1,8 @@
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
-from match import Match
+from __future__ import absolute_import
+from __future__ import print_function
+from .match import Match
class DocbookDocument:
""" binds some xml content page with additional markup - in this
@@ -23,14 +25,14 @@ class DocbookDocument:
def get_title(self):
if self.title: return title
try: return self.text[0].get_title()
- except Exception, e: pass
+ except Exception as e: pass
return self.title
def _xml_doctype(self, rootnode):
return "<!DOCTYPE "+rootnode+self.docbook_dtd+">"
def _xml_text(self, xml):
""" accepts adapter objects with .xml_text() """
try: return xml.xml_text()
- except Exception, e: print "DocbookDocument/text", e; pass
+ except Exception as e: print("DocbookDocument/text", e); pass
return str(xml)
def _fetch_rootnode(self, text):
fetch = Match(r"^[^<>]*<(\w+)\b")
@@ -47,7 +49,7 @@ class DocbookDocument:
return filename
def save(self, filename = None):
filename = self._filename(filename)
- print "writing '"+filename+"'"
+ print("writing '"+filename+"'")
if len(self.text) > 1:
self.save_all(filename)
else:
@@ -58,12 +60,12 @@ class DocbookDocument:
xml_text = self._xml_text(text)
rootnode = self._fetch_rootnode(xml_text)
doctype = self._xml_doctype(rootnode)
- print >>fd, doctype
- print >>fd, xml_text
+ print(doctype, file=fd)
+ print(xml_text, file=fd)
fd.close()
return True
- except IOError, e:
- print "could not open '"+filename+"'file", e
+ except IOError as e:
+ print("could not open '"+filename+"'file", e)
return False
def save_all(self, filename):
assert len(self.text) > 1
@@ -76,20 +78,20 @@ class DocbookDocument:
else:
rootnode = self.rootnode
doctype = self._xml_doctype(rootnode)
- print >>fd, doctype
+ print(doctype, file=fd)
title = self.get_title()
if title and self.rootnode in self.has_title_child:
- print >>fd, "<"+self.rootnode+'><title>'+title+'</title>'
+ print("<"+self.rootnode+'><title>'+title+'</title>', file=fd)
elif title:
- print >>fd, "<"+self.rootnode+' id="'+title+'">'
+ print("<"+self.rootnode+' id="'+title+'">', file=fd)
else:
- print >>fd, "<"+self.rootnode+'>'
+ print("<"+self.rootnode+'>', file=fd)
for text in self.text:
text = self._xml_text(text)
- print >>fd, text
- print >>fd, "</"+self.rootnode+">"
+ print(text, file=fd)
+ print("</"+self.rootnode+">", file=fd)
fd.close()
return True
- except IOError, e:
- print "could not open '"+filename+"'file", e
+ except IOError as e:
+ print("could not open '"+filename+"'file", e)
return False
diff --git a/docs/zzipdoc/functionheader.py b/docs/zzipdoc/functionheader.py
index 81bb385..a424a6d 100644
--- a/docs/zzipdoc/functionheader.py
+++ b/docs/zzipdoc/functionheader.py
@@ -1,4 +1,5 @@
-from match import Match
+from __future__ import absolute_import
+from .match import Match
class FunctionHeader:
""" parsing the comment block that is usually presented before
diff --git a/docs/zzipdoc/functionlisthtmlpage.py b/docs/zzipdoc/functionlisthtmlpage.py
index 4ec9178..8009194 100644
--- a/docs/zzipdoc/functionlisthtmlpage.py
+++ b/docs/zzipdoc/functionlisthtmlpage.py
@@ -1,5 +1,7 @@
-from options import *
-from match import Match
+from __future__ import absolute_import
+from __future__ import print_function
+from .options import *
+from .match import Match
class FunctionListHtmlPage:
""" The main part here is to create a TOC (table of contents) at the
@@ -35,7 +37,7 @@ class FunctionListHtmlPage:
head_text = entry.head_xml_text()
body_text = entry.body_xml_text(name)
if not head_text:
- print "no head_text for", name
+ print("no head_text for", name)
return
try:
prespec = entry.head_get_prespec()
@@ -43,7 +45,7 @@ class FunctionListHtmlPage:
callspec = entry.head_get_callspec()
head_text = ("<code><b><function>"+namespec+"</function></b>"
+callspec+" : "+prespec+"</code>")
- except Exception, e:
+ except Exception as e:
pass
try:
extraline = ""
@@ -56,7 +58,7 @@ class FunctionListHtmlPage:
'<em><small>'+filename+'</small></em>'+
'</td></table>')
body_text = extraline + body_text
- except Exception, e:
+ except Exception as e:
pass
def link(text):
return (text & Match("<function>(\w*)</function>")
@@ -102,7 +104,7 @@ class FunctionListHtmlPage:
text &= (Match("(?s)<link>(\w+)</link>")
>> (lambda x: self.resolve_internal(x.group(1))))
if len(self.not_found_in_anchors):
- print "not found in anchors: ", self.not_found_in_anchors
+ print("not found in anchors: ", self.not_found_in_anchors)
return (text & Match("(?s)<link>([^<>]*)</link>")
>> "<code>\\1</code>")
def resolve_external(self, func, sect):
diff --git a/docs/zzipdoc/functionlistreference.py b/docs/zzipdoc/functionlistreference.py
index c38ff0a..5993d45 100644
--- a/docs/zzipdoc/functionlistreference.py
+++ b/docs/zzipdoc/functionlistreference.py
@@ -1,7 +1,9 @@
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
-from match import Match
-from htm2dbk import *
+from __future__ import absolute_import
+from __future__ import print_function
+from .match import Match
+from .htm2dbk import *
class FunctionListReference:
""" Creating a docbook-style <reference> list of <refentry> parts
@@ -19,7 +21,7 @@ class FunctionListReference:
description = entry.body_xml_text(name)
funcsynopsis = entry.head_xml_text()
if not funcsynopsis:
- print "no funcsynopsis for", name
+ print("no funcsynopsis for", name)
return
if self.entry is None:
self.entry = FunctionListRefEntry(entry, self.o)
diff --git a/docs/zzipdoc/functionprototype.py b/docs/zzipdoc/functionprototype.py
index fda85bb..1247f6c 100644
--- a/docs/zzipdoc/functionprototype.py
+++ b/docs/zzipdoc/functionprototype.py
@@ -1,4 +1,5 @@
-from match import Match
+from __future__ import absolute_import
+from .match import Match
class FunctionPrototype:
""" takes a single function prototype line (cut from some source file)
diff --git a/docs/zzipdoc/htm2dbk.py b/docs/zzipdoc/htm2dbk.py
index ec9685b..12b70dd 100644
--- a/docs/zzipdoc/htm2dbk.py
+++ b/docs/zzipdoc/htm2dbk.py
@@ -6,8 +6,10 @@ The mapping of markups and links is far from perfect. But all we
want is the docbook-to-pdf converter and similar technology being
present in the world of docbook-to-anything converters. """
+from __future__ import absolute_import
+from __future__ import print_function
from datetime import date
-import match
+from . import match
import sys
m = match.Match
@@ -146,8 +148,8 @@ def htm2dbk_files(args):
doc.filename = filename
doc.add(f.read())
f.close()
- except IOError, e:
- print >> sys.stderr, "can not open "+filename
+ except IOError as e:
+ print("can not open "+filename, file=sys.stderr)
return doc.value()
def html2docbook(text):
@@ -155,4 +157,4 @@ def html2docbook(text):
return htm2dbk_conversion().convert2(text)
if __name__ == "__main__":
- print htm2dbk_files(sys.argv[1:])
+ print(htm2dbk_files(sys.argv[1:]))
diff --git a/docs/zzipdoc/htmldocument.py b/docs/zzipdoc/htmldocument.py
index 47d58dc..5e4445a 100644
--- a/docs/zzipdoc/htmldocument.py
+++ b/docs/zzipdoc/htmldocument.py
@@ -1,6 +1,8 @@
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
-from match import Match
+from __future__ import absolute_import
+from __future__ import print_function
+from .match import Match
class HtmlDocument:
""" binds some html content page with additional markup - in this
@@ -29,31 +31,31 @@ class HtmlDocument:
def get_title(self):
if self.title: return self.title
try: return self.text[0].get_title()
- except Exception, e: pass
+ except Exception as e: pass
return self.title
def _html_meta(self, meta):
""" accepts adapter objects with .html_meta() """
try: return meta.html_meta()
- except Exception, e: pass
+ except Exception as e: pass
return str(meta)
def _html_style(self, style):
""" accepts adapter objects with .html_style() and .xml_style() """
ee = None
try: return style.html_style()
- except Exception, e: ee = e; pass
+ except Exception as e: ee = e; pass
try: return style.xml_style()
- except Exception, e: print "HtmlDocument/style", ee, e; pass
+ except Exception as e: print("HtmlDocument/style", ee, e); pass
try: return str(style)
- except Exception, e: print "HtmlDocument/style", e; return ""
+ except Exception as e: print("HtmlDocument/style", e); return ""
def _html_text(self, html):
""" accepts adapter objects with .html_text() and .xml_text() """
ee = None
try: return html.html_text()
- except Exception, e: ee = e; pass
+ except Exception as e: ee = e; pass
try: return html.xml_text()
- except Exception, e: print "HtmlDocument/text", ee, e; pass
+ except Exception as e: print("HtmlDocument/text", ee, e); pass
try: return str(html)
- except Exception, e: print "HtmlDocument/text", e; return "&nbsp;"
+ except Exception as e: print("HtmlDocument/text", e); return "&nbsp;"
def navigation(self):
if self.navi:
return self.navi
@@ -63,7 +65,7 @@ class HtmlDocument:
self.navi = fd.read()
fd.close()
return self.navi
- except Exception, e:
+ except Exception as e:
pass
return None
def html_header(self):
@@ -103,15 +105,15 @@ class HtmlDocument:
return filename
def save(self, filename = None):
filename = self._filename(filename)
- print "writing '"+filename+"'"
+ print("writing '"+filename+"'")
try:
fd = open(filename, "w")
- print >>fd, self.html_header()
+ print(self.html_header(), file=fd)
for text in self.text:
- print >>fd, self._html_text(text)
- print >>fd, self.html_footer()
+ print(self._html_text(text), file=fd)
+ print(self.html_footer(), file=fd)
fd.close()
return True
- except IOError, e:
- print "could not open '"+filename+"'file", e
+ except IOError as e:
+ print("could not open '"+filename+"'file", e)
return False
diff --git a/docs/zzipdoc/match.py b/docs/zzipdoc/match.py
index a089ec3..5f12478 100644
--- a/docs/zzipdoc/match.py
+++ b/docs/zzipdoc/match.py
@@ -3,7 +3,10 @@
# @creator (C) 2003 Guido U. Draheim
# @license http://creativecommons.org/licenses/by-nc-sa/2.0/de/
+from __future__ import absolute_import
+from __future__ import print_function
import re
+import six
# ---------------------------------------------------------- Regex Match()
# beware, stupid python interprets backslashes in replace-parts only partially!
@@ -18,7 +21,7 @@ class MatchReplace:
MatchReplace.__call__(self, matching, template, count, flags)
def __call__(self, matching, template = None, count = 0, flags = None):
""" other than __init__ the template may be left off to be unchanged"""
- if isinstance(count, basestring): # count/flags swapped over?
+ if isinstance(count, six.string_types): # count/flags swapped over?
flags = count; count = 0
if isinstance(matching, Match):
self.matching = matching
@@ -57,7 +60,7 @@ class Match(str):
def __call__(self, pattern, flags = None):
assert isinstance(pattern, str) or pattern is None
assert isinstance(flags, str) or flags is None
- str.__init__(self, pattern)
+ super(Match,self).__init__()
self.replaced = 0 # set by subn() inside MatchReplace
self.found = None # set by search() to a MatchObject
self.pattern = pattern
@@ -90,14 +93,14 @@ class Match(str):
if __name__ == "__main__":
# matching:
if "foo" & Match("oo"):
- print "oo"
+ print("oo")
x = Match()
if "foo" & x("(o+)"):
- print x[1]
+ print(x[1])
# replacing:
y = "fooboo" & Match("oo") >> "ee"
- print y
+ print(y)
r = Match("oo") >> "ee"
- print "fooboo" & r
+ print("fooboo" & r)
s = MatchReplace("oo", "ee")
- print "fooboo" & s
+ print("fooboo" & s)
diff --git a/docs/zzipdoc/options.py b/docs/zzipdoc/options.py
index c6758d5..4a93bb7 100644
--- a/docs/zzipdoc/options.py
+++ b/docs/zzipdoc/options.py
@@ -3,13 +3,14 @@
# @creator (C) 2003 Guido U. Draheim
# @license http://creativecommons.org/licenses/by-nc-sa/2.0/de/
-from match import Match
+from __future__ import absolute_import
+from .match import Match
# use as o.optionname to check for commandline options.
class Options:
var = {}
def __getattr__(self, name):
- if not self.var.has_key(name): return None
+ if name not in self.var: return None
return self.var[name]
def __setattr__(self, name, value):
self.var[name] = value
diff --git a/docs/zzipdoc/textfile.py b/docs/zzipdoc/textfile.py
index bfaff8d..9fabeac 100644
--- a/docs/zzipdoc/textfile.py
+++ b/docs/zzipdoc/textfile.py
@@ -1,4 +1,6 @@
+from __future__ import absolute_import
+from six.moves import range
def _src_to_xml(text):
return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt")
@@ -17,7 +19,7 @@ class TextFile:
self.src_text = fd.read()
fd.close()
return True
- except IOError, e:
+ except IOError as e:
pass
return False
def assert_src_text(self):
@@ -41,7 +43,7 @@ class TextFile:
self._line(self.src_text, offset)
def _line(self, text, offset):
line = 1
- for x in xrange(0,offset):
+ for x in range(0,offset):
if x == "\n":
line += 1
return line
diff --git a/docs/zzipdoc/textfileheader.py b/docs/zzipdoc/textfileheader.py
index ceaa28e..63be1e1 100644
--- a/docs/zzipdoc/textfileheader.py
+++ b/docs/zzipdoc/textfileheader.py
@@ -1,4 +1,6 @@
-from match import Match
+from __future__ import absolute_import
+from __future__ import print_function
+from .match import Match
class TextFileHeader:
""" scan for a comment block at the source file start and fill the
@@ -17,7 +19,7 @@ class TextFileHeader:
x = Match()
text = self.textfile.get_src_text()
if not text:
- print "nonexistent file:", self.textfile.get_filename()
+ print("nonexistent file:", self.textfile.get_filename())
return False
if text & x(r"(?s)[/][*]+(\s(?:.(?!\*\/))*.)\*\/"
r"(?:\s*\#(?:define|ifdef|endif)[ ]*\S*[ ]*\S*)*"
--
2.14.4

View File

@ -0,0 +1,71 @@
From 9411bde3e4a70a81ff3ffd256b71927b2d90dcbb Mon Sep 17 00:00:00 2001
From: jmoellers <josef.moellers@suse.com>
Date: Fri, 7 Sep 2018 11:32:04 +0200
Subject: [PATCH] Avoid memory leak from __zzip_parse_root_directory().
---
test/test.zip | Bin 1361 -> 1361 bytes
zzip/zip.c | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/zzip/zip.c b/zzip/zip.c
index 88b833b..a685280 100644
--- a/zzip/zip.c
+++ b/zzip/zip.c
@@ -475,9 +475,15 @@ __zzip_parse_root_directory(int fd,
} else
{
if (io->fd.seeks(fd, zz_rootseek + zz_offset, SEEK_SET) < 0)
+ {
+ free(hdr0);
return ZZIP_DIR_SEEK;
+ }
if (io->fd.read(fd, &dirent, sizeof(dirent)) < __sizeof(dirent))
+ {
+ free(hdr0);
return ZZIP_DIR_READ;
+ }
d = &dirent;
}
@@ -577,12 +583,38 @@ __zzip_parse_root_directory(int fd,
if (hdr_return)
*hdr_return = hdr0;
+ else
+ {
+ /* If it is not assigned to *hdr_return, it will never be free()'d */
+ free(hdr0);
+ /* Make sure we don't free it again in case of error */
+ hdr0 = NULL;
+ }
} /* else zero (sane) entries */
# ifndef ZZIP_ALLOW_MODULO_ENTRIES
- return (entries != zz_entries ? ZZIP_CORRUPTED : 0);
+ if (entries != zz_entries)
+ {
+ /* If it was assigned to *hdr_return, undo assignment */
+ if (p_reclen && hdr_return)
+ *hdr_return = NULL;
+ /* Free it, if it was not already free()'d */
+ if (hdr0 != NULL)
+ free(hdr0);
+ return ZZIP_CORRUPTED;
+ }
# else
- return ((entries & (unsigned)0xFFFF) != zz_entries ? ZZIP_CORRUPTED : 0);
+ if (((entries & (unsigned)0xFFFF) != zz_entries)
+ {
+ /* If it was assigned to *hdr_return, undo assignment */
+ if (p_reclen && hdr_return)
+ *hdr_return = NULL;
+ /* Free it, if it was not already free()'d */
+ if (hdr0 != NULL)
+ free(hdr0);
+ return ZZIP_CORRUPTED;
+ }
# endif
+ return 0;
}
/* ------------------------- high-level interface ------------------------- */

View File

@ -0,0 +1,50 @@
From d2e5d5c53212e54a97ad64b793a4389193fec687 Mon Sep 17 00:00:00 2001
From: jmoellers <josef.moellers@suse.com>
Date: Fri, 7 Sep 2018 11:49:28 +0200
Subject: [PATCH] Avoid memory leak from __zzip_parse_root_directory().
---
zzip/zip.c | 25 ++-----------------------
1 file changed, 2 insertions(+), 23 deletions(-)
diff --git a/zzip/zip.c b/zzip/zip.c
index a685280..51a1a4d 100644
--- a/zzip/zip.c
+++ b/zzip/zip.c
@@ -587,34 +587,13 @@ __zzip_parse_root_directory(int fd,
{
/* If it is not assigned to *hdr_return, it will never be free()'d */
free(hdr0);
- /* Make sure we don't free it again in case of error */
- hdr0 = NULL;
}
} /* else zero (sane) entries */
# ifndef ZZIP_ALLOW_MODULO_ENTRIES
- if (entries != zz_entries)
- {
- /* If it was assigned to *hdr_return, undo assignment */
- if (p_reclen && hdr_return)
- *hdr_return = NULL;
- /* Free it, if it was not already free()'d */
- if (hdr0 != NULL)
- free(hdr0);
- return ZZIP_CORRUPTED;
- }
+ return (entries != zz_entries) ? ZZIP_CORRUPTED : 0;
# else
- if (((entries & (unsigned)0xFFFF) != zz_entries)
- {
- /* If it was assigned to *hdr_return, undo assignment */
- if (p_reclen && hdr_return)
- *hdr_return = NULL;
- /* Free it, if it was not already free()'d */
- if (hdr0 != NULL)
- free(hdr0);
- return ZZIP_CORRUPTED;
- }
+ return ((entries & (unsigned)0xFFFF) != zz_entries) ? ZZIP_CORRUPTED : 0;
# endif
- return 0;
}
/* ------------------------- high-level interface ------------------------- */

View File

@ -0,0 +1,22 @@
From 0e1dadb05c1473b9df2d7b8f298dab801778ef99 Mon Sep 17 00:00:00 2001
From: jmoellers <josef.moellers@suse.com>
Date: Fri, 7 Sep 2018 13:55:35 +0200
Subject: [PATCH] One more free() to avoid memory leak.
---
zzip/zip.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/zzip/zip.c b/zzip/zip.c
index 51a1a4d..bc6c080 100644
--- a/zzip/zip.c
+++ b/zzip/zip.c
@@ -589,6 +589,8 @@ __zzip_parse_root_directory(int fd,
free(hdr0);
}
} /* else zero (sane) entries */
+ else
+ free(hdr0);
# ifndef ZZIP_ALLOW_MODULO_ENTRIES
return (entries != zz_entries) ? ZZIP_CORRUPTED : 0;
# else

View File

@ -0,0 +1,341 @@
From 81dfa6b3e08f6934885ba5c98939587d6850d08e Mon Sep 17 00:00:00 2001
From: Josef Moellers <jmoellers@suse.de>
Date: Thu, 4 Oct 2018 14:21:48 +0200
Subject: [PATCH] Fix issue #62: Remove any "../" components from pathnames of
extracted files. [CVE-2018-17828]
---
bins/unzzipcat-big.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
bins/unzzipcat-mem.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
bins/unzzipcat-mix.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
bins/unzzipcat-zip.c | 57 +++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 224 insertions(+), 4 deletions(-)
diff --git a/bins/unzzipcat-big.c b/bins/unzzipcat-big.c
index 982d262..88c4d65 100644
--- a/bins/unzzipcat-big.c
+++ b/bins/unzzipcat-big.c
@@ -53,6 +53,48 @@ static void unzzip_cat_file(FILE* disk, char* name, FILE* out)
}
}
+/*
+ * NAME: remove_dotdotslash
+ * PURPOSE: To remove any "../" components from the given pathname
+ * ARGUMENTS: path: path name with maybe "../" components
+ * RETURNS: Nothing, "path" is modified in-place
+ * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it!
+ * Also, "path" is not used after creating it.
+ * So modifying "path" in-place is safe to do.
+ */
+static inline void
+remove_dotdotslash(char *path)
+{
+ /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */
+ char *dotdotslash;
+ int warned = 0;
+
+ dotdotslash = path;
+ while ((dotdotslash = strstr(dotdotslash, "../")) != NULL)
+ {
+ /*
+ * Remove only if at the beginning of the pathname ("../path/name")
+ * or when preceded by a slash ("path/../name"),
+ * otherwise not ("path../name..")!
+ */
+ if (dotdotslash == path || dotdotslash[-1] == '/')
+ {
+ char *src, *dst;
+ if (!warned)
+ {
+ /* Note: the first time through the pathname is still intact */
+ fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path);
+ warned = 1;
+ }
+ /* We cannot use strcpy(), as there "The strings may not overlap" */
+ for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++)
+ ;
+ }
+ else
+ dotdotslash +=3; /* skip this instance to prevent infinite loop */
+ }
+}
+
static void makedirs(const char* name)
{
char* p = strrchr(name, '/');
@@ -70,6 +112,16 @@ static void makedirs(const char* name)
static FILE* create_fopen(char* name, char* mode, int subdirs)
{
+ char *name_stripped;
+ FILE *fp;
+ int mustfree = 0;
+
+ if ((name_stripped = strdup(name)) != NULL)
+ {
+ remove_dotdotslash(name_stripped);
+ name = name_stripped;
+ mustfree = 1;
+ }
if (subdirs)
{
char* p = strrchr(name, '/');
@@ -79,7 +131,10 @@ static FILE* create_fopen(char* name, char* mode, int subdirs)
free (dir_name);
}
}
- return fopen(name, mode);
+ fp = fopen(name, mode);
+ if (mustfree)
+ free(name_stripped);
+ return fp;
}
diff --git a/bins/unzzipcat-mem.c b/bins/unzzipcat-mem.c
index 9bc966b..793bde8 100644
--- a/bins/unzzipcat-mem.c
+++ b/bins/unzzipcat-mem.c
@@ -58,6 +58,48 @@ static void unzzip_mem_disk_cat_file(ZZIP_MEM_DISK* disk, char* name, FILE* out)
}
}
+/*
+ * NAME: remove_dotdotslash
+ * PURPOSE: To remove any "../" components from the given pathname
+ * ARGUMENTS: path: path name with maybe "../" components
+ * RETURNS: Nothing, "path" is modified in-place
+ * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it!
+ * Also, "path" is not used after creating it.
+ * So modifying "path" in-place is safe to do.
+ */
+static inline void
+remove_dotdotslash(char *path)
+{
+ /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */
+ char *dotdotslash;
+ int warned = 0;
+
+ dotdotslash = path;
+ while ((dotdotslash = strstr(dotdotslash, "../")) != NULL)
+ {
+ /*
+ * Remove only if at the beginning of the pathname ("../path/name")
+ * or when preceded by a slash ("path/../name"),
+ * otherwise not ("path../name..")!
+ */
+ if (dotdotslash == path || dotdotslash[-1] == '/')
+ {
+ char *src, *dst;
+ if (!warned)
+ {
+ /* Note: the first time through the pathname is still intact */
+ fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path);
+ warned = 1;
+ }
+ /* We cannot use strcpy(), as there "The strings may not overlap" */
+ for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++)
+ ;
+ }
+ else
+ dotdotslash +=3; /* skip this instance to prevent infinite loop */
+ }
+}
+
static void makedirs(const char* name)
{
char* p = strrchr(name, '/');
@@ -75,6 +117,16 @@ static void makedirs(const char* name)
static FILE* create_fopen(char* name, char* mode, int subdirs)
{
+ char *name_stripped;
+ FILE *fp;
+ int mustfree = 0;
+
+ if ((name_stripped = strdup(name)) != NULL)
+ {
+ remove_dotdotslash(name_stripped);
+ name = name_stripped;
+ mustfree = 1;
+ }
if (subdirs)
{
char* p = strrchr(name, '/');
@@ -84,7 +136,10 @@ static FILE* create_fopen(char* name, char* mode, int subdirs)
free (dir_name);
}
}
- return fopen(name, mode);
+ fp = fopen(name, mode);
+ if (mustfree)
+ free(name_stripped);
+ return fp;
}
static int unzzip_cat (int argc, char ** argv, int extract)
diff --git a/bins/unzzipcat-mix.c b/bins/unzzipcat-mix.c
index 91c2f00..73b6ed6 100644
--- a/bins/unzzipcat-mix.c
+++ b/bins/unzzipcat-mix.c
@@ -69,6 +69,48 @@ static void unzzip_cat_file(ZZIP_DIR* disk, char* name, FILE* out)
}
}
+/*
+ * NAME: remove_dotdotslash
+ * PURPOSE: To remove any "../" components from the given pathname
+ * ARGUMENTS: path: path name with maybe "../" components
+ * RETURNS: Nothing, "path" is modified in-place
+ * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it!
+ * Also, "path" is not used after creating it.
+ * So modifying "path" in-place is safe to do.
+ */
+static inline void
+remove_dotdotslash(char *path)
+{
+ /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */
+ char *dotdotslash;
+ int warned = 0;
+
+ dotdotslash = path;
+ while ((dotdotslash = strstr(dotdotslash, "../")) != NULL)
+ {
+ /*
+ * Remove only if at the beginning of the pathname ("../path/name")
+ * or when preceded by a slash ("path/../name"),
+ * otherwise not ("path../name..")!
+ */
+ if (dotdotslash == path || dotdotslash[-1] == '/')
+ {
+ char *src, *dst;
+ if (!warned)
+ {
+ /* Note: the first time through the pathname is still intact */
+ fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path);
+ warned = 1;
+ }
+ /* We cannot use strcpy(), as there "The strings may not overlap" */
+ for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++)
+ ;
+ }
+ else
+ dotdotslash +=3; /* skip this instance to prevent infinite loop */
+ }
+}
+
static void makedirs(const char* name)
{
char* p = strrchr(name, '/');
@@ -86,6 +128,16 @@ static void makedirs(const char* name)
static FILE* create_fopen(char* name, char* mode, int subdirs)
{
+ char *name_stripped;
+ FILE *fp;
+ int mustfree = 0;
+
+ if ((name_stripped = strdup(name)) != NULL)
+ {
+ remove_dotdotslash(name_stripped);
+ name = name_stripped;
+ mustfree = 1;
+ }
if (subdirs)
{
char* p = strrchr(name, '/');
@@ -95,7 +147,10 @@ static FILE* create_fopen(char* name, char* mode, int subdirs)
free (dir_name);
}
}
- return fopen(name, mode);
+ fp = fopen(name, mode);
+ if (mustfree)
+ free(name_stripped);
+ return fp;
}
static int unzzip_cat (int argc, char ** argv, int extract)
diff --git a/bins/unzzipcat-zip.c b/bins/unzzipcat-zip.c
index 2810f85..7f7f3fa 100644
--- a/bins/unzzipcat-zip.c
+++ b/bins/unzzipcat-zip.c
@@ -69,6 +69,48 @@ static void unzzip_cat_file(ZZIP_DIR* disk, char* name, FILE* out)
}
}
+/*
+ * NAME: remove_dotdotslash
+ * PURPOSE: To remove any "../" components from the given pathname
+ * ARGUMENTS: path: path name with maybe "../" components
+ * RETURNS: Nothing, "path" is modified in-place
+ * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it!
+ * Also, "path" is not used after creating it.
+ * So modifying "path" in-place is safe to do.
+ */
+static inline void
+remove_dotdotslash(char *path)
+{
+ /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */
+ char *dotdotslash;
+ int warned = 0;
+
+ dotdotslash = path;
+ while ((dotdotslash = strstr(dotdotslash, "../")) != NULL)
+ {
+ /*
+ * Remove only if at the beginning of the pathname ("../path/name")
+ * or when preceded by a slash ("path/../name"),
+ * otherwise not ("path../name..")!
+ */
+ if (dotdotslash == path || dotdotslash[-1] == '/')
+ {
+ char *src, *dst;
+ if (!warned)
+ {
+ /* Note: the first time through the pathname is still intact */
+ fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path);
+ warned = 1;
+ }
+ /* We cannot use strcpy(), as there "The strings may not overlap" */
+ for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++)
+ ;
+ }
+ else
+ dotdotslash +=3; /* skip this instance to prevent infinite loop */
+ }
+}
+
static void makedirs(const char* name)
{
char* p = strrchr(name, '/');
@@ -86,6 +128,16 @@ static void makedirs(const char* name)
static FILE* create_fopen(char* name, char* mode, int subdirs)
{
+ char *name_stripped;
+ FILE *fp;
+ int mustfree = 0;
+
+ if ((name_stripped = strdup(name)) != NULL)
+ {
+ remove_dotdotslash(name_stripped);
+ name = name_stripped;
+ mustfree = 1;
+ }
if (subdirs)
{
char* p = strrchr(name, '/');
@@ -95,7 +147,10 @@ static FILE* create_fopen(char* name, char* mode, int subdirs)
free (dir_name);
}
}
- return fopen(name, mode);
+ fp = fopen(name, mode);
+ if (mustfree)
+ free(name_stripped);
+ return fp;
}
static int unzzip_cat (int argc, char ** argv, int extract)

View File

@ -0,0 +1,48 @@
From 1ba660b3300d67b8ce9f6b96bbae0b36fa2d6b06 Mon Sep 17 00:00:00 2001
From: Guido Draheim <guidod@gmx.de>
Date: Tue, 13 Mar 2018 01:29:44 +0100
Subject: [PATCH] check zlib space to be within buffer #39
---
zzip/memdisk.c | 9 +++++++++
zzip/mmapped.c | 2 ++
2 files changed, 11 insertions(+)
diff --git a/zzip/memdisk.c b/zzip/memdisk.c
index 3de201c..8d5743d 100644
--- a/zzip/memdisk.c
+++ b/zzip/memdisk.c
@@ -521,11 +521,20 @@ zzip_mem_entry_fopen(ZZIP_MEM_DISK * dir, ZZIP_MEM_ENTRY * entry)
file->zlib.avail_in = zzip_mem_entry_csize(entry);
file->zlib.next_in = zzip_mem_entry_to_data(entry);
+ debug2("compressed size %i", (int) file->zlib.avail_in);
+ if (file->zlib.next_in + file->zlib.avail_in >= file->endbuf)
+ goto error;
+ if (file->zlib.next_in < file->buffer)
+ goto error;
+
if (! zzip_mem_entry_data_deflated(entry) ||
inflateInit2(&file->zlib, -MAX_WBITS) != Z_OK)
{ free (file); return 0; }
return file;
+error:
+ errno = EBADMSG;
+ return NULL;
}
zzip__new__ ZZIP_MEM_DISK_FILE *
diff --git a/zzip/mmapped.c b/zzip/mmapped.c
index 920c4df..8af18f4 100644
--- a/zzip/mmapped.c
+++ b/zzip/mmapped.c
@@ -654,6 +654,8 @@ zzip_disk_entry_fopen(ZZIP_DISK * disk, ZZIP_DISK_ENTRY * entry)
DBG2("compressed size %i", (int) file->zlib.avail_in);
if (file->zlib.next_in + file->zlib.avail_in >= disk->endbuf)
goto error;
+ if (file->zlib.next_in < disk->buffer)
+ goto error;
if (! zzip_file_header_data_deflated(header))
goto error;

View File

@ -0,0 +1,31 @@
From 8f48323c181e20b7e527b8be7229d6eb1148ec5f Mon Sep 17 00:00:00 2001
From: Guido Draheim <guidod@gmx.de>
Date: Tue, 13 Mar 2018 00:23:33 +0100
Subject: [PATCH] check rootseek and rootsize to be positive #27
---
zzip/zip.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/zzip/zip.c b/zzip/zip.c
index a5db9d8..6be8d7c 100644
--- a/zzip/zip.c
+++ b/zzip/zip.c
@@ -318,6 +318,8 @@ __zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
trailer->zz_rootseek = zzip_disk_trailer_rootseek(orig);
trailer->zz_rootsize = zzip_disk_trailer_rootsize(orig);
# endif
+ if (trailer->zz_rootseek < 0 || trailer->zz_rootsize < 0)
+ return(ZZIP_CORRUPTED); // forged value
__fixup_rootseek(offset + tail - mapped, trailer);
/*
@@ -344,6 +346,8 @@ __zzip_fetch_disk_trailer(int fd, zzip_off_t filesize,
zzip_disk64_trailer_finalentries(orig);
trailer->zz_rootseek = zzip_disk64_trailer_rootseek(orig);
trailer->zz_rootsize = zzip_disk64_trailer_rootsize(orig);
+ if (trailer->zz_rootseek < 0 || trailer->zz_rootsize < 0)
+ return(ZZIP_CORRUPTED); // forged value
/*
* "extract data from files archived in a single zip file."
* So the file offsets must be within the current ZIP archive!

View File

@ -0,0 +1,40 @@
From 19c9e4dc6c5cf92a38d0d23dbccac6993f9c41be Mon Sep 17 00:00:00 2001
From: Guido Draheim <guidod@gmx.de>
Date: Tue, 13 Mar 2018 01:50:36 +0100
Subject: [PATCH] check rootseek after correction #41
---
zzip/zip.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/zzip/zip.c b/zzip/zip.c
index 6be8d7c..0d79d52 100644
--- a/zzip/zip.c
+++ b/zzip/zip.c
@@ -1,4 +1,3 @@
-
/*
* Author:
* Guido Draheim <guidod@gmx.de>
@@ -422,6 +421,9 @@ __zzip_parse_root_directory(int fd,
zzip_off64_t zz_rootseek = _disk_trailer_rootseek(trailer);
__correct_rootseek(zz_rootseek, zz_rootsize, trailer);
+ if (zz_entries < 0 || zz_rootseek < 0 || zz_rootseek < 0)
+ return ZZIP_CORRUPTED;
+
hdr0 = (struct zzip_dir_hdr *) malloc(zz_rootsize);
if (! hdr0)
return ZZIP_DIRSIZE;
@@ -465,8 +467,9 @@ __zzip_parse_root_directory(int fd,
# endif
if (fd_map)
- { d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* fd_map+fd_gap==u_rootseek */
- else
+ {
+ d = (void*)(fd_map+zz_fd_gap+zz_offset); /* fd_map+fd_gap==u_rootseek */
+ } else
{
if (io->fd.seeks(fd, zz_rootseek + zz_offset, SEEK_SET) < 0)
return ZZIP_DIR_SEEK;

View File

@ -0,0 +1,22 @@
From feae4da1a5c92100c44ebfcbaaa895959cc0829b Mon Sep 17 00:00:00 2001
From: Guido Draheim <guidod@gmx.de>
Date: Thu, 15 Mar 2018 23:54:37 +0100
Subject: [PATCH] fix for zz_rootsize #41
---
zzip/zip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/zzip/zip.c b/zzip/zip.c
index 0d79d52..14e2e06 100644
--- a/zzip/zip.c
+++ b/zzip/zip.c
@@ -421,7 +421,7 @@ __zzip_parse_root_directory(int fd,
zzip_off64_t zz_rootseek = _disk_trailer_rootseek(trailer);
__correct_rootseek(zz_rootseek, zz_rootsize, trailer);
- if (zz_entries < 0 || zz_rootseek < 0 || zz_rootseek < 0)
+ if (zz_entries < 0 || zz_rootseek < 0 || zz_rootsize < 0)
return ZZIP_CORRUPTED;
hdr0 = (struct zzip_dir_hdr *) malloc(zz_rootsize);

138
SOURCES/CVE-2018-7727.patch Normal file
View File

@ -0,0 +1,138 @@
From 83a2da55922f67e07f22048ac9671a44cc0d35c4 Mon Sep 17 00:00:00 2001
From: Guido Draheim <guidod@gmx.de>
Date: Wed, 14 Mar 2018 07:50:44 +0100
Subject: [PATCH] ensure disk_close to avoid mem-leak #40
---
bins/unzzipcat-mem.c | 57 +++++++++++++++++++++++++++-------------------------
bins/unzzipdir-mem.c | 10 ++++-----
2 files changed, 34 insertions(+), 33 deletions(-)
diff --git a/bins/unzzipcat-mem.c b/bins/unzzipcat-mem.c
index d13029c..9bc966b 100644
--- a/bins/unzzipcat-mem.c
+++ b/bins/unzzipcat-mem.c
@@ -89,7 +89,7 @@ static FILE* create_fopen(char* name, char* mode, int subdirs)
static int unzzip_cat (int argc, char ** argv, int extract)
{
- int done;
+ int done = 0;
int argn;
ZZIP_MEM_DISK* disk;
@@ -116,47 +116,50 @@ static int unzzip_cat (int argc, char ** argv, int extract)
FILE* out = stdout;
if (extract) out = create_fopen(name, "w", 1);
if (! out) {
- if (errno != EISDIR) done = EXIT_ERRORS;
+ if (errno != EISDIR) {
+ DBG3("can not open output file %i %s", errno, strerror(errno));
+ done = EXIT_ERRORS;
+ }
continue;
}
unzzip_mem_disk_cat_file (disk, name, out);
if (extract) fclose(out);
}
- return done;
- }
-
- if (argc == 3 && !extract)
+ }
+ else if (argc == 3 && !extract)
{ /* list from one spec */
ZZIP_MEM_ENTRY* entry = 0;
while ((entry = zzip_mem_disk_findmatch(disk, argv[2], entry, 0, 0)))
{
unzzip_mem_entry_fprint (disk, entry, stdout);
}
-
- return 0;
- }
-
- for (argn=1; argn < argc; argn++)
- { /* list only the matching entries - each in order of commandline */
- ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
- for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
- {
- char* name = zzip_mem_entry_to_name (entry);
- if (! _zzip_fnmatch (argv[argn], name,
- FNM_NOESCAPE|FNM_PATHNAME|FNM_PERIOD))
+ } else {
+ for (argn=1; argn < argc; argn++)
+ { /* list only the matching entries - each in order of commandline */
+ ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
+ for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
{
- FILE* out = stdout;
- if (extract) out = create_fopen(name, "w", 1);
- if (! out) {
- if (errno != EISDIR) done = EXIT_ERRORS;
- continue;
- }
- unzzip_mem_disk_cat_file (disk, name, out);
- if (extract) fclose(out);
- break; /* match loop */
+ char* name = zzip_mem_entry_to_name (entry);
+ if (! _zzip_fnmatch (argv[argn], name,
+ FNM_NOESCAPE|FNM_PATHNAME|FNM_PERIOD))
+ {
+ FILE* out = stdout;
+ if (extract) out = create_fopen(name, "wb", 1);
+ if (! out) {
+ if (errno != EISDIR) {
+ DBG3("can not open output file %i %s", errno, strerror(errno));
+ done = EXIT_ERRORS;
+ }
+ continue;
+ }
+ unzzip_mem_disk_cat_file (disk, name, out);
+ if (extract) fclose(out);
+ break; /* match loop */
+ }
}
}
}
+ zzip_mem_disk_close(disk);
return done;
}
diff --git a/bins/unzzipdir-mem.c b/bins/unzzipdir-mem.c
index e54cd8d..beca788 100644
--- a/bins/unzzipdir-mem.c
+++ b/bins/unzzipdir-mem.c
@@ -68,10 +68,8 @@ unzzip_list (int argc, char ** argv, int verbose)
printf ("%lli/%lli %s %s\n", csize, usize, defl, name);
}
}
- return 0;
}
-
- if (argc == 3)
+ else if (argc == 3)
{ /* list from one spec */
ZZIP_MEM_ENTRY* entry = 0;
while ((entry = zzip_mem_disk_findmatch(disk, argv[2], entry, 0, 0)))
@@ -89,9 +87,8 @@ unzzip_list (int argc, char ** argv, int verbose)
printf ("%lli/%lli %s %s\n", csize, usize, defl, name);
}
}
- return 0;
}
-
+ else
{ /* list only the matching entries - in order of zip directory */
ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
@@ -118,8 +115,9 @@ unzzip_list (int argc, char ** argv, int verbose)
}
}
}
- return 0;
}
+ zzip_mem_disk_close(disk);
+ return EXIT_OK;
}
int

View File

@ -0,0 +1,39 @@
--- ./a/zzip/_config.h 2018-10-11 12:28:07.994739469 +0200
+++ ./b/zzip/_config.h 2018-10-11 10:30:48.000000000 +0200
@@ -133,9 +133,11 @@
/* whether the system defaults to 32bit off_t but can do 64bit when requested
*/
+#if __WORDSIZE == 32
#ifndef ZZIP_LARGEFILE_SENSITIVE
#define ZZIP_LARGEFILE_SENSITIVE 1
#endif
+#endif
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
@@ -185,7 +187,11 @@
/* The number of bytes in type long */
#ifndef ZZIP_SIZEOF_LONG
-#define ZZIP_SIZEOF_LONG 4
+#if __WORDSIZE == 32
+#define ZZIP_SIZEOF_LONG 4
+#elif __WORDSIZE == 64
+#define ZZIP_SIZEOF_LONG 8
+#endif
#endif
/* The number of bytes in type short */
@@ -221,9 +227,11 @@
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
+#if __WORDSIZE == 32
#ifndef ZZIP__FILE_OFFSET_BITS
#define ZZIP__FILE_OFFSET_BITS 64
#endif
+#endif
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

View File

@ -0,0 +1,42 @@
diff -up ./x86_64-redhat-linux-gnu/zzip/_config.h.orig ./x86_64-redhat-linux-gnu/zzip/_config.h
--- ./x86_64-redhat-linux-gnu/zzip/_config.h.orig 2018-02-01 22:13:36.593910695 +0200
+++ ./x86_64-redhat-linux-gnu/zzip/_config.h 2018-02-01 22:15:40.341476130 +0200
@@ -133,7 +133,11 @@
/* whether the system defaults to 32bit off_t but can do 64bit when requested
*/
-/* #undef LARGEFILE_SENSITIVE */
+#if __WORDSIZE == 32
+#ifndef ZZIP_LARGEFILE_SENSITIVE
+#define ZZIP_LARGEFILE_SENSITIVE 1
+#endif
+#endif
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
@@ -183,8 +187,12 @@
/* The number of bytes in type long */
#ifndef ZZIP_SIZEOF_LONG
+#if __WORDSIZE == 32
+#define ZZIP_SIZEOF_LONG 4
+#elif __WORDSIZE == 64
#define ZZIP_SIZEOF_LONG 8
#endif
+#endif
/* The number of bytes in type short */
#ifndef ZZIP_SIZEOF_SHORT
@@ -219,7 +227,11 @@
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
+#if __WORDSIZE == 32
+#ifndef ZZIP__FILE_OFFSET_BITS
+#define ZZIP__FILE_OFFSET_BITS 64
+#endif
+#endif
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

286
SPECS/zziplib.spec Normal file
View File

@ -0,0 +1,286 @@
Summary: Lightweight library to easily extract data from zip files
Name: zziplib
Version: 0.13.68
Release: 7%{?dist}
License: LGPLv2+ or MPLv1.1
Group: Applications/Archiving
URL: http://zziplib.sourceforge.net/
Source: https://github.com/gdraheim/zziplib/archive/v%{version}.tar.gz
Patch100: zziplib-0.13.67-multilib.patch
Patch101: zziplib-0.13.67-multilib-32.patch
Patch1: 0001-FIX-port-documentation-scripts-to-python3.patch
Patch2: CVE-2018-7725.patch
#part1 also fixes #1545818
Patch3: CVE-2018-7726.part1.patch
Patch4: CVE-2018-7726.part2.patch
Patch5: CVE-2018-7726.part3.patch
Patch6: CVE-2018-7727.patch
Patch7: CVE-2018-16548.part1.patch
Patch8: CVE-2018-16548.part2.patch
Patch9: CVE-2018-16548.part3.patch
Patch10: CVE-2018-17828.patch
BuildRequires: perl-interpreter
BuildRequires: python3-devel
BuildRequires: python3-six
BuildRequires: zip
BuildRequires: xmlto
BuildRequires: zlib-devel
BuildRequires: SDL-devel
BuildRequires: pkgconfig
#BuildRequires: autoconf
#BuildRequires: automake
%description
The zziplib library is intentionally lightweight, it offers the ability to
easily extract data from files archived in a single zip file. Applications
can bundle files into a single zip archive and access them. The implementation
is based only on the (free) subset of compression with the zlib algorithm
which is actually used by the zip/unzip tools.
%package utils
Summary: Utilities for the zziplib library
Group: Applications/Archiving
Requires: %{name}%{?_isa} = %{version}-%{release}
%description utils
The zziplib library is intentionally lightweight, it offers the ability to
easily extract data from files archived in a single zip file. Applications
can bundle files into a single zip archive and access them. The implementation
is based only on the (free) subset of compression with the zlib algorithm
which is actually used by the zip/unzip tools.
This packages contains all the utilities that come with the zziplib library.
%package devel
Summary: Development files for the zziplib library
Group: Development/Libraries
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig
Requires: zlib-devel
Requires: SDL-devel
%description devel
The zziplib library is intentionally lightweight, it offers the ability to
easily extract data from files archived in a single zip file. Applications
can bundle files into a single zip archive and access them. The implementation
is based only on the (free) subset of compression with the zlib algorithm
which is actually used by the zip/unzip tools.
This package contains files required to build applications that will use the
zziplib library.
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
pathfix.py -i %{__python3} -pn docs
%build
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
%configure \
--disable-static \
--enable-sdl \
--enable-frame-pointer \
--enable-builddir=_builddir
# Remove rpath on 64bit archs
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' */libtool
sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' */libtool
# Only patch generated _config.h on non-i686 and armv7hl
# These platforms have a correct _config.h already
cd _builddir
%ifarch i686 armv7hl
%apply_patch %{PATCH101} -p2
%endif
%ifnarch i686 armv7hl
%apply_patch %{PATCH100} -p2
%endif
cd ..
%{__make} %{?_smp_mflags}
%install
make install DESTDIR=%{buildroot}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%doc docs/COPYING* ChangeLog README TODO
%{_libdir}/*.so.*
%files utils
%{_bindir}/*
%files devel
%doc docs/README.SDL docs/*.htm docs/*.html
%{_includedir}/*
%exclude %{_libdir}/*.la
%{_libdir}/*.so
%{_libdir}/pkgconfig/*.pc
%{_datadir}/aclocal/*.m4
%{_mandir}/man3/*
%changelog
* Tue Oct 16 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-7
- Fix CVE-2018-17828
- Resolves: #1635890
* Thu Oct 11 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-6
- Fix multilib regression by adding a 32bit version of the multilib patch
- Properly bump the release number in the previous changelog message
- Resolves: #1638337
* Thu Oct 04 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-5
- Fix memory leak caused by the CVE-2018-16548
- Resolves: #1626202
* Mon Aug 13 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-4
- Change the build dependency to python-devel and use the pathfix.py script
- Related: 1592262
* Sat Jul 28 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-3
- Fix CVEs 2018-7725, 2018-7726, 2018-7727, 2018-6484, 2018-6869
- Resolves: 1555082
- Resolves: 1545818
* Tue Jul 03 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-2
- Port documentation generating scripts to Python 3
- Include both docs/*.htm and docs/*html files
* Wed Feb 14 2018 Alexander Bokovoy <abokovoy@redhat.com> - 0.13.68-1
- 0.13.68
- Fixes: #1543942 (CVE-2018-6484)
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.67-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Thu Feb 01 2018 Alexander Bokovoy <abokovoy@redhat.com> - 0.13.67-1
- Update release
- CVE-2018-6381
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.62-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Thu Jul 27 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.62-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.62-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Fri Feb 05 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.62-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Fri Jun 19 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.62-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Mon Aug 18 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.62-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.62-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Sun Aug 04 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.62-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
* Wed Jan 30 2013 Jindrich Novy <jnovy@redhat.com> 0.13.62-2
- rebuild with -fno-strict-aliasing
* Wed Oct 10 2012 Matthias Saou <matthias@saou.eu> 0.13.62-1
- Update to 0.13.62.
- Remove no longer needed -Wl patch.
* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.60-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
* Thu Mar 8 2012 Tom Callaway <spot@fedoraproject.org> - 0.13.60-1
- update to 0.13.60
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.59-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.59-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
* Thu Dec 9 2010 Hans de Goede <hdegoede@redhat.com> 0.13.59-2
- Fix broken zzip/_config.h which causes apps using zziplib to fail to compile
* Sat Dec 4 2010 Matthias Saou <http://freshrpms.net/> 0.13.59-1
- Update to 0.13.59.
- Remove no longer needed 'open' patch.
- Rebase the multilib patch, still required.
- Re-enable _smp_mflags, build works again with it apparently.
* Mon Jul 27 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.49-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.49-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Mon Dec 22 2008 Matthias Saou <http://freshrpms.net/> 0.13.49-6
- Patch _config.h to make it identical for 32bit and 64bit archs (#343521).
* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org>
- Autorebuild for GCC 4.3
* Wed Aug 8 2007 Matthias Saou <http://freshrpms.net/> 0.13.49-4
- Include patch to fix fd.open calls with recent glibc.
- Disable _smp_mflags since the docs fail to build.
* Fri Aug 3 2007 Matthias Saou <http://freshrpms.net/> 0.13.49-3
- Update License field.
* Tue Jun 19 2007 Matthias Saou <http://freshrpms.net/> 0.13.49-2
- Disable static lib build instead of excluding it later.
- Remove rpath on 64bit archs.
- Switch to using DESTDIR install method.
* Mon Mar 26 2007 Matthias Saou <http://freshrpms.net/> 0.13.49-1
- Update to 0.13.49 to fix CVE-2007-1614 (rhbz #233700).
- Include new man3 pages to the devel sub-package.
* Mon Aug 28 2006 Matthias Saou <http://freshrpms.net/> 0.13.47-1
- Update to 0.13.47.
- FC6 rebuild.
* Mon Jul 24 2006 Matthias Saou <http://freshrpms.net/> 0.13.45-3
- Split off -utils sub-package (#199467). Could have been plain "zzip"?
- Have sub-packages require exact release too.
- Build require automake to make the aclocal-1.9 check happy.
- Use --enable-frame-pointer otherwise -g gets removed from the CFLAGS.
* Mon Mar 6 2006 Matthias Saou <http://freshrpms.net/> 0.13.45-2
- FC5 rebuild.
* Thu Feb 9 2006 Matthias Saou <http://freshrpms.net/> 0.13.45-1
- Update to 0.13.45.
- Exclude static library.
* Sun May 22 2005 Jeremy Katz <katzj@redhat.com> - 0.13.38-2
- rebuild on all arches
* Tue Apr 5 2005 Matthias Saou <http://freshrpms.net/> 0.13.38-1
- Update to 0.13.38, fixes gcc4 compile issues (Adrian Reber).
* Tue Nov 16 2004 Matthias Saou <http://freshrpms.net/> 0.13.36-2
- Bump release to provide Extras upgrade path.
* Tue Jun 8 2004 Matthias Saou <http://freshrpms.net/> 0.13.36-1
- Initial RPM release.