From e3aa152edd5cce142c1e841572e65d94a62a42c8 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Thu, 5 Dec 2024 12:50:31 -0800 Subject: [PATCH] api: Add global attribute `imageinput:strict` We don't do anything with this at the present time, but this PR reserves and documents this attribute for future use. The intent is to be able to set whether we want image readers to try being as tolerant as possible when reading a file with flaws (press on and see if the rest of the file is ok?), or be more conservative and abandon reading any file as soon as a corruption or invalid data is encountered (because that might be a clue that the file is arbitrarily corrupted or even maliciously constructed). I documented it as defaulting to 0 (err on the side of being permissive of bad input), with high-security applications being responsible for setting it to 1. But it's open for debate of people think that a better default is to be strict and let applications who want to be more tolerant be responsible for accepting the risk and switching the mode. Signed-off-by: Larry Gritz --- src/include/OpenImageIO/imageio.h | 11 +++++++++++ src/include/imageio_pvt.h | 1 + src/libOpenImageIO/imageio.cpp | 9 +++++++++ 3 files changed, 21 insertions(+) diff --git a/src/include/OpenImageIO/imageio.h b/src/include/OpenImageIO/imageio.h index d3f1da20d8..20224e8b31 100644 --- a/src/include/OpenImageIO/imageio.h +++ b/src/include/OpenImageIO/imageio.h @@ -2981,6 +2981,17 @@ OIIO_API std::string geterror(bool clear = true); /// If nonzero, an `ImageBuf` that references a file but is not given an /// ImageCache will read the image through the default ImageCache. /// +/// - `imageinput:strict` (int: 0) +/// +/// If zero (the default), ImageInput readers will try to be very tolerant +/// of minor flaws or invalidity in image files being read, if possible just +/// skipping something erroneous it encounters in the hopes that the rest of +/// the file's data will be usable. If nonzero, anything clearly invalid in +/// the file will be understood to be a corrupt file with unreliable data at +/// best, and possibly malicious construction, and so will not attempt to +/// further decode anything in the file. This may be a better choice to +/// enable globally in an environment where security is a higher priority +/// than being tolerant of partially broken image files. OIIO_API bool attribute(string_view name, TypeDesc type, const void* val); /// Shortcut attribute() for setting a single integer. diff --git a/src/include/imageio_pvt.h b/src/include/imageio_pvt.h index c9d72438c4..a626ddeb94 100644 --- a/src/include/imageio_pvt.h +++ b/src/include/imageio_pvt.h @@ -47,6 +47,7 @@ extern int limit_channels; extern int limit_imagesize_MB; extern int imagebuf_print_uncaught_errors; extern int imagebuf_use_imagecache; +extern int imageinput_strict; extern atomic_ll IB_local_mem_current; extern atomic_ll IB_local_mem_peak; extern std::atomic IB_total_open_time; diff --git a/src/libOpenImageIO/imageio.cpp b/src/libOpenImageIO/imageio.cpp index 7d7bfc60f8..cdfd004b76 100644 --- a/src/libOpenImageIO/imageio.cpp +++ b/src/libOpenImageIO/imageio.cpp @@ -55,6 +55,7 @@ int dds_bc5normal(0); int limit_channels(1024); int limit_imagesize_MB(std::min(32 * 1024, int(Sysutil::physical_memory() >> 20))); +int imageinput_strict(0); ustring font_searchpath(Sysutil::getenv("OPENIMAGEIO_FONTS")); ustring plugin_searchpath(OIIO_DEFAULT_PLUGIN_SEARCHPATH); std::string format_list; // comma-separated list of all formats @@ -403,6 +404,10 @@ attribute(string_view name, TypeDesc type, const void* val) imagebuf_use_imagecache = *(const int*)val; return true; } + if (name == "imageinput:strict" && type == TypeInt) { + imageinput_strict = *(const int*)val; + return true; + } if (name == "use_tbb" && type == TypeInt) { oiio_use_tbb = *(const int*)val; return true; @@ -578,6 +583,10 @@ getattribute(string_view name, TypeDesc type, void* val) *(int*)val = imagebuf_use_imagecache; return true; } + if (name == "imageinput:strict" && type == TypeInt) { + *(int*)val = imageinput_strict; + return true; + } if (name == "use_tbb" && type == TypeInt) { *(int*)val = oiio_use_tbb; return true;