mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-11-20 13:50:12 +01:00
NDK Install: Handle symlinks present in NDK zip
This commit is contained in:
parent
b12ece1eba
commit
aead3310bd
@ -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:
|
||||||
|
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user