Compare commits

...

No commits in common. 'c9' and 'c8-beta' have entirely different histories.
c9 ... c8-beta

2
.gitignore vendored

@ -1 +1 @@
SOURCES/v0.13.71-pruned.tar.gz SOURCES/v0.13.68.tar.gz

@ -1 +1 @@
8f4b65912e109f1841387a67b47a4626aca129bb SOURCES/v0.13.71-pruned.tar.gz bf62bf6138a7a5bddbad41d6c5dbb169e1528110 SOURCES/v0.13.68.tar.gz

@ -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

@ -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 ------------------------- */

@ -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 ------------------------- */

@ -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

@ -0,0 +1,59 @@
diff --git a/bins/unzip-mem.c b/bins/unzip-mem.c
index c45cb72..ff564a5 100644
--- a/bins/unzip-mem.c
+++ b/bins/unzip-mem.c
@@ -88,10 +88,53 @@ static void zzip_mem_entry_pipe(ZZIP_MEM_DISK* disk,
}
}
+
+
+
+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 zzip_mem_entry_make(ZZIP_MEM_DISK* disk,
ZZIP_MEM_ENTRY* entry)
{
- FILE* file = fopen (entry->zz_name, "w");
+ char name_stripped[PATH_MAX+1];
+ FILE* file;
+
+ strncpy(name_stripped, entry->zz_name, PATH_MAX);
+ name_stripped[PATH_MAX]='\0';
+ remove_dotdotslash(name_stripped);
+
+ file = fopen (name_stripped, "wb");
if (file) { zzip_mem_entry_pipe (disk, entry, file); fclose (file); }
perror (entry->zz_name);
if (status < EXIT_WARNINGS) status = EXIT_WARNINGS;

@ -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)

@ -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;

@ -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!

@ -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;

@ -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);

@ -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

@ -1,23 +1,30 @@
From 803f49aaae16b7f2899e4769afdfc673a21fa9e8 Mon Sep 17 00:00:00 2001 From 18c6c043bd7d8f139f30e9c7749013115d5fc5b7 Mon Sep 17 00:00:00 2001
From: Guido Draheim <guidod@gmx.de> From: Valentin Lefebvre <valentin.lefebvre@suse.com>
Date: Mon, 26 Feb 2024 23:17:12 +0100 Date: Wed, 20 Sep 2023 12:04:56 +0200
Subject: [PATCH] #69 assert full zzip_file_header Subject: [PATCH] mmappend.c: Avoid invalid access for header entry
* zzip_disk_entry_to_file_header checking the pointer by substraction
instead of addition where it could lead to an invalid access memory.
* CVE-2020-18770
Signed-off-by: Valentin Lefebvre <valentin.lefebvre@suse.com>
--- ---
zzip/mmapped.c | 3 ++- zzip/mmapped.c | 5 +++--
1 file changed, 2 insertions(+), 1 deletion(-) 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/zzip/mmapped.c b/zzip/mmapped.c diff --git a/zzip/mmapped.c b/zzip/mmapped.c
index 2071882..306ba51 100644 index 2071882..beb094d 100644
--- a/zzip/mmapped.c --- a/zzip/mmapped.c
+++ b/zzip/mmapped.c +++ b/zzip/mmapped.c
@@ -276,7 +276,8 @@ struct zzip_file_header * @@ -275,8 +275,9 @@ zzip_disk_entry_to_data(ZZIP_DISK * disk, struct zzip_disk_entry * entry)
struct zzip_file_header *
zzip_disk_entry_to_file_header(ZZIP_DISK * disk, struct zzip_disk_entry *entry) zzip_disk_entry_to_file_header(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
{ {
zzip_byte_t *const ptr = disk->buffer + zzip_disk_entry_fileoffset(entry); - zzip_byte_t *const ptr = disk->buffer + zzip_disk_entry_fileoffset(entry);
- if (disk->buffer > ptr || ptr >= disk->endbuf) - if (disk->buffer > ptr || ptr >= disk->endbuf)
+ zzip_byte_t *const end = ptr + sizeof(struct zzip_file_header); + zzip_off_t off = zzip_disk_entry_fileoffset(entry);
+ if (disk->buffer > ptr || end >= disk->endbuf || end <= NULL) + zzip_byte_t *const ptr = disk->buffer + off;
+ if (disk->buffer > ptr || disk->buffer >= disk->endbuf - off)
{ {
errno = EBADMSG; errno = EBADMSG;
return 0; return 0;

@ -1,108 +0,0 @@
#! /usr/bin/env python3
from __future__ import print_function
import re
try:
basestring
except NameError:
basestring = str
# ---------------------------------------------------------- Regex Match()
# beware, stupid python interprets backslashes in replace-parts only partially!
class MatchReplace:
""" A MatchReplace is a mix of a Python Pattern and a Replace-Template """
def __init__(self, matching, template, count = 0, flags = None):
""" setup a substition from regex 'matching' into 'template',
the replacement count default of 0 will replace all occurrences.
The first argument may be a Match object or it is a string that
will be turned into one by using Match(matching, flags). """
self.template = template
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?
flags = count; count = 0
if isinstance(matching, Match):
self.matching = matching
else:
self.matching = Match()(matching, flags) ## python 2.4.2 bug
if template is not None:
self.template = template
self.count = count
def __and__(self, string):
""" z = MatchReplace('foo', 'bar') & 'foo'; assert z = 'bar' """
text, self.matching.replaced = \
self.matching.regex.subn(self.template, string, self.count)
return text
def __rand__(self, string):
""" z = 'foo' & Match('foo') >> 'bar'; assert z = 'bar' """
text, self.matching.replaced = \
self.matching.regex.subn(self.template, string, self.count)
return text
def __iand__(self, string):
""" x = 'foo' ; x &= Match('foo') >> 'bar'; assert x == 'bar' """
string, self.matching.replaced = \
self.matching.regex.subn(self.template, string, self.count)
return string
def __rshift__(self, count):
" shorthand to set the replacement count: Match('foo') >> 'bar' >> 1 "
self.count = count ; return self
def __rlshift__(self, count):
self.count = count ; return self
class Match:
""" A Match is actually a mix of a Python Pattern and MatchObject """
def __init__(self, pattern = None, flags = None):
""" flags is a string: 'i' for case-insensitive etc.; it is just
short for a regex prefix: Match('foo','i') == Match('(?i)foo') """
Match.__call__(self, pattern, flags)
def __call__(self, pattern, flags = None):
assert isinstance(pattern, str) or pattern is None
assert isinstance(flags, str) or flags is None
self.replaced = 0 # set by subn() inside MatchReplace
self.found = None # set by search() to a MatchObject
self.pattern = pattern
if pattern is not None:
if flags:
self.regex = re.compile("(?"+flags+")"+self.pattern)
else:
self.regex = re.compile(self.pattern)
return self
def __repr__(self):
return self.pattern
def __truth__(self):
return self.found is not None
def __and__(self, string):
self.found = self.regex.search(string)
return self.__truth__()
def __rand__(self, string):
self.found = self.regex.search(string)
return self.__truth__()
def __rshift__(self, template):
return MatchReplace(self, template)
def __rlshift__(self, template):
return MatchReplace(self, template)
def __getitem__(self, index):
return self.group(index)
def group(self, index):
assert self.found is not None
return self.found.group(index)
def finditer(self, string):
return self.regex.finditer(string)
if __name__ == "__main__":
# matching:
if "foo" & Match("oo"):
print("oo")
x = Match()
if "foo" & x("(o+)"):
print(x[1])
# replacing:
y = "fooboo" & Match("oo") >> "ee"
print(y)
r = Match("oo") >> "ee"
print("fooboo" & r)
s = MatchReplace("oo", "ee")
print("fooboo" & s)

@ -1,29 +0,0 @@
--- ./a/zzip/_config.h 2021-07-21 14:18:09.000000000 +0200
+++ ./b/zzip/_config.h 2021-07-21 14:46:24.037432969 +0200
@@ -138,9 +138,12 @@
/* 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
+/* #undef LARGEFILE_SENSITIVE */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#ifndef ZZIP_LT_OBJDIR
@@ -227,9 +230,13 @@
#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
+/* #undef _FILE_OFFSET_BITS */
+
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

@ -1,29 +0,0 @@
--- ./a/zzip/_config.h 2021-07-21 14:18:14.000000000 +0200
+++ ./b/zzip/_config.h 2021-07-21 14:46:24.037432969 +0200
@@ -138,6 +138,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
/* #undef LARGEFILE_SENSITIVE */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
@@ -225,8 +230,14 @@
#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
/* #undef _FILE_OFFSET_BITS */
+
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

@ -1,28 +0,0 @@
#! /usr/bin/env python3
from zzipdoc.match import Match
# use as o.optionname to check for commandline options.
class Options:
var = {}
def __getattr__(self, name):
if not name in self.var: return None
return self.var[name]
def __setattr__(self, name, value):
self.var[name] = value
def scan(self, optionstring): # option-name or None
x = Match()
if optionstring & x(r"^--?(\w+)=(.*)"):
self.var[x[1]] = x[2] ; return x[1]
if optionstring & x(r"^--?no-(\w+)$"):
self.var[x[1]] = "" ; return x[1]
if optionstring & x(r"^--?(\w+)$"):
self.var[x[1]] = "*"; return x[1]
return None
#end Options
if False:
o = Options()
o.help = """
scans for options
"""

@ -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 */

@ -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 */

@ -1,29 +1,36 @@
Summary: Lightweight library to easily extract data from zip files Summary: Lightweight library to easily extract data from zip files
Name: zziplib Name: zziplib
Version: 0.13.71 Version: 0.13.68
Release: 11%{?dist} Release: 12%{?dist}
License: LGPLv2+ or MPLv1.1 License: LGPLv2+ or MPLv1.1
Group: Applications/Archiving
URL: http://zziplib.sourceforge.net/ URL: http://zziplib.sourceforge.net/
#Source: https://github.com/gdraheim/zziplib/archive/v%{version}.tar.gz Source: https://github.com/gdraheim/zziplib/archive/v%{version}.tar.gz
#Using the pruned version of the upstream archive. The archive does not contain the Source1 and Source2 files. Their github version is used instead (the original ones had licensing issues) Patch100: zziplib-0.13.67-multilib.patch
#rhbz#1982241 Patch101: zziplib-0.13.67-multilib-32.patch
Source0: v%{version}-pruned.tar.gz
#https://raw.githubusercontent.com/gdraheim/zziplib/465450c86c930026664329876e5350d21a7527db/docs/zzipdoc/match.py Patch1: 0001-FIX-port-documentation-scripts-to-python3.patch
Source1: match.py Patch2: CVE-2018-7725.patch
#https://raw.githubusercontent.com/gdraheim/zziplib/465450c86c930026664329876e5350d21a7527db/docs/zzipdoc/options.py #part1 also fixes #1545818
Source2: options.py Patch3: CVE-2018-7726.part1.patch
Patch4: CVE-2018-7726.part2.patch
Patch1: CVE-2020-18442.patch Patch5: CVE-2018-7726.part3.patch
Patch2: CVE-2020-18770.patch Patch6: CVE-2018-7727.patch
Patch100: multilib-32.patch
Patch101: multilib-64.patch Patch7: CVE-2018-16548.part1.patch
Patch8: CVE-2018-16548.part2.patch
BuildRequires: make Patch9: CVE-2018-16548.part3.patch
BuildRequires: gcc
Patch10: CVE-2018-17828.patch
Patch11: CVE-2018-17828-singlez.patch
Patch12: CVE-2020-18442.patch
Patch13: CVE-2020-18770.patch
BuildRequires: perl-interpreter BuildRequires: perl-interpreter
BuildRequires: python3 BuildRequires: python3-devel
BuildRequires: python3-rpm-macros BuildRequires: python3-six
BuildRequires: zip BuildRequires: zip
BuildRequires: xmlto BuildRequires: xmlto
BuildRequires: zlib-devel BuildRequires: zlib-devel
@ -41,6 +48,7 @@ which is actually used by the zip/unzip tools.
%package utils %package utils
Summary: Utilities for the zziplib library Summary: Utilities for the zziplib library
Group: Applications/Archiving
Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}%{?_isa} = %{version}-%{release}
%description utils %description utils
@ -54,6 +62,7 @@ This packages contains all the utilities that come with the zziplib library.
%package devel %package devel
Summary: Development files for the zziplib library Summary: Development files for the zziplib library
Group: Development/Libraries
Requires: %{name}%{?_isa} = %{version}-%{release} Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig Requires: pkgconfig
Requires: zlib-devel Requires: zlib-devel
@ -71,41 +80,55 @@ zziplib library.
%prep %prep
%setup -q %setup -q
cp %{SOURCE1} docs/zzipdoc/
cp %{SOURCE2} docs/zzipdoc/
%patch1 -p1 %patch1 -p1
%patch2 -p1 %patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
pathfix.py -i %{__python3} -pn docs
%build %build
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
%configure \ %configure \
--disable-static \ --disable-static \
--enable-sdl \ --enable-sdl \
--enable-frame-pointer --enable-frame-pointer \
--enable-builddir=_builddir \
ac_cv_path_PYTHON=%__python3
# Remove rpath on 64bit archs # Remove rpath on 64bit archs
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool 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 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 # Only patch generated _config.h on non-i686 and armv7hl
# These platforms have a correct _config.h already # These platforms have a correct _config.h already
cd _builddir
pushd %{_builddir}/zziplib-%{version}
%ifarch i686 armv7hl %ifarch i686 armv7hl
patch -p2 < %{PATCH100} %apply_patch %{PATCH101} -p2
%endif %endif
%ifnarch i686 armv7hl %ifnarch i686 armv7hl
patch -p2 < %{PATCH101} %apply_patch %{PATCH100} -p2
%endif %endif
popd cd ..
%make_build %{__make} %{?_smp_mflags}
%install %install
%make_install make install DESTDIR=%{buildroot}
%ldconfig_scriptlets %post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files %files
%doc docs/COPYING* ChangeLog README TODO %doc docs/COPYING* ChangeLog README TODO
@ -115,7 +138,7 @@ popd
%{_bindir}/* %{_bindir}/*
%files devel %files devel
%doc docs/README.SDL docs/*.htm %doc docs/README.SDL docs/*.htm docs/*.html
%{_includedir}/* %{_includedir}/*
%exclude %{_libdir}/*.la %exclude %{_libdir}/*.la
%{_libdir}/*.so %{_libdir}/*.so
@ -124,94 +147,51 @@ popd
%{_mandir}/man3/* %{_mandir}/man3/*
%changelog %changelog
* Wed Feb 28 2024 Jakub Martisko <jamartis@redhat.com> - 0.13.71-11 * Tue Feb 06 2024 Jakub Martisko <jamartis@redhat.com> - 0.13.68-12
- Fix CVE-2020-18770 - Add the gating tests from the 8.8.0 branch
Previous patch was causing segfault Resolves: RHEL-24429
Resolves: RHEL-14967
* Wed Jan 24 2024 Jakub Martisko <jamartis@redhat.com> - 0.13.71-10 * Sat Jan 27 2024 Jakub Martisko <jamartis@redhat.com> - 0.13.68-11
- Fix CVE-2020-18770 - Use %__python3 macro during the config phase (used for doc generation)
Resolves: RHEL-14967 Resolves: RHEL-22880
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 0.13.71-9 * Wed Jan 24 2024 Jakub Martisko <jamartis@redhat.com> - 0.13.68-10
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags - Fix CVE-2020-18770
Related: rhbz#1991688 Resolves: RHEL-14966
* Tue Jul 27 2021 Jakub Martisko <jamartis@redhat.com> - 0.13.71-8
- Add gating tests
Resolves: rhbz#1986332
* Fri Jul 23 2021 Jakub Martisko <jamartis@redhat.com> - 0.13.71-7
- Remove the doc/zzipdoc/{options,match}.py scritps from the original tar
- Replace them with a current github version
- The original version of the files contains autogenerated header with incompatible license
- This build thus uses modified tar archive
Resolves: rhbz#1982241
* Thu Jul 22 2021 Jakub Martisko <jamartis@redhat.com> - 0.13.71-6 * Mon Aug 02 2021 Jakub Martisko <jamartis@redhat.com> - 0.13.68-9
- Fix CVE-2020-18442 - Fix CVE-2020-18442
Resolves: CVE-2020-18442 - Resolves: CVE-2020-18442
Resolves: 1977964
* Thu Jul 22 2021 Jakub Martisko <jamartis@redhat.com> - 0.13.71-5
- Refresh the multilib patch
Resolves: rhbz#1915747
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 0.13.71-4
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Mon Feb 01 2021 Jakub Martisko <jamartis@redhat.com> - 0.13.71-3
- Use python3 (versioned) as buildrequires
* Thu Jan 28 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.71-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Thu Jan 21 2021 Jakub Martisko <jamartis@redhat.com> - 0.13.71-1
- Rebase to 0.13.71
- Drop the CVE patches, they are now part of the upstream package
- Build no longer requires python2
- Resolves: 1807565
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.69-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jul 14 2020 Tom Stellard <tstellar@redhat.com> - 0.13.69-8
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.69-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.69-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.69-5 * Tue Oct 16 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - Fix CVE-2018-17828 in the "single z" binaries
- Resolves: #1772447
* Thu Jan 24 2019 Jakub Martisko <jamartis@redhat.com> - 0.13.69-4 * Tue Oct 16 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-7
- Add the missing CVE-2018-17828.part2.patch file - Fix CVE-2018-17828
- Fix Formating of the previous 2 changelog entries - Resolves: #1635890
* Thu Jan 24 2019 Jakub Martisko <jamartis@redhat.com> - 0.13.69-3 * Thu Oct 11 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-6
- Related: #1626202 - Fix multilib regression by adding a 32bit version of the multilib patch
- Resolves: CVE-2018-16548 - Properly bump the release number in the previous changelog message
- Resolves: #1638337
* Thu Jan 24 2019 Jakub Martisko <jamartis@redhat.com> - 0.13.69-2 * Thu Oct 04 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-5
- Related: 1635890 - Fix memory leak caused by the CVE-2018-16548
- Resolves: CVE-2018-17828 - Resolves: #1626202
* Mon Jul 23 2018 Alexander Bokovoy <abokovoy@redhat.com> - 0.13.69-1 * Mon Aug 13 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-4
- Update to 0.13.69 release - Change the build dependency to python-devel and use the pathfix.py script
- Fixes: #1598246 (CVE-2018-6541) - Related: 1592262
- Fixes: #1554673 (CVE-2018-7727)
- Use versioned python executables everywhere
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.13.68-3 * Sat Jul 28 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - Fix CVEs 2018-7725, 2018-7726, 2018-7727, 2018-6484, 2018-6869
- Resolves: 1555082
- Resolves: 1545818
* Sun Mar 18 2018 Iryna Shcherbina <ishcherb@redhat.com> - 0.13.68-2 * Tue Jul 03 2018 Jakub Martisko <jamartis@redhat.com> - 0.13.68-2
- Update Python 2 dependency declarations to new packaging standards - Port documentation generating scripts to Python 3
(See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3) - Include both docs/*.htm and docs/*html files
* Wed Feb 14 2018 Alexander Bokovoy <abokovoy@redhat.com> - 0.13.68-1 * Wed Feb 14 2018 Alexander Bokovoy <abokovoy@redhat.com> - 0.13.68-1
- 0.13.68 - 0.13.68

Loading…
Cancel
Save