mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-03 17:50:11 +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:
commit
c26345214f
@ -4338,7 +4338,19 @@ def _install_ndk(ndk):
|
||||
with zipfile.ZipFile(zipball) as zipfp:
|
||||
for info in zipfp.infolist():
|
||||
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)
|
||||
os.chmod(os.path.join(ndk_base, info.filename), 0o755) # nosec bandit B103
|
||||
else:
|
||||
|
@ -20,7 +20,8 @@ import unittest
|
||||
import textwrap
|
||||
import yaml
|
||||
import gzip
|
||||
from zipfile import ZipFile
|
||||
import stat
|
||||
from zipfile import ZipFile, ZipInfo
|
||||
from unittest import mock
|
||||
from pathlib import Path
|
||||
|
||||
@ -2116,6 +2117,70 @@ class CommonTest(unittest.TestCase):
|
||||
_ignored # silence the linters
|
||||
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):
|
||||
"""Test the auto-detection of NDKs installed in standard paths"""
|
||||
sdk_path = tempfile.mkdtemp(
|
||||
|
Loading…
Reference in New Issue
Block a user