Commit 2bc3f97be for imagemagick.org
commit 2bc3f97be4b48afed6e75d92dc3b41558c5f6ba7
Author: Learner <22483432+007bsd@users.noreply.github.com>
Date: Sun May 17 21:50:54 2026 +0300
Add profile_fuzzer for raw EXIF/XMP/IPTC/ICC parsing (#8736)
* Add profile_fuzzer for raw EXIF/XMP/IPTC/ICC parsing
Drives ProfileImage() directly with attacker-controlled raw bytes,
exercising the EXIF/XMP/IPTC/ICC/8BIM/APP1/APP13 sub-parsers without
the per-format wrapper that encoder_fuzzer relies on.
* profile_fuzzer: bounds-check profile index instead of modulo; rename vars
diff --git a/oss-fuzz/profile_fuzzer.cc b/oss-fuzz/profile_fuzzer.cc
new file mode 100644
index 000000000..70d176bd4
--- /dev/null
+++ b/oss-fuzz/profile_fuzzer.cc
@@ -0,0 +1,54 @@
+/*
+ Copyright @ 2026 ImageMagick Studio LLC, a non-profit organization
+ dedicated to making software imaging solutions freely available.
+
+ You may not use this file except in compliance with the License. You may
+ obtain a copy of the License at
+
+ https://imagemagick.org/license/
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <cstdint>
+
+#include <Magick++/Blob.h>
+#include <Magick++/Image.h>
+
+#include "utils.cc"
+
+static const char *profileNames[] = {
+ "exif", "xmp", "iptc", "icc", "8bim", "app1", "app13"
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data,size_t Size)
+{
+ if (IsInvalidSize(Size,2))
+ return(0);
+
+ const unsigned int profileIndex=Data[0];
+ if (profileIndex >= sizeof(profileNames) / sizeof(*profileNames))
+ return(0);
+ const Magick::Blob blob(Data + 1, Size - 1);
+
+ try
+ {
+ Magick::Image image("16x16","white");
+ image.profile(profileNames[profileIndex],blob);
+ }
+#if defined(BUILD_MAIN)
+ catch (Magick::Exception &e)
+ {
+ std::cout << "Exception when reading profile: " << e.what() << std::endl;
+ }
+#else
+ catch (Magick::Exception)
+ {
+ }
+#endif
+ return(0);
+}