aboutsummaryrefslogtreecommitdiff
path: root/projects/openexr
diff options
context:
space:
mode:
authorMichael Jezierny <michael@alsophian.net>2020-07-07 14:28:37 -0700
committerGitHub <noreply@github.com>2020-07-07 14:28:37 -0700
commitc8279e2c2d1c16c15c8ffc1663308db61811c5ae (patch)
tree6ed27d29d1d6d10aa1071ffd56693cc88e6a3fb6 /projects/openexr
parent2c664877af692dbffbf553e66d0c685d028eb8b0 (diff)
downloadoss-fuzz-c8279e2c2d1c16c15c8ffc1663308db61811c5ae.tar.gz
[openexr] Initial integration of OpenEXR fuzzers. (#4060)
* Add a working skeleton for OpenEXR fuzzers. * added openexr fuzzers, updated build script to include them * cleaned up bash loop * replace "/work" with in build.sh * Reformat CMake settings, and also prevent building utils and examples. * Reformat and change names in build.sh. * Omit the version prefix when building OpenEXR and IlmBase libraries. * Correct the contact addresses for OpenEXR. Co-authored-by: Ravi Jotwani <rjotwani@google.com>
Diffstat (limited to 'projects/openexr')
-rw-r--r--projects/openexr/Dockerfile21
-rwxr-xr-xprojects/openexr/build.sh53
-rw-r--r--projects/openexr/openexr_deepscanlines_fuzzer.cc185
-rw-r--r--projects/openexr/openexr_deeptiles_fuzzer.cc196
-rw-r--r--projects/openexr/openexr_scanlines_fuzzer.cc132
-rw-r--r--projects/openexr/openexr_tiles_fuzzer.cc196
-rw-r--r--projects/openexr/project.yaml5
7 files changed, 788 insertions, 0 deletions
diff --git a/projects/openexr/Dockerfile b/projects/openexr/Dockerfile
new file mode 100644
index 000000000..d8c4d5e13
--- /dev/null
+++ b/projects/openexr/Dockerfile
@@ -0,0 +1,21 @@
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+RUN apt-get update && apt-get install -y make autoconf automake libtool zlib1g-dev
+RUN git clone --depth 1 https://github.com/AcademySoftwareFoundation/openexr openexr
+WORKDIR openexr
+COPY build.sh openexr_deepscanlines_fuzzer.cc openexr_deeptiles_fuzzer.cc openexr_scanlines_fuzzer.cc openexr_tiles_fuzzer.cc $SRC/
diff --git a/projects/openexr/build.sh b/projects/openexr/build.sh
new file mode 100755
index 000000000..fa63c2a4e
--- /dev/null
+++ b/projects/openexr/build.sh
@@ -0,0 +1,53 @@
+#!/bin/bash -eu
+# Copyright 2020 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# 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.
+#
+################################################################################
+
+cd $WORK/
+
+CMAKE_SETTINGS=(
+ "-D BUILD_SHARED_LIBS=OFF" # Build static libraries only
+ "-D PYILMBASE_ENABLE=OFF" # Don't build Python support
+ "-D BUILD_TESTING=OFF" # Or tests
+ "-D OPENEXR_BUILD_UTILS=OFF" # Or utilities
+ "-D INSTALL_OPENEXR_EXAMPLES=OFF" # Or examples
+ "-D OPENEXR_LIB_SUFFIX=" # Don't append the version number to library files
+ "-D ILMBASE_LIB_SUFFIX="
+)
+cmake $SRC/openexr ${CMAKE_SETTINGS[@]}
+make -j$(nproc)
+
+INCLUDES=(
+ "-I $SRC/openexr/OpenEXR/IlmImf"
+ "-I $SRC/openexr/IlmBase/Imath"
+ "-I $SRC/openexr/IlmBase/Iex"
+ "-I $SRC/openexr/IlmBase/Half"
+ "-I $WORK/OpenEXR/config"
+ "-I $WORK/IlmBase/config"
+)
+
+LIBS=(
+ "$WORK/OpenEXR/IlmImf/libIlmImf.a"
+ "$WORK/IlmBase/Iex/libIex.a"
+ "$WORK/IlmBase/Half/libHalf.a"
+ "$WORK/IlmBase/IlmThread/libIlmThread.a"
+ "$WORK/IlmBase/Imath/libImath.a"
+)
+
+for fuzzer in $SRC/*_fuzzer.cc; do
+ fuzzer_basename=$(basename -s .cc $fuzzer)
+ $CXX $CXXFLAGS -std=c++11 -pthread ${INCLUDES[@]} $fuzzer $LIB_FUZZING_ENGINE ${LIBS[@]} -lz \
+ -o $OUT/$fuzzer_basename
+done
diff --git a/projects/openexr/openexr_deepscanlines_fuzzer.cc b/projects/openexr/openexr_deepscanlines_fuzzer.cc
new file mode 100644
index 000000000..9682dea0f
--- /dev/null
+++ b/projects/openexr/openexr_deepscanlines_fuzzer.cc
@@ -0,0 +1,185 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// 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 <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vector>
+
+#include <ImfArray.h>
+#include <ImfChannelList.h>
+#include <ImfDeepFrameBuffer.h>
+#include <ImfDeepScanLineInputPart.h>
+#include <ImfMultiPartInputFile.h>
+#include <ImfNamespace.h>
+
+namespace IMF = OPENEXR_IMF_NAMESPACE;
+using namespace IMF;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+
+namespace {
+
+const int width = 90;
+const int height = 80;
+const int minX = 10;
+const int minY = 11;
+const Box2i dataWindow(V2i(minX, minY),
+ V2i(minX + width - 1, minY + height - 1));
+const Box2i displayWindow(V2i(0, 0), V2i(minX + width * 2, minY + height * 2));
+
+template <typename T>
+static void readFile(T *inpart) {
+ const Header &fileHeader = inpart->header();
+
+ int channelCount = 0;
+ for (ChannelList::ConstIterator i = fileHeader.channels().begin();
+ i != fileHeader.channels().end(); ++i, ++channelCount) {
+ }
+
+ Array2D<unsigned int> localSampleCount;
+ localSampleCount.resizeErase(height, width);
+ Array<Array2D<void *> > data(channelCount);
+
+ for (int i = 0; i < channelCount; i++) data[i].resizeErase(height, width);
+
+ DeepFrameBuffer frameBuffer;
+
+ frameBuffer.insertSampleCountSlice(
+ Slice(IMF::UINT,
+ (char *)(&localSampleCount[0][0] - dataWindow.min.x -
+ dataWindow.min.y * width),
+ sizeof(unsigned int) * 1, sizeof(unsigned int) * width));
+
+ std::vector<int> read_channel(channelCount);
+
+ for (int i = 0; i < channelCount; i++) {
+ PixelType type = IMF::FLOAT;
+
+ std::stringstream ss;
+ ss << i;
+ std::string str = ss.str();
+
+ int sampleSize = sizeof(float);
+
+ int pointerSize = sizeof(char *);
+
+ frameBuffer.insert(
+ str, DeepSlice(type,
+ (char *)(&data[i][0][0] - dataWindow.min.x -
+ dataWindow.min.y * width),
+ pointerSize * 1, pointerSize * width, sampleSize));
+ }
+
+ inpart->setFrameBuffer(frameBuffer);
+ inpart->readPixelSampleCounts(dataWindow.min.y, dataWindow.max.y);
+ for (int i = 0; i < dataWindow.max.y - dataWindow.min.y + 1; i++) {
+ int y = i + dataWindow.min.y;
+
+ for (int j = 0; j < width; j++) {
+ for (int k = 0; k < channelCount; k++) {
+ data[k][i][j] = new float[localSampleCount[i][j]];
+ }
+ }
+ }
+ try {
+ inpart->readPixels(dataWindow.min.y, dataWindow.max.y);
+ } catch (...) {
+ }
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ for (int k = 0; k < channelCount; k++) {
+ delete[](float *) data[k][i][j];
+ }
+ }
+ }
+}
+
+static void readFileSingle(const char filename[]) {
+ DeepScanLineInputFile *file = NULL;
+ try {
+ file = new DeepScanLineInputFile(filename, 0);
+ } catch (...) {
+ return;
+ }
+
+ try {
+ readFile(file);
+ } catch (std::exception &e) {
+ }
+
+ delete file;
+}
+
+static void readFileMulti(const char filename[]) {
+ MultiPartInputFile *file = NULL;
+ try {
+ file = new MultiPartInputFile(filename, 0);
+ } catch (...) {
+ return;
+ }
+
+ for (int p = 0; p < file->parts(); p++) {
+ DeepScanLineInputPart *inpart = NULL;
+ try {
+ inpart = new DeepScanLineInputPart(*file, p);
+ } catch (...) {
+ continue;
+ }
+ try {
+ readFile(inpart);
+ } catch (std::exception &e) {
+ }
+ delete inpart;
+ }
+
+ delete file;
+}
+
+} // namespace
+
+// from cl/164883104
+static char *buf_to_file(const char *buf, size_t size) {
+ char *name = strdup("/dev/shm/fuzz-XXXXXX");
+ int fd = mkstemp(name);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ size_t pos = 0;
+ while (pos < size) {
+ int nbytes = write(fd, &buf[pos], size - pos);
+ if (nbytes <= 0) {
+ perror("write");
+ exit(1);
+ }
+ pos += nbytes;
+ }
+ if (close(fd) != 0) {
+ perror("close");
+ exit(1);
+ }
+ return name;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ char *file = buf_to_file((const char *)data, size);
+ readFileSingle(file);
+ readFileMulti(file);
+ unlink(file);
+ free(file);
+ return 0;
+}
diff --git a/projects/openexr/openexr_deeptiles_fuzzer.cc b/projects/openexr/openexr_deeptiles_fuzzer.cc
new file mode 100644
index 000000000..4a51be115
--- /dev/null
+++ b/projects/openexr/openexr_deeptiles_fuzzer.cc
@@ -0,0 +1,196 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// 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 <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <ImfArray.h>
+#include <ImfChannelList.h>
+#include <ImfDeepTiledInputFile.h>
+#include <ImfDeepTiledInputPart.h>
+#include <ImfTiledInputPart.h>
+
+namespace IMF = OPENEXR_IMF_NAMESPACE;
+using namespace IMF;
+using IMATH_NAMESPACE::Box2i;
+
+namespace {
+
+template <typename T>
+static void readFile(T *part) {
+ const Header &fileHeader = part->header();
+
+ Array2D<unsigned int> localSampleCount;
+
+ Box2i dataWindow = fileHeader.dataWindow();
+
+ int height = dataWindow.size().y + 1;
+ int width = dataWindow.size().x + 1;
+
+ localSampleCount.resizeErase(height, width);
+
+ int channelCount = 0;
+ for (ChannelList::ConstIterator i = fileHeader.channels().begin();
+ i != fileHeader.channels().end(); ++i, channelCount++) {
+ }
+
+ Array<Array2D<void *> > data(channelCount);
+
+ for (int i = 0; i < channelCount; i++) {
+ data[i].resizeErase(height, width);
+ }
+
+ DeepFrameBuffer frameBuffer;
+
+ int memOffset = dataWindow.min.x + dataWindow.min.y * width;
+ frameBuffer.insertSampleCountSlice(
+ Slice(IMF::UINT, (char *)(&localSampleCount[0][0] - memOffset),
+ sizeof(unsigned int) * 1, sizeof(unsigned int) * width));
+
+ for (int i = 0; i < channelCount; i++) {
+ std::stringstream ss;
+ ss << i;
+ std::string str = ss.str();
+
+ int sampleSize = sizeof(float);
+
+ int pointerSize = sizeof(char *);
+
+ frameBuffer.insert(
+ str, DeepSlice(IMF::FLOAT, (char *)(&data[i][0][0] - memOffset),
+ pointerSize * 1, pointerSize * width, sampleSize));
+ }
+
+ part->setFrameBuffer(frameBuffer);
+ for (int ly = 0; ly < part->numYLevels(); ly++) {
+ for (int lx = 0; lx < part->numXLevels(); lx++) {
+ Box2i dataWindowL = part->dataWindowForLevel(lx, ly);
+
+ part->readPixelSampleCounts(0, part->numXTiles(lx) - 1, 0,
+ part->numYTiles(ly) - 1, lx, ly);
+
+ for (int i = 0; i < part->numYTiles(ly); i++) {
+ for (int j = 0; j < part->numXTiles(lx); j++) {
+ Box2i box = part->dataWindowForTile(j, i, lx, ly);
+ for (int y = box.min.y; y <= box.max.y; y++)
+ for (int x = box.min.x; x <= box.max.x; x++) {
+ int dwy = y - dataWindowL.min.y;
+ int dwx = x - dataWindowL.min.x;
+
+ for (int k = 0; k < channelCount; k++) {
+ data[k][dwy][dwx] = new float[localSampleCount[dwy][dwx]];
+ }
+ }
+ }
+ }
+
+ try {
+ part->readTiles(0, part->numXTiles(lx) - 1, 0, part->numYTiles(ly) - 1,
+ lx, ly);
+ } catch (...) {
+ }
+
+ for (int i = 0; i < part->levelHeight(ly); i++) {
+ for (int j = 0; j < part->levelWidth(lx); j++) {
+ for (int k = 0; k < channelCount; k++) {
+ delete[](float *) data[k][i][j];
+ }
+ }
+ }
+ }
+ }
+}
+
+static void readFileSingle(const char filename[]) {
+ DeepTiledInputFile *file;
+ try {
+ file = new DeepTiledInputFile(filename, 8);
+ } catch (...) {
+ return;
+ }
+
+ try {
+ readFile(file);
+ } catch (std::exception &e) {
+ }
+
+ delete file;
+}
+
+static void readFileMulti(const char filename[]) {
+ MultiPartInputFile *file;
+
+ try {
+ file = new MultiPartInputFile(filename, 8);
+ } catch (...) {
+ return;
+ }
+
+ for (int p = 0; p < file->parts(); p++) {
+ DeepTiledInputPart *part;
+ try {
+ part = new DeepTiledInputPart(*file, p);
+ } catch (...) {
+ continue;
+ }
+
+ try {
+ readFile(part);
+ } catch (...) {
+ }
+
+ delete part;
+ }
+
+ delete file;
+}
+
+} // namespace
+
+// from cl/164883104
+static char *buf_to_file(const char *buf, size_t size) {
+ char *name = strdup("/dev/shm/fuzz-XXXXXX");
+ int fd = mkstemp(name);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ size_t pos = 0;
+ while (pos < size) {
+ int nbytes = write(fd, &buf[pos], size - pos);
+ if (nbytes <= 0) {
+ perror("write");
+ exit(1);
+ }
+ pos += nbytes;
+ }
+ if (close(fd) != 0) {
+ perror("close");
+ exit(1);
+ }
+ return name;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ char *file = buf_to_file((const char *)data, size);
+ Header::setMaxImageSize(10000, 10000);
+ readFileSingle(file);
+ readFileMulti(file);
+ unlink(file);
+ free(file);
+ return 0;
+}
diff --git a/projects/openexr/openexr_scanlines_fuzzer.cc b/projects/openexr/openexr_scanlines_fuzzer.cc
new file mode 100644
index 000000000..214b595d8
--- /dev/null
+++ b/projects/openexr/openexr_scanlines_fuzzer.cc
@@ -0,0 +1,132 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// 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 <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <ImfArray.h>
+#include <ImfInputPart.h>
+#include <ImfMultiPartInputFile.h>
+#include <ImfRgbaFile.h>
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
+using IMATH_NAMESPACE::Box2i;
+
+namespace {
+
+static void readSingle(const char fileName[]) {
+ RgbaInputFile *in = NULL;
+ try {
+ in = new RgbaInputFile(fileName);
+ } catch (...) {
+ return;
+ }
+
+ try {
+ const Box2i &dw = in->dataWindow();
+
+ int w = dw.max.x - dw.min.x + 1;
+ int dx = dw.min.x;
+
+ if (w > (1 << 24)) return;
+
+ Array<Rgba> pixels(w);
+ in->setFrameBuffer(&pixels[-dx], 1, 0);
+
+ for (int y = dw.min.y; y <= dw.max.y; ++y) in->readPixels(y);
+ } catch (...) {
+ }
+
+ delete in;
+}
+
+static void readMulti(const char fileName[]) {
+ MultiPartInputFile *file;
+ try {
+ file = new MultiPartInputFile(fileName);
+ } catch (...) {
+ return;
+ }
+
+ for (int p = 0; p < file->parts(); p++) {
+ InputPart *in;
+ try {
+ in = new InputPart(*file, p);
+ } catch (...) {
+ continue;
+ }
+
+ try {
+ const Box2i &dw = in->header().dataWindow();
+
+ int w = dw.max.x - dw.min.x + 1;
+ int dx = dw.min.x;
+
+ if (w > (1 << 24)) return;
+
+ Array<Rgba> pixels(w);
+ FrameBuffer i;
+ i.insert("R", Slice(HALF, (char *)&(pixels[-dx].r), sizeof(Rgba), 0));
+ i.insert("G", Slice(HALF, (char *)&(pixels[-dx].g), sizeof(Rgba), 0));
+ i.insert("B", Slice(HALF, (char *)&(pixels[-dx].b), sizeof(Rgba), 0));
+ i.insert("A", Slice(HALF, (char *)&(pixels[-dx].a), sizeof(Rgba), 0));
+
+ in->setFrameBuffer(i);
+ for (int y = dw.min.y; y <= dw.max.y; ++y) in->readPixels(y);
+ } catch (...) {
+ }
+
+ delete in;
+ }
+
+ delete file;
+}
+
+} // namespace
+
+// from cl/164883104
+static char *buf_to_file(const char *buf, size_t size) {
+ char *name = strdup("/dev/shm/fuzz-XXXXXX");
+ int fd = mkstemp(name);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ size_t pos = 0;
+ while (pos < size) {
+ int nbytes = write(fd, &buf[pos], size - pos);
+ if (nbytes <= 0) {
+ perror("write");
+ exit(1);
+ }
+ pos += nbytes;
+ }
+ if (close(fd) != 0) {
+ perror("close");
+ exit(1);
+ }
+ return name;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ char *file = buf_to_file((const char *)data, size);
+ readSingle(file);
+ readMulti(file);
+ unlink(file);
+ free(file);
+ return 0;
+}
diff --git a/projects/openexr/openexr_tiles_fuzzer.cc b/projects/openexr/openexr_tiles_fuzzer.cc
new file mode 100644
index 000000000..2cc8ccd7a
--- /dev/null
+++ b/projects/openexr/openexr_tiles_fuzzer.cc
@@ -0,0 +1,196 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// 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 <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <ImfArray.h>
+#include <ImfTiledRgbaFile.h>
+
+// Handle the case when the custom namespace is not exposed
+#include <ImfChannelList.h>
+#include <ImfMultiPartInputFile.h>
+#include <ImfMultiPartOutputFile.h>
+#include <ImfPartType.h>
+#include <ImfTiledInputPart.h>
+#include <ImfTiledOutputPart.h>
+#include <OpenEXRConfig.h>
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
+using IMATH_NAMESPACE::Box2i;
+
+namespace {
+
+void readImageONE(TiledRgbaInputFile *in, int dwx, int dwy) {
+ try {
+ const Box2i &dw = in->dataWindow();
+
+ int w = dw.max.x - dw.min.x + 1;
+ int h = dw.max.y - dw.min.y + 1;
+
+ Array2D<Rgba> pixels(h, w);
+ in->setFrameBuffer(&pixels[-dwy][-dwx], 1, w);
+ in->readTiles(0, in->numXTiles() - 1, 0, in->numYTiles() - 1);
+ } catch (...) {
+ }
+}
+
+void readImageONE2(const char fileName[]) {
+ MultiPartInputFile *in;
+ try {
+ in = new MultiPartInputFile(fileName);
+ } catch (...) {
+ return;
+ }
+
+ TiledInputPart *inpart;
+ try {
+ for (int p = 0; p < in->parts(); p++) {
+ try {
+ inpart = new TiledInputPart(*in, p);
+ } catch (...) {
+ inpart = NULL;
+ continue;
+ }
+
+ const Box2i &dw = inpart->header().dataWindow();
+
+ int w = dw.max.x - dw.min.x + 1;
+ int h = dw.max.y - dw.min.y + 1;
+ int dwx = dw.min.x;
+ int dwy = dw.min.y;
+
+ Array2D<Rgba> pixels(h, w);
+ FrameBuffer i;
+ i.insert("R", Slice(HALF, (char *)&(pixels[-dwy][-dwx].r), sizeof(Rgba),
+ w * sizeof(Rgba)));
+ i.insert("G", Slice(HALF, (char *)&(pixels[-dwy][-dwx].g), sizeof(Rgba),
+ w * sizeof(Rgba)));
+ i.insert("B", Slice(HALF, (char *)&(pixels[-dwy][-dwx].b), sizeof(Rgba),
+ w * sizeof(Rgba)));
+ i.insert("A", Slice(HALF, (char *)&(pixels[-dwy][-dwx].a), sizeof(Rgba),
+ w * sizeof(Rgba)));
+
+ inpart->setFrameBuffer(i);
+ inpart->readTiles(0, inpart->numXTiles() - 1, 0, inpart->numYTiles() - 1);
+
+ delete inpart;
+ inpart = NULL;
+ }
+ } catch (...) {
+ delete inpart;
+ }
+
+ delete in;
+}
+
+void readImageMIP(TiledRgbaInputFile *in, int dwx, int dwy) {
+ try {
+ int numLevels = in->numLevels();
+ Array<Array2D<Rgba> > levels2(numLevels);
+
+ for (int level = 0; level < numLevels; ++level) {
+ int levelWidth = in->levelWidth(level);
+ int levelHeight = in->levelHeight(level);
+ levels2[level].resizeErase(levelHeight, levelWidth);
+
+ in->setFrameBuffer(&(levels2[level])[-dwy][-dwx], 1, levelWidth);
+ in->readTiles(0, in->numXTiles(level) - 1, 0, in->numYTiles(level) - 1,
+ level);
+ }
+ } catch (...) {
+ }
+}
+
+void readImageRIP(TiledRgbaInputFile *in, int dwx, int dwy) {
+ try {
+ int numXLevels = in->numXLevels();
+ int numYLevels = in->numYLevels();
+ Array2D<Array2D<Rgba> > levels2(numYLevels, numXLevels);
+
+ for (int ylevel = 0; ylevel < numYLevels; ++ylevel) {
+ for (int xlevel = 0; xlevel < numXLevels; ++xlevel) {
+ int levelWidth = in->levelWidth(xlevel);
+ int levelHeight = in->levelHeight(ylevel);
+ levels2[ylevel][xlevel].resizeErase(levelHeight, levelWidth);
+ in->setFrameBuffer(&(levels2[ylevel][xlevel])[-dwy][-dwx], 1,
+ levelWidth);
+
+ in->readTiles(0, in->numXTiles(xlevel) - 1, 0,
+ in->numYTiles(ylevel) - 1, xlevel, ylevel);
+ }
+ }
+ } catch (...) {
+ }
+}
+
+} // namespace
+
+static void fuzzImage(const char filename[]) {
+ Header::setMaxImageSize(10000, 10000);
+ Header::setMaxTileSize(10000, 10000);
+
+ TiledRgbaInputFile *in;
+ try {
+ in = new TiledRgbaInputFile(filename);
+ } catch (...) {
+ return;
+ }
+
+ const Box2i &dw = in->dataWindow();
+ int dwx = dw.min.x;
+ int dwy = dw.min.y;
+
+ readImageMIP(in, dwx, dwy);
+ readImageRIP(in, dwx, dwy);
+ readImageONE(in, dwx, dwy);
+ readImageONE2(filename);
+
+ delete in;
+}
+
+// from cl/164883104
+static char *buf_to_file(const char *buf, size_t size) {
+ char *name = strdup("/dev/shm/fuzz-XXXXXX");
+ int fd = mkstemp(name);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ size_t pos = 0;
+ while (pos < size) {
+ int nbytes = write(fd, &buf[pos], size - pos);
+ if (nbytes <= 0) {
+ perror("write");
+ exit(1);
+ }
+ pos += nbytes;
+ }
+ if (close(fd) != 0) {
+ perror("close");
+ exit(1);
+ }
+ return name;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ char *file = buf_to_file((const char *)data, size);
+ fuzzImage(file);
+ unlink(file);
+ free(file);
+ return 0;
+}
diff --git a/projects/openexr/project.yaml b/projects/openexr/project.yaml
new file mode 100644
index 000000000..79ab21ee0
--- /dev/null
+++ b/projects/openexr/project.yaml
@@ -0,0 +1,5 @@
+homepage: "https://openexr.com"
+language: c++
+primary_contact: "twodeecoda@gmail.com"
+auto_ccs:
+ - "cbpilm@gmail.com"