Compare commits

..

32 commits

Author SHA1 Message Date
Fedora Release Engineering
6375da78ff Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-25 21:18:51 +00:00
Fedora Release Engineering
8acab478a5 Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-19 16:47:24 +00:00
Jakub Martisko
965d5021a9 Manpages: --no-extra option is actually called --strip-extra 2024-12-11 11:58:26 +01:00
Fedora Release Engineering
fabe9e5d1d Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild 2024-07-20 10:53:10 +00:00
Software Management Team
22bf29651c Eliminate use of obsolete %patchN syntax (#2283636) 2024-05-30 12:46:50 +02:00
Fedora Release Engineering
5843ce319d Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-27 11:08:19 +00:00
Jakub Martisko
a2433a4859 Fix: buffer overflow with unicode file names
Resolves: rhbz#2165653
2023-09-18 13:04:00 +02:00
Fedora Release Engineering
2105f00991 Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-07-22 19:42:58 +00:00
Lukáš Zaoral
f0aa624a47
migrate to SPDX license format 2023-04-13 14:47:41 +02:00
Fedora Release Engineering
a52777446f Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-01-21 08:16:41 +00:00
Florian Weimer
98b40e35ca Really build with -std=gnu89 (#2143565) 2022-11-18 08:06:30 +01:00
Florian Weimer
9006220708 Build with -std=gnu89 (#2143565) 2022-11-17 09:54:36 +01:00
Fedora Release Engineering
359c42d3bf Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-07-23 13:56:04 +00:00
Fedora Release Engineering
aa70fe9dea - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-01-22 05:52:18 +00:00
Fedora Release Engineering
58c0889b70 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-07-23 22:18:40 +00:00
Jakub Martisko
0a4a3aefb6 Use the generic build target instead of generic_gcc 2021-03-05 13:48:55 +01:00
Jakub Martisko
eaea924793 Use build macros 2021-03-05 13:27:50 +01:00
Fedora Release Engineering
26ddc6ced9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2021-01-28 00:42:40 +00:00
Tom Stellard
dea2f3587c Add BuildRequires: make
https://fedoraproject.org/wiki/Changes/Remove_make_from_BuildRoot
2021-01-09 01:53:28 +00:00
Fedora Release Engineering
18b8781d25 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-07-29 15:23:50 +00:00
Fedora Release Engineering
537855f109 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2020-01-31 05:19:59 +00:00
Fedora Release Engineering
ef2e772ce7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2019-07-27 05:01:16 +00:00
Fedora Release Engineering
3aa1b995be - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2019-02-03 13:11:44 +00:00
Igor Gnatenko
1cac73c467 Remove obsolete Group tag
References: https://fedoraproject.org/wiki/Changes/Remove_Group_Tag
2019-01-28 20:24:57 +01:00
Fedora Release Engineering
39819218ac - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2018-07-14 09:50:49 +00:00
Jakub Martiško
db52ce845b Merge #2 Add CI tests using the standard test interface 2018-03-14 11:08:43 +00:00
Jakub Martisko
6d2c780558 zip.spec: add gcc to buildrequires 2018-03-01 11:12:40 +01:00
Fedora Release Engineering
97885930b2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2018-02-09 22:28:39 +00:00
esakaiev@redhat.com
5bfd267546 Fixes for zip tests 2018-02-09 18:05:33 +02:00
esakaiev
aa3f4dccc7 Porting tests for zip package to dist-git 2018-02-08 18:12:48 +02:00
Fedora Release Engineering
ed96214499 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild 2017-08-03 11:11:40 +00:00
Fedora Release Engineering
328bd15235 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild 2017-07-27 22:43:33 +00:00
13 changed files with 1150 additions and 13 deletions

12
buffer_overflow.patch Normal file
View file

@ -0,0 +1,12 @@
diff -urp zip30/fileio.c zip30/fileio.c
--- zip30/fileio.c 2008-05-29 03:13:24.000000000 +0300
+++ zip30/fileio.c 2023-05-02 12:19:50.488314853 +0300
@@ -3502,7 +3502,7 @@ zwchar *local_to_wide_string(local_strin
if ((wc_string = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t))) == NULL) {
ZIPERR(ZE_MEM, "local_to_wide_string");
}
- wsize = mbstowcs(wc_string, local_string, strlen(local_string) + 1);
+ wsize = mbstowcs(wc_string, local_string, wsize + 1);
wc_string[wsize] = (wchar_t) 0;
/* in case wchar_t is not zwchar */

47
tests/tests.yml Normal file
View file

@ -0,0 +1,47 @@
---
- hosts: localhost
tags:
- classic
tasks:
- name: Define remote_artifacts if it is not already defined
set_fact:
artifacts: ${HOME}/artifacts
when: artifacts is not defined
- name: Make artifacts directory
file: path={{ artifacts }} state=directory recurse=yes
- block:
- name: Execute tests
shell: |
logfile={{ artifacts }}/test.{{ item }}.log
exec 2>>$logfile 1>>$logfile
cd tests
#make script executable
chmod 0775 {{ item }}
#execute the test
python2 {{ item }}.py
if [ $? -eq 0 ]; then
echo "PASS {{ item }}" >> {{ artifacts }}/test.log
else
echo "FAIL {{ item }}" >> {{ artifacts }}/test.log
fi
with_items:
- "test_4GBsegfault"
- "test_big_file_in_archive"
- "test_long_path_in_archive"
- "test_many_files_in_archive"
- "test_umask"
- "test_umask_when_creating"
- "test_zipnote_fails_to_update_the_archive"
# Can't go in block. See
# https://github.com/ansible/ansible/issues/20736
- name: Check the results
shell: grep "^FAIL" {{ artifacts }}/test.log
register: test_fails
failed_when: test_fails.stdout or test_fails.stderr

154
tests/tests/__init__.py Executable file
View file

@ -0,0 +1,154 @@
'''
author = esakaiev@redhat.com
'''
import logging
import sys
import subprocess
import os
import shutil
def decorated_message(message):
"""
This decorator is used for providing logging header for different sections in the scripts
:param message: (`STRING`)
:return: decorated_function
"""
def decorated_function(func):
"""
:param func:
:return:
"""
def wrapper(self):
"""
:param self:
:return:
"""
print " "
print ("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
print (":: {0}".format(message))
print ("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
func(self)
return wrapper
return decorated_function
class BaseZipTests(object):
"""
This is a Base class for zip tests
"""
def __init__(self):
self._set_logger()
self._purpose = ""
self.print_test_purpose()
def _set_logger(self):
"""
This method is used for instantiating of logger
:return:
- None
"""
self.logger = logging.getLogger()
self.logger.setLevel(logging.DEBUG)
self.handler = logging.StreamHandler(sys.stdout)
self.handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('[ %(asctime)s ] :: [ %(message)s ]')
self.handler.setFormatter(formatter)
self.logger.addHandler(self.handler)
@decorated_message("PURPOSE")
def print_test_purpose(self):
"""
:return:
"""
print self._purpose
def run_cmd(self, cmd, exp_err_code, message, cwd=None):
"""
This method is used for executing cmd, check output error code and
add result in the logger
:param cmd: ('STRING') - some command to execute
:param exp_err_code: ('INTEGER') - expected error code
:param message: ('STRING') - command description
:param cwd: ('STRING') - path to directory, where need to execute cmd
:return:
- errcode ('INTEGER')
"""
try:
errcode = subprocess.call(cmd, shell=True, cwd=cwd, stdout=sys.stderr.fileno())
if errcode != exp_err_code:
self.logger.debug("FAIL :: {0}".format(message))
else:
self.logger.debug("PASS ] :: [ {0}".format(message))
return errcode
except subprocess.CalledProcessError as exp:
self.logger.error("Could not execute command {0}, e: {1}".format(cmd, exp))
def check_package(self):
"""
This method is used for checking, if zip package is installed
:return: None
"""
assert self.run_cmd("dnf list installed zip", 0, "Dnf package should be installed") == 0
def check_output(self, cmd, exp_output, message, cwd=None):
"""
This method is used for executing cmd and compare output result with expected message
:param cmd: (`STRING`) - some command to execute
:param exp_err_code: (`INTEGER`) - expected error code
:param message: (`STRING`) - command description
:param cwd: (`STRING`) - path to directory, where need to execute cmd
:return:
- output message (`STRING`)
"""
try:
output = self.execute_cmd(cmd, cwd)
if output != exp_output:
self.logger.debug("FAIL ]:: [ {}".format(message))
else:
self.logger.debug("PASS ] :: [ {}".format(message))
return output
except subprocess.CalledProcessError as exp:
self.logger.error(r'FAIL ] :: [ Could not execute command: "{0}",\
ex: {1}'.format(cmd, exp))
def execute_cmd(self, cmd, cwd=None):
"""
This method is used for executing cmd and return output message
:param cmd: (`STRING`) - some command to execute
:param cwd: (`STRING`) - path to directory, where need to execute cmd
:return:
- output message (`STRING`)
"""
try:
output = subprocess.check_output(cmd, shell=True, cwd=cwd)
return output
except subprocess.CalledProcessError as exp:
self.logger.error(r'FAIL ] :: [ Could not execute command: "{0}",\
ex: {1}'.format(cmd, exp))
def remove_file(self, file_path, is_directory=False):
"""
This method is used for removing files or directories after execution of test cases
:param file_path:(`STRING`) - path to file/folder
:param is_directory: (`BOOLEAN`) - True for directories
:return: None
"""
try:
if is_directory:
shutil.rmtree(file_path)
else:
os.remove(file_path)
self.logger.debug("File {0} has been successfully removed".format(file_path))
except OSError, exp:
self.logger.debug("File {0} doesn't exists, e: {1}".format(file_path, exp))

89
tests/tests/test_4GBsegfault.py Executable file
View file

@ -0,0 +1,89 @@
# Copyright (c) 2018 Red Hat, Inc. All rights reserved. This copyrighted material
# is made available to anyone wishing to use, modify, copy, or
# redistribute it subject to the terms and conditions of the GNU General
# Public License v.2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Author: Eduard Sakaiev <esakaiev@redhat.com>
import sys
import uuid
sys.path.append("..")
from tests import BaseZipTests
from tests import decorated_message
PURPOSE = '''zip mustn't segfault when packing files larger than 4 GB.
Note: this test can't run on RHEL 2.1 since the utilities used here
in the test don't work there as expected. This test can't run on
RHEL 5 either, but in this case, the reason is reworked zip which
can't work with files larger than 4 GB at all.'''
class Test4GBsegfault(BaseZipTests):
"""
This class is used for providing functionality
for Test4GBsegfault test case
"""
def __init__(self):
"""
"""
self._purpose = PURPOSE
super(Test4GBsegfault, self).__init__()
self._tmpdir = "/tmp/{}".format(uuid.uuid4())
@decorated_message("SETUP")
def prepare_setup(self):
"""
:return:
"""
self.check_package()
self.run_cmd("mkdir {}".format(self._tmpdir), 0,
"Creating tmp directory {}".format(self._tmpdir))
@decorated_message("TEST")
def start_test(self):
"""
:return:
"""
self.run_cmd("dd if=/dev/zero of=testfile bs=1M count=4097", 0,
"Creating of 4Gb file", self._tmpdir + "/")
self.run_cmd("zip testfile.zip testfile", 0,
"Archiving file with zip", self._tmpdir + "/")
@decorated_message("CLEANUP")
def cleanup(self):
"""
:return:
"""
self.run_cmd("rm -r {}".format(self._tmpdir), 0,
"Removing tmp directory")
if __name__ == "__main__":
test_4gb = Test4GBsegfault()
try:
test_4gb.prepare_setup()
test_4gb.start_test()
except AssertionError, exp:
test_4gb.logger.debug("FAIL ] :: [ Assertion occurred {0}".format(exp))
except Exception, exp:
test_4gb.logger.debug("FAIL ] :: [ Exception occurred {0}".format(exp))
finally:
test_4gb.cleanup()

View file

@ -0,0 +1,128 @@
# python2 test_big_file_in_archive.py
# Author: Josef Zila <jzila@redhat.com>
# Location: CoreOS/zip/Functionality/stress-tests/big-file-in-archive/runtest.sh
# Description: zip - tests handling large files (2GB,3MB,4GB)
# Copyright (c) 2008 Red Hat, Inc. All rights reserved. This copyrighted material
# is made available to anyone wishing to use, modify, copy, or
# redistribute it subject to the terms and conditions of the GNU General
# Public License v.2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Include rhts and rhtslib environment
# rpm -q --quiet rhtslib || rpm -Uvh http://nest.test.redhat.com/mnt/qa/scratch/pmuller/rhtslib/rhtslib.rpm
import sys
import uuid
import platform
sys.path.append("..")
from tests import BaseZipTests
from tests import decorated_message
PURPOSE = '''
Test Name: Big file in archive
Author: Josef Zila <jzila@redhat.com>
Location: CoreOS/zip/Functionality/stress-tests/big-file-in-archive/PURPOSE
Short Description:
Tests handling large files (2GB,3GB,4GB)
Long Description:
Test creates three files (2GB, 3GB and 4GB large) and attempts to archive each of them using zip. Then original files are deleted
and archives are unpacked, to check size of unpacked files. Current version of zip on all archs and distros in time of
writing(2.31-1) passes test. Note: 4GB file is too large for zip to handle, so it is not supposed to be successfully archived
or unpacked, test just checks for correct return codes.
how to run it:
python2 test_big_file_in_archive.py
TEST UPDATED (esakaiev)
------------------------
After rebase to zip-3.0-1 there is no 4GB limit. Patching the test accordingly.
'''
class TestBigFileInArchive(BaseZipTests):
"""
This class is used for providing functionality
for TestBigFileInArchive test case
"""
def __init__(self):
"""
"""
self._purpose = PURPOSE
super(TestBigFileInArchive, self).__init__()
self._files = ['/tmp/tmp.{}'.format(uuid.uuid4()) for x in xrange(3)]
self._files_sizes = [2048, 3056, 4096]
self._os_distribution = platform.linux_distribution()
@decorated_message("Preparing Setup")
def prepare_setup(self):
"""
:return:
"""
self.check_package()
for i, file_name in enumerate(self._files):
size = self._files_sizes[i]
assert self.run_cmd("dd if=/dev/zero of={0} bs=1M count={1}".format(file_name, size), 0,
"Creating {0} GB file".format(size / 1000), cwd="/tmp/") == 0
@decorated_message("Starting Test")
def start_test(self):
"""
:return:
"""
for i, file_name in enumerate(self._files):
error_code = 0
self.remove_file(file_name + ".zip") # #remove archive temp files, we just need unused temp names
size = self._files_sizes[i]
self.run_cmd("zip {0} {1}".format(file_name + ".zip", file_name), error_code,
"Archiving {} Gb file".format(size / 1000), cwd="/tmp/")
self.remove_file(file_name) # Removing original files
self.run_cmd("unzip {0} -d /".format(file_name + ".zip"), error_code,
"Unpacking {} Gb file".format(size / 1000), cwd="/tmp/")
# Checking new 2GB file size
self.check_output("stat -c %s {0}".format(self._files[0]), "2147483648\n", "Checking new 2GB file size")
@decorated_message("Cleaning up")
def cleanup(self):
"""
:return:
"""
for file_name in self._files:
self.remove_file(file_name)
self.remove_file(file_name + ".zip")
if __name__ == "__main__":
test = TestBigFileInArchive()
try:
test.prepare_setup()
test.start_test()
except AssertionError, exp:
test.logger.debug("FAIL ] :: [ Assertion occurred {0}".format(exp))
except Exception, exp:
test.logger.debug("FAIL ] :: [ Exception occurred {0}".format(exp))
finally:
test.cleanup()

View file

@ -0,0 +1,140 @@
# Author: Josef Zila <jzila@redhat.com>
# Location: CoreOS/zip/Functionality/stress-tests/long-path-in-archive/runtest.sh
# Description: zip - tests handling very long paths within archive (15*256 characters long path)
# Copyright (c) 2008 Red Hat, Inc. All rights reserved. This copyrighted material
# is made available to anyone wishing to use, modify, copy, or
# redistribute it subject to the terms and conditions of the GNU General
# Public License v.2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
import uuid
import os
from shutil import copyfile
sys.path.append("..")
from tests import BaseZipTests
from tests import decorated_message
PURPOSE = '''
Test Name:
Author: Josef Zila <jzila@redhat.com>
Location: CoreOS/zip/Functionality/stress-tests/long-path-in-archive/PURPOSE
Short Description:
Tests handling very long paths within archive (15*256 characters long path)
Long Description:
This test creates file with very long path of 15 directories, each 255 characters. This whole directory structure is then zipped and unzipped
to determine if zip program handles paths this long correctly. Current version of zip on all archs and distros in time of writing(2.31-1) passes test.
how to run it:
choose arch and distro
TEST UPDATED (esakaiev)
'''
class TestLongPathInArchive(BaseZipTests):
"""
This class is used for providing functionality
for TestLongPathInArchive test case
"""
def __init__(self):
self._purpose = PURPOSE
super(TestLongPathInArchive, self).__init__()
self._tmpdir = "/tmp/{}".format(uuid.uuid4())
self._file_under_test = "/proc/version"
self._long_name = "".join(["aaaaa" for i in xrange(51)])
self._long_path = "/".join([self._long_name for x in xrange(15)])
self._test_file_path = self._tmpdir + "/" + self._long_path + "/" + "testfile"
self._package_ver = ""
self._package_release = ""
@decorated_message("Prepare setup")
def prepare_setup(self):
"""
:return:
"""
self.check_package()
self.run_cmd("mkdir {}".format(self._tmpdir), 0, "Creating tmp directory {}".format(self._tmpdir))
self._package_ver = self.execute_cmd("rpm -q zip --queryformat %{version}")
self._package_release = self.execute_cmd("rpm -q zip --queryformat %{version}")
self.logger.debug("Running zip.{0}.{1} package".format(self._package_ver, self._package_release))
# creating folders structure:
try:
os.makedirs(self._tmpdir + "/" + self._long_path)
self.logger.debug("PASS ] :: [ Test directory with long path has been successfully created")
except OSError, exp:
self.logger.debug("FAIL ] :: [ Could not create directories by path, e: {}".format(exp))
raise
copyfile(self._file_under_test, self._test_file_path)
@decorated_message("Starting Test cases")
def start_test(self):
"""
:return:
"""
self.run_cmd("zip -r test {0} -q".format(self._long_name), 0,
"Zipping test file",
cwd=self._tmpdir)
self.remove_file(self._tmpdir + "/" + self._long_name, True)
self.run_cmd("unzip -qq test.zip", 0,
"Unzipping test file",
cwd=self._tmpdir)
content_init = None
with open(self._file_under_test) as fp_init:
content_init = fp_init.read().replace('\n', '')
content_fut = None
with open(self._test_file_path) as fp_fut:
content_fut = fp_fut.read().replace('\n', '')
if content_init == content_fut:
self.logger.debug("PASS ] :: [ {}".format("Content of the initial file and file under test was matched"))
else:
self.logger.debug("FAIL ] :: [ {}".format("Content of the initial file and file under test wasn't matched"))
@decorated_message("Cleaning up")
def cleanup(self):
"""
:return:
"""
self.remove_file(self._tmpdir, True)
if __name__ == "__main__":
test = TestLongPathInArchive()
try:
test.prepare_setup()
test.start_test()
except AssertionError, exp:
test.logger.debug("FAIL ] :: [ Assertion occurred {0}".format(exp))
except Exception, exp:
test.logger.debug("FAIL ] :: [ Exception occurred {0}".format(exp))
finally:
test.cleanup()

View file

@ -0,0 +1,140 @@
# Author: Josef Zila <jzila@redhat.com>
# Location: CoreOS/zip/Functionality/stress-tests/many-files-in-archive/runtest.sh
# Description: zip - Tests behaviour with many files in archive (1048578 files)
# Copyright (c) 2008 Red Hat, Inc. All rights reserved. This copyrighted material
# is made available to anyone wishing to use, modify, copy, or
# redistribute it subject to the terms and conditions of the GNU General
# Public License v.2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
import uuid
sys.path.append("..")
from tests import BaseZipTests
from tests import decorated_message
PURPOSE = '''
Test Name:
Author: Josef Zila <jzila@redhat.com>
Location: CoreOS/zip/Functionality/stress-tests/many-files-in-archive/PURPOSE
Short Description:
Tests behaviour with many files in archive (1048577 files)
Long Description:
This test creates 1048576 empty files and one non-empty file. Then zips and unzips directory containing all those files and tests content of
non-empty file and count of unzipped files. This test is very time-consuming. Current version of zip on all archs and distros in time of writing
(2.31-1) passes test.
how to run it:
choose arch and distro
TEST UPDATED (esakaiev)
'''
class TestManyFilesInArchive(BaseZipTests):
"""
This class is used for providing functionality
for TestManyFilesInArchive test case
"""
def __init__(self):
self._purpose = PURPOSE
super(TestManyFilesInArchive, self).__init__()
self._tmpdir = "/tmp/{}".format(uuid.uuid4())
self._files_number = 1048576
self._package_ver = ""
self._package_release = ""
@decorated_message("Prepare setup")
def prepare_setup(self):
"""
:return:
"""
self.check_package()
self.run_cmd("mkdir {}".format(self._tmpdir), 0,
"Creating tmp directory {}".format(self._tmpdir))
self._package_ver = self.execute_cmd("rpm -q zip --queryformat %{version}")
self._package_release = self.execute_cmd("rpm -q zip --queryformat %{version}")
self.logger.debug("Running zip.{0}.{1} package".format(self._package_ver, self._package_release))
self.logger.debug("Creating {0} files".format(self._files_number))
[open("{0}/{1}".format(self._tmpdir, i), "w").close() for i in xrange(self._files_number)]
self.logger.debug("Creating test file")
with open("{0}/test.txt".format(self._tmpdir), "w") as fp:
fp.write("12345")
@decorated_message("Starting Test cases")
def start_test(self):
"""
:return:
"""
self.run_cmd("zip -r test {0} -q".format(self._tmpdir.split('/')[-1]), 0,
"Zipping test files",
cwd='/tmp')
self.remove_file(self._tmpdir, True)
self.run_cmd("unzip -qq test.zip", 0,
"Unzipping test files",
cwd='/tmp')
test_file_content = None
with open("{0}/test.txt".format(self._tmpdir)) as fp:
test_file_content = fp.read().replace('/n', '')
if test_file_content == "12345":
self.logger.debug("PASS ] :: [ {}".format("Unpacked content matches original"))
else:
self.logger.debug("FAIL ] :: [ {}".format("Unpacked content does not match original!"))
files_count = self.execute_cmd("ls {0} | wc -l".format(self._tmpdir)).replace("\n", "")
if files_count == str(self._files_number + 1):
self.logger.debug(
"PASS ] :: [ {}".format("All {0} files present after unpacking".format(self._files_number + 1)))
else:
self.logger.debug(r"FAIL ] :: [ File count changed after unpacking! \
Before zipping there was {0} files. \
After unzip there is {1} files.".format(self._files_number + 1, files_count))
@decorated_message("Cleaning up")
def cleanup(self):
"""
:return:
"""
self.remove_file(self._tmpdir, True)
self.remove_file("/tmp/test.zip")
if __name__ == "__main__":
test = TestManyFilesInArchive()
try:
test.prepare_setup()
test.start_test()
except AssertionError, exp:
test.logger.debug("FAIL ] :: [ Assertion occurred {0}".format(exp))
except Exception, exp:
test.logger.debug("FAIL ] :: [ Exception occurred {0}".format(exp))
finally:
test.cleanup()

106
tests/tests/test_umask.py Executable file
View file

@ -0,0 +1,106 @@
# Copyright (c) 2006 Red Hat, Inc. All rights reserved. This copyrighted material
# is made available to anyone wishing to use, modify, copy, or
# redistribute it subject to the terms and conditions of the GNU General
# Public License v.2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Author: Radek Biba <rbiba@redhat.com>
import sys
import uuid
UMASK = "Running umask"
sys.path.append("..")
from tests import BaseZipTests
from tests import decorated_message
PURPOSE = '''
zip is supposed to honor umask settings when creating archives.
This test case just checks if it really does
TEST UPDATED (esakaiev)
'''
class TestUmask(BaseZipTests):
"""
This class is used for providing functionality
for TestUmask test case
"""
def __init__(self):
self._purpose = PURPOSE
super(TestUmask, self).__init__()
self._tmpdir = "/tmp/{}".format(uuid.uuid4())
self._mask_list = ["0", "2", "20", "22", "200", "202", "220", "222", "6", "60"]
self._package_ver = ""
self._package_release = ""
@decorated_message("Prepare setup")
def prepare_setup(self):
"""
:return:
"""
self.check_package()
self.run_cmd("mkdir {}".format(self._tmpdir), 0, "Creating tmp directory {}".format(self._tmpdir))
self._package_ver = self.execute_cmd("rpm -q zip --queryformat %{version}")
self._package_release = self.execute_cmd("rpm -q zip --queryformat %{version}")
self.logger.debug("Running zip.{0}.{1} package".format(self._package_ver, self._package_release))
# Trying to verify that zip honors umask. Trying with various combinations
# of 'w's and 'r's for User, Group, and Others.
@decorated_message("Starting Test cases")
def start_test(self):
"""
:return:
"""
for mask in self._mask_list:
self.logger.debug("Running umask and zipping file {0}".format(mask))
self.execute_cmd("umask {0}; touch {0}; zip -q {0}.zip {0}".format(mask), cwd=self._tmpdir)
stat_test_zip = self.execute_cmd("stat -c %a {0}.zip".format(mask), cwd=self._tmpdir).replace("\n", "")
stat_test = self.execute_cmd("stat -c %a {0}".format(mask), cwd=self._tmpdir).replace("\n", "")
print stat_test_zip, stat_test
if stat_test_zip == stat_test:
self.logger.debug(
"PASS ] :: [ permissions for {0}.zip match to {0}, {1} == {2}".format(mask, stat_test_zip,
stat_test))
else:
self.logger.debug(
"FAIL ] :: [ permissions for {0}.zip doesn't match to {0}, {1} != {2}".format(mask, stat_test_zip,
stat_test))
@decorated_message("Cleaning up")
def cleanup(self):
"""
:return:
"""
self.remove_file(self._tmpdir, True)
if __name__ == "__main__":
test = TestUmask()
try:
test.prepare_setup()
test.start_test()
except AssertionError, exp:
test.logger.debug("FAIL ] :: [ Assertion occurred {0}".format(exp))
except Exception, exp:
test.logger.debug("FAIL ] :: [ Exception occurred {0}".format(exp))
finally:
test.cleanup()

View file

@ -0,0 +1,105 @@
# Author: Josef Zila <jzila@redhat.com>
# Description: Zip did not honor umask setting when creating archives.
# Copyright (c) 2008 Red Hat, Inc. All rights reserved. This copyrighted material
# is made available to anyone wishing to use, modify, copy, or
# redistribute it subject to the terms and conditions of the GNU General
# Public License v.2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
import uuid
UMASK = "Running umask"
sys.path.append("..")
from tests import BaseZipTests
from tests import decorated_message
PURPOSE = '''
Test Name: umask-when-creating
Author: Josef Zila <jzila@redhat.com>
Short Description:
zip does not honor umaks setting when creating archive
Long Description:
zip appears to have a built-in umask of 0022 regardless of the global umask.
With umask set to 0000, zip-2.3-27 creates zip files with permissions of
0644 instead of 0666. Previous versions created files with correct permissions.
TEST UPDATED (esakaiev)
'''
class TestUmaskWhenCreating(BaseZipTests):
"""
This class is used for providing functionality
for TestUmaskWhenCreating test case
"""
def __init__(self):
self._purpose = PURPOSE
super(TestUmaskWhenCreating, self).__init__()
self._tmpdir = "/tmp/{}".format(uuid.uuid4())
self._mask_list = ["777", "000", "027"]
self._expected_results = ["----------", "-rw-rw-rw-", "-rw-r-----"]
self._package_ver = ""
self._package_release = ""
@decorated_message("Prepare setup")
def prepare_setup(self):
self.check_package()
self.run_cmd("mkdir {}".format(self._tmpdir), 0, "Creating tmp directory {}".format(self._tmpdir))
self._package_ver = self.execute_cmd("rpm -q zip --queryformat %{version}")
self._package_release = self.execute_cmd("rpm -q zip --queryformat %{version}")
self.logger.debug("Running zip.{0}.{1} package".format(self._package_ver, self._package_release))
@decorated_message("Starting Test cases")
def start_test(self):
for i, mask in enumerate(self._mask_list):
self.logger.debug("Running umask and zipping file {0}".format(mask))
self.execute_cmd("umask -S {0} >> /dev/null; zip test /etc/services >> /dev/null".format(mask),
cwd=self._tmpdir)
result = self.execute_cmd("ls -l test.zip | cut -b 1-10", cwd=self._tmpdir).replace("\n", "")
if result == self._expected_results[i]:
self.logger.debug(
"PASS ] :: [ file permissions match to {0}".format(self._expected_results[i]))
else:
self.logger.debug(
"FAIL ] :: [ file permissions don't match to {0}".format(self._expected_results[i]))
self.remove_file(self._tmpdir + "/" + "test.zip")
@decorated_message("Cleaning up")
def cleanup(self):
self.remove_file(self._tmpdir, True)
if __name__ == "__main__":
test = TestUmaskWhenCreating()
try:
test.prepare_setup()
test.start_test()
except AssertionError, exp:
test.logger.debug("FAIL ] :: [ Assertion occurred {0}".format(exp))
except Exception, exp:
test.logger.debug("FAIL ] :: [ Exception occurred {0}".format(exp))
finally:
test.cleanup()

View file

@ -0,0 +1,105 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Description: zipnote fails to update the archive
# Author: Karel Volny <kvolny@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2015 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import sys
import uuid
sys.path.append("..")
from tests import BaseZipTests
from tests import decorated_message
PURPOSE = '''
PURPOSE of zipnote-fails-to-update-the-archive
Description: zipnote fails to update the archive
Author: Karel Volny <kvolny@redhat.com>
TEST UPDATED (esakaiev)
'''
class TestZipnoteFailsToUpdateTheArchive(BaseZipTests):
"""
This class is used for providing functionality
for TestZipnoteFailsToUpdateTheArchive test case
"""
def __init__(self):
self._purpose = PURPOSE
super(TestZipnoteFailsToUpdateTheArchive, self).__init__()
self._tmpdir = '/tmp/tmp.{}'.format(uuid.uuid4())
@decorated_message("Preparing setup")
def prepare_setup(self):
"""
:return:
"""
self.check_package()
self.run_cmd("mkdir {}".format(self._tmpdir), 0, "Creating tmp directory {}".format(self._tmpdir))
@decorated_message("Starting Test")
def start_test(self):
"""
:return:
"""
self.run_cmd("touch file", 0, "Creating the Demo file", cwd=self._tmpdir)
self.run_cmd("zip archive.zip file", 0, "Creating the archive including the file", cwd=self._tmpdir)
self.run_cmd("zipnote archive.zip > info.txt", 0, "Reading the archive comments", cwd=self._tmpdir)
## bad - e.g. zip-3.0-1.el6.i686:
# zipnote error: Interrupted (aborting)
# Segmentation fault
## good: no output
self.run_cmd("zipnote -w archive.zip < info.txt > output_file.txt 2>&1", 0, "Writing comments to the archive",
cwd=self._tmpdir)
if 'error' in open(self._tmpdir + '/output_file.txt').read():
self.logger.debug("FAIL ] :: [ File shouldn't contain an error pattern")
else:
self.logger.debug("PASS ] :: [ File doesn't contain an error pattern")
@decorated_message("Cleaning up")
def cleanup(self):
"""
:return:
"""
self.run_cmd("rm -r {}".format(self._tmpdir), 0,
"Removing tmp directory")
if __name__ == "__main__":
test = TestZipnoteFailsToUpdateTheArchive()
try:
test.prepare_setup()
test.start_test()
except AssertionError, exp:
test.logger.debug("FAIL ] :: [ Assertion occurred {0}".format(exp))
except Exception, exp:
test.logger.debug("FAIL ] :: [ Exception occurred {0}".format(exp))
finally:
test.cleanup()

View file

@ -0,0 +1,11 @@
--- ./man/zip.1.old 2024-12-11 10:51:22.837845520 +0100
+++ ./man/zip.1 2024-12-11 10:51:34.458142392 +0100
@@ -2297,7 +2297,7 @@
.B \-X
.TP
.PD
-.B \-\-no\-extra
+.B \-\-strip\-extra
Do not save extra file attributes (Extended Attributes on OS/2, uid/gid
and file times on Unix). The zip format uses extra fields to include
additional information for each entry. Some extra fields are specific

15
zip-gnu89-build.patch Normal file
View file

@ -0,0 +1,15 @@
zip uses C89-only features, so it needs to be built in C89 mode.
diff --git a/unix/Makefile b/unix/Makefile
index 86cf54bf0f56cea9..244390893eab5fc6 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -202,7 +202,7 @@ generic: flags
eval $(MAKE) $(MAKEF) zips `cat flags`
generic_gcc:
- $(MAKE) $(MAKEF) generic CC=gcc CPP="gcc -E"
+ $(MAKE) $(MAKEF) generic CC="gcc -std=gnu89" CPP="gcc -E"
# AT&T 6300 PLUS (don't know yet how to allocate 64K bytes):
att6300nodir:

111
zip.spec
View file

@ -1,9 +1,8 @@
Summary: A file compression and packaging utility compatible with PKZIP
Name: zip
Version: 3.0
Release: 18%{?dist}
License: BSD
Group: Applications/Archiving
Release: 44%{?dist}
License: Info-ZIP
Source: http://downloads.sourceforge.net/infozip/zip30.tar.gz
URL: http://www.info-zip.org/Zip.html
@ -17,7 +16,11 @@ Patch3: zip-3.0-time.patch
Patch4: man.patch
Patch5: zip-3.0-format-security.patch
Patch6: zipnote.patch
BuildRequires: bzip2-devel
Patch7: zip-gnu89-build.patch
Patch8: buffer_overflow.patch
Patch9: zip-3.0-man-strip-extra.patch
BuildRequires: make
BuildRequires: bzip2-devel, gcc
Requires: unzip
%description
@ -31,22 +34,25 @@ program.
%prep
%setup -q -n zip30
%patch1 -p1 -b .exec-shield
%patch2 -p1 -b .currdir
%patch3 -p1 -b .time
%patch4 -p1 -b .man
%patch5 -p1 -b .format-security
%patch6 -p1 -b .zipnote
%patch -P1 -p1 -b .exec-shield
%patch -P2 -p1 -b .currdir
%patch -P3 -p1 -b .time
%patch -P4 -p1 -b .man
%patch -P5 -p1 -b .format-security
%patch -P6 -p1 -b .zipnote
%patch -P7 -p1 -b .gnu89-build
%patch -P8 -p1
%patch -P9 -p1
%build
make -f unix/Makefile prefix=%{_prefix} "CFLAGS_NOOPT=-I. -DUNIX $RPM_OPT_FLAGS" generic_gcc %{?_smp_mflags}
%{make_build} -f unix/Makefile prefix=%{_prefix} "CFLAGS_NOOPT=-I. -DUNIX $RPM_OPT_FLAGS" generic_gcc
%install
mkdir -p $RPM_BUILD_ROOT%{_bindir}
mkdir -p $RPM_BULD_ROOT%{_mandir}/man1
make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} \
MANDIR=$RPM_BUILD_ROOT%{_mandir}/man1 install
%{make_install} -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} \
MANDIR=$RPM_BUILD_ROOT%{_mandir}/man1
%files
%license LICENSE
@ -62,6 +68,85 @@ make -f unix/Makefile prefix=$RPM_BUILD_ROOT%{_prefix} \
%{_mandir}/man1/zipsplit.1*
%changelog
* Fri Jul 25 2025 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-44
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Sun Jan 19 2025 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-43
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Wed Dec 11 2024 Jakub Martisko <jamartis@redhat.com> - 3.0-42
- Fix teh manpage: --no-extra option is actually called --strip-extra
* Sat Jul 20 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-41
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Sat Jan 27 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-40
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Mon Sep 18 2023 Jakub Martisko <jamartis@redhat.com> - 3.0-39
- Fixc buffer overflow in unicode file names
Resolves: rhbz#2165653
* Sat Jul 22 2023 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-38
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Thu Apr 13 2023 Lukáš Zaoral <lzaoral@redhat.com> - 3.0-37
- migrate to SPDX license format
* Sat Jan 21 2023 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-36
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Fri Nov 18 2022 Florian Weimer <fweimer@redhat.com> - 3.0-35
- Really build with -std=gnu89 (#2143565)
* Thu Nov 17 2022 Florian Weimer <fweimer@redhat.com> - 3.0-34
- Build with -std=gnu89 (#2143565)
* Sat Jul 23 2022 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-33
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Sat Jan 22 2022 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-32
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-31
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Fri Mar 05 2021 Jakub Martisko <jamartis@redhat.com> - 3.0-30
- Use generic build instead of generic_gcc
* Fri Mar 05 2021 Jakub Martisko <jamartis@redhat.com> - 3.0-29
- Use build macros
* Thu Jan 28 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-28
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-27
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-26
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-25
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-24
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-23
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu Mar 01 2018 Jakub Martisko <jamartis@redhat.com> - 3.0-22
- Add gcc to buildrequires
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-21
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-20
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Thu Jul 27 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-19
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-18
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild