From 969c4f7efa1f757078b12862c6d32a8db86ce2e1 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Thu, 23 May 2024 17:04:29 -0400 Subject: [PATCH] Disallow certain names from being read by any but specific sources Fixes #1536. --- CHANGELOG.md | 1 + docs/config_options.rst | 4 +++- large_image/config.py | 4 ++++ large_image/tilesource/__init__.py | 5 ++++- test/lisource_compare.py | 1 + 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 634799e4f..22cd7d2a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Improvements - Better detect available memory in containers ([#1532](../../pull/1532)) - Reject the promise from a canceled annotation ([#1535](../../pull/1535)) +- Disallow certain names from being read by any but specific sources ([#1537](../../pull/1537)) ### Changes - Log more when saving annotations ([#1525](../../pull/1525)) diff --git a/docs/config_options.rst b/docs/config_options.rst index f614efb2f..8ac0bb06f 100644 --- a/docs/config_options.rst +++ b/docs/config_options.rst @@ -27,7 +27,9 @@ Configuration parameters: - ``max_small_image_size``: The PIL tilesource is used for small images if they are no more than this many pixels along their maximum dimension. -- ``source_bioformats_ignored_names``, ``source_pil_ignored_names``, ``source_vips_ignored_names``: Some tile sources can read some files that are better read by other tilesources. Since reading these files is suboptimal, these tile sources have a setting that, by default, ignores files without extensions or with particular extensions. This setting is a Python regular expressions. For bioformats this defaults to ``r'(^[!.]*|\.(jpg|jpeg|jpe|png|tif|tiff|ndpi))$'``. +- ``source_bioformats_ignored_names``, ``source_pil_ignored_names``, ``source_vips_ignored_names``: Some tile sources can read some files that are better read by other tilesources. Since reading these files is suboptimal, these tile sources have a setting that, by default, ignores files without extensions or with particular extensions. This setting is a Python regular expression. For bioformats this defaults to ``r'(^[!.]*|\.(jpg|jpeg|jpe|png|tif|tiff|ndpi))$'``. + +- ``all_sources_ignored_names``: If a file matches the regular expression in this setting, it will only be opened by sources that explicitly match the extension or mimetype. Some formats are composed of multiple files that can be read as either a small image or as a large image depending on the source; this prohibits all sources that don't explicitly support the format. - ``icc_correction``: If this is True or undefined, ICC color correction will be applied for tile sources that have ICC profile information. If False, correction will not be applied. If the style used to open a tilesource specifies ICC correction explicitly (on or off), then this setting is not used. This may also be a string with one of the intents defined by the PIL.ImageCms.Intents enum. ``True`` is the same as ``perceptual``. diff --git a/large_image/config.py b/large_image/config.py index cbdaea090..88029455e 100644 --- a/large_image/config.py +++ b/large_image/config.py @@ -58,6 +58,10 @@ # via direct load 'max_annotation_input_file_length': 1 * 1024 ** 3 if not HAS_PSUTIL else max( 1 * 1024 ** 3, psutil.virtual_memory().total // 16), + + # Any path that matches here will only be opened by a source that matches + # extension or mime type. + 'all_sources_ignored_names': r'(\.mrxs|\.vsi)$', } diff --git a/large_image/tilesource/__init__.py b/large_image/tilesource/__init__.py index 795bb30e8..1d2eec26b 100644 --- a/large_image/tilesource/__init__.py +++ b/large_image/tilesource/__init__.py @@ -88,6 +88,9 @@ def getSortedSourceList( '_geospatial_source': isGeospatial(pathOrUri), } isNew = str(pathOrUri).startswith(NEW_IMAGE_PATH_FLAG) + ignored_names = config.getConfig('all_sources_ignored_names') + ignoreName = (ignored_names and re.search( + ignored_names, os.path.basename(str(pathOrUri)), flags=re.IGNORECASE)) sourceList = [] for sourceName in availableSources: sourceExtensions = availableSources[sourceName].extensions @@ -109,7 +112,7 @@ def getSortedSourceList( fallback = False if isLargeImageUri and sourceName == uriWithoutProtocol: priority = SourcePriority.NAMED - if priority >= SourcePriority.MANUAL: + if priority >= SourcePriority.MANUAL or (ignoreName and fallback): continue propertiesClash = any( getattr(availableSources[sourceName], k, False) != v diff --git a/test/lisource_compare.py b/test/lisource_compare.py index cb90fe636..b2d0deb42 100755 --- a/test/lisource_compare.py +++ b/test/lisource_compare.py @@ -533,6 +533,7 @@ def command(): for key in list(large_image.config.ConfigValues): if '_ignored_names' in key: del large_image.config.ConfigValues[key] + large_image.config.ConfigValues.pop('all_sources_ignored_names', None) main(opts)