1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-07-07 01:40:10 +02:00

Merge branch 'ndk-unzip' into 'master'

NDK-Install: handle symbolic links correctly

See merge request fdroid/fdroidserver!1023
This commit is contained in:
Hans-Christoph Steiner 2021-11-03 08:30:33 +00:00
commit c26345214f
2 changed files with 79 additions and 2 deletions

View File

@ -4338,7 +4338,19 @@ def _install_ndk(ndk):
with zipfile.ZipFile(zipball) as zipfp: with zipfile.ZipFile(zipball) as zipfp:
for info in zipfp.infolist(): for info in zipfp.infolist():
permbits = info.external_attr >> 16 permbits = info.external_attr >> 16
if stat.S_ISDIR(permbits) or stat.S_IXUSR & permbits: if stat.S_ISLNK(permbits):
link = os.path.join(ndk_base, info.filename)
link_target = zipfp.read(info).decode()
link_dir = os.path.dirname(link)
os.makedirs(link_dir, 0o755, True) # ensure intermediate directories are created
os.symlink(link_target, link)
real_target = os.path.realpath(link)
if not real_target.startswith(ndk_base):
os.remove(link)
logging.error(_('Unexpected symlink target: {link} -> {target}')
.format(link=link, target=real_target))
elif stat.S_ISDIR(permbits) or stat.S_IXUSR & permbits:
zipfp.extract(info.filename, path=ndk_base) zipfp.extract(info.filename, path=ndk_base)
os.chmod(os.path.join(ndk_base, info.filename), 0o755) # nosec bandit B103 os.chmod(os.path.join(ndk_base, info.filename), 0o755) # nosec bandit B103
else: else:

View File

@ -20,7 +20,8 @@ import unittest
import textwrap import textwrap
import yaml import yaml
import gzip import gzip
from zipfile import ZipFile import stat
from zipfile import ZipFile, ZipInfo
from unittest import mock from unittest import mock
from pathlib import Path from pathlib import Path
@ -2116,6 +2117,70 @@ class CommonTest(unittest.TestCase):
_ignored # silence the linters _ignored # silence the linters
fdroidserver.common._install_ndk(r) fdroidserver.common._install_ndk(r)
def test_install_ndk_with_symlinks(self):
"""Some NDK zipballs might have symlinks in them."""
def fake_download(url, zipball):
print(url, zipball)
unix_st_mode = (
stat.S_IFLNK
| stat.S_IRUSR
| stat.S_IWUSR
| stat.S_IXUSR
| stat.S_IRGRP
| stat.S_IWGRP
| stat.S_IXGRP
| stat.S_IROTH
| stat.S_IWOTH
| stat.S_IXOTH
)
with ZipFile(zipball, 'w') as zipfp:
zipfp.writestr('ndk/' + os.path.basename(url), url)
zipInfo = ZipInfo('ndk/basename')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, os.path.basename(url))
zipInfo = ZipInfo('ndk/bad_abs_link')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, '/etc/passwd')
zipInfo = ZipInfo('ndk/bad_rel_link')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, '../../../../../../../etc/passwd')
zipInfo = ZipInfo('ndk/bad_rel_link2')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, 'foo/../../../../../../../../../etc/passwd')
sdk_path = tempfile.mkdtemp(
prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir
)
config = {'sdk_path': sdk_path}
fdroidserver.common.config = config
r = 'r20'
sha256 = '57435158f109162f41f2f43d5563d2164e4d5d0364783a9a6fab3ef12cb06ce0'
with mock.patch(
'fdroidserver.net.download_file', side_effect=fake_download
) as _ignored, mock.patch(
'fdroidserver.common.get_ndk_version', return_value=r
) as _ignored, mock.patch(
'fdroidserver.common.sha256sum', return_value=sha256
):
_ignored # silence the linters
fdroidserver.common._install_ndk(r)
self.assertTrue(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20')))
self.assertTrue(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'basename')))
self.assertFalse(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'bad_abs_link')))
self.assertFalse(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'bad_rel_link')))
self.assertFalse(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'bad_rel_link2')))
os.system('ls -l ' + os.path.join(sdk_path, 'ndk', 'r20'))
def test_fill_config_defaults(self): def test_fill_config_defaults(self):
"""Test the auto-detection of NDKs installed in standard paths""" """Test the auto-detection of NDKs installed in standard paths"""
sdk_path = tempfile.mkdtemp( sdk_path = tempfile.mkdtemp(