Commit 6f274446 authored by Julien Muchembled's avatar Julien Muchembled

fix_shebang: don't touch symlinks

Symlinks can point anywhere outside the parts. Also symlinks can be
broken.

By using lstat instead of stat, the symlink is not considered as a
regular file.

See merge request !14
parent 02a086dd
Pipeline #13863 passed with stage
in 0 seconds
......@@ -463,7 +463,7 @@ echo %s
continue
for f in os.listdir(dir_abspath):
f_abspath = os.path.join(dir_abspath, f)
st_mode = os.stat(f_abspath).st_mode
st_mode = os.lstat(f_abspath).st_mode
if not stat.S_ISREG(st_mode):
continue
with open(f_abspath, 'rb') as f:
......
......@@ -8,8 +8,10 @@ import shutil
import stat
import tarfile
import tempfile
import pkg_resources
from contextlib import contextmanager
from io import BytesIO
from time import sleep
import pkg_resources
import zc.buildout
import zc.buildout.testing
import zc.buildout.tests
......@@ -30,6 +32,25 @@ def setUp(test):
zc.buildout.testing.install('slapos.recipe.build', test)
zc.buildout.testing.install_develop('slapos.recipe.cmmi', test)
def tarfile_addfileobj(tarobj, name, dataobj, **kw):
tarinfo = tarfile.TarInfo(name)
dataobj.seek(0, 2)
tarinfo.size = dataobj.tell()
dataobj.seek(0)
for x in kw.items():
setattr(tarinfo, *x)
tarobj.addfile(tarinfo, dataobj)
@contextmanager
def fake_package(**kw):
with tempfile.NamedTemporaryFile(suffix=".tar") as tmp:
with tarfile.open(mode='w', fileobj=tmp) as tar:
for k, v in kw.items():
tarfile_addfileobj(tar, k, BytesIO(v.encode()),
**{'mode':stat.S_IRWXU} if v.startswith('#!') else {})
tmp.flush()
yield tmp.name
class NonInformativeTests(unittest.TestCase):
def setUp(self):
......@@ -103,25 +124,13 @@ class NonInformativeTests(unittest.TestCase):
recipe.install()
def test_restart_after_failure(self):
temp_directory = tempfile.mkdtemp(dir=self.dir, prefix="fake_package")
configure_path = os.path.join(temp_directory, 'configure')
self.write_file(configure_path, 'exit 0', mode=stat.S_IRWXU)
makefile_path = os.path.join(temp_directory, 'Makefile')
self.write_file(makefile_path, 'all:\n\texit -1')
os.chdir(temp_directory)
ignore, tarfile_path = tempfile.mkstemp(suffix=".tar")
tar = tarfile.open(tarfile_path, 'w')
tar.add('configure')
tar.add('Makefile')
tar.close()
with fake_package(
configure='#!/bin/sh\n',
Makefile='all:\n\texit -1',
) as tarfile_path:
recipe = self.make_recipe({}, 'test', {'url': tarfile_path})
os.chdir(self.dir)
recipe = self.make_recipe({}, 'test', {'url': tarfile_path})
os.chdir(self.dir)
try:
# expected failure
with self.assertRaises(zc.buildout.UserError):
recipe.install()
......@@ -129,12 +138,6 @@ class NonInformativeTests(unittest.TestCase):
# the install should still fail, and _not_ raise an OSError
with self.assertRaises(zc.buildout.UserError):
recipe.install()
finally:
try:
shutil.rmtree(temp_directory)
os.remove(tarfile_path)
except:
pass
def test_environment_restored_after_building_a_part(self):
# Make sure the test variables do not exist beforehand
......@@ -345,6 +348,22 @@ class NonInformativeTests(unittest.TestCase):
build_directory = os.path.join(self.dir, 'test_parts/test__compile__')
self.assertTrue(os.path.exists(build_directory))
def test_bad_symlink_in_bin(self):
with fake_package(
configure="""#!/bin/sh
echo prefix = ${@##--prefix=} > Makefile.in
""",
Makefile="""include Makefile.in
install:
\tmkdir -p $(prefix)/bin
\tln -sf /DUMMYFILENOTEXISTING $(prefix)/bin/badlink
""",
) as tarfile_path:
recipe = self.make_recipe({}, 'test', {'url': tarfile_path})
os.chdir(self.dir)
recipe.install()
self.assertTrue(os.path.islink('test_parts/test/bin/badlink'))
def test_suite():
sums = []
def md5sum(m):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment