Skip to content

Commit d684e45

Browse files
kthurstoncary-ilm
andauthored
Add check to avoid overflow, add tests for reading / writing many channels (#2525)
Signed-off-by: Kimball Thurston <kthurston@wetafx.co.nz> Co-authored-by: Cary Phillips <cary@ilm.com>
1 parent 1dd2da1 commit d684e45

3 files changed

Lines changed: 81 additions & 4 deletions

File tree

src/lib/OpenEXRCore/channel_list.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,17 @@ exr_attr_chlist_add_with_length (
173173

174174
if (newcount > clist->num_alloced)
175175
{
176-
int nsz = clist->num_alloced * 2;
176+
int nsz;
177+
178+
/* perhaps an arbitrary limit, but that is a LOT of channels */
179+
if (clist->num_alloced >= (INT32_MAX / 2))
180+
{
181+
exr_attr_string_destroy (ctxt, &(nent.name));
182+
return ctxt->standard_error (ctxt, EXR_ERR_OUT_OF_MEMORY);
183+
}
184+
185+
nsz = clist->num_alloced * 2;
186+
177187
if (newcount > nsz) nsz = newcount + 1;
178188
nlist = (exr_attr_chlist_entry_t*) ctxt->alloc_fn (
179189
sizeof (*nlist) * (size_t) nsz);

src/test/OpenEXRCoreTest/general_attr.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,22 @@ testChlistHelper (exr_context_t f)
803803

804804
// make sure we can re-delete something?
805805
EXRCORE_TEST_RVAL (exr_attr_chlist_destroy (f, &cl));
806+
807+
for ( int curc = 0; curc < 384; ++curc )
808+
{
809+
char cname[32];
810+
/* use zero pad to avoid dealing with lexical ordering of channels */
811+
snprintf (cname, 32, "c%03d", curc);
812+
EXRCORE_TEST_RVAL (exr_attr_chlist_add (
813+
f, &cl, cname, EXR_PIXEL_HALF, EXR_PERCEPTUALLY_LINEAR, 1, 2));
814+
EXRCORE_TEST (cl.num_channels == (curc + 1));
815+
EXRCORE_TEST (0 == strcmp (cl.entries[curc].name.str, cname));
816+
EXRCORE_TEST (cl.entries[curc].pixel_type == EXR_PIXEL_HALF);
817+
EXRCORE_TEST (cl.entries[curc].p_linear == (uint8_t) EXR_PERCEPTUALLY_LINEAR);
818+
EXRCORE_TEST (cl.entries[curc].x_sampling == 1);
819+
EXRCORE_TEST (cl.entries[curc].y_sampling == 2);
820+
}
821+
EXRCORE_TEST_RVAL (exr_attr_chlist_destroy (f, &cl));
806822
}
807823

808824
void

src/test/OpenEXRTest/testChannels.cpp

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ writeRead (
4545
const Array2D<half>& h2out,
4646
const char fileName[],
4747
int width,
48-
int height)
48+
int height,
49+
bool manyC)
4950
{
5051
//
5152
// Write an image file with three channels, H1, H2 and H3.
@@ -78,6 +79,17 @@ writeRead (
7879
1, // xSampling
7980
1) // ySampling
8081
);
82+
if (manyC)
83+
{
84+
for ( int curc = 0; curc < 132; ++curc )
85+
{
86+
char cname[32];
87+
snprintf (cname, 32, "c%03d", curc);
88+
hdr.channels ().insert (
89+
cname,
90+
Channel (HALF, 1, 1));
91+
}
92+
}
8193

8294
{
8395
FrameBuffer fb;
@@ -104,7 +116,10 @@ writeRead (
104116
1) // ySampling
105117
);
106118

107-
cout << "writing" << flush;
119+
if (manyC)
120+
cout << "Many Channels: writing" << flush;
121+
else
122+
cout << "Values: writing" << flush;
108123

109124
remove (fileName);
110125
OutputFile out (fileName, hdr);
@@ -213,6 +228,41 @@ writeRead (
213228
assert (h4in[y][x] == 3.0);
214229
}
215230
}
231+
232+
if (manyC)
233+
{
234+
for ( int curc = 0; curc < 132; ++curc )
235+
{
236+
char cname[32];
237+
snprintf (cname, 32, "c%03d", curc);
238+
239+
cout << " " << curc << flush;
240+
Array2D<half> testcin (h, w);
241+
242+
FrameBuffer fb;
243+
244+
/* if the channel isn't there, will fill with 3 but we should have 0 */
245+
fb.insert (
246+
cname, // name
247+
Slice (
248+
HALF, // type
249+
(char*) &testcin[-dy][-dx], // base
250+
sizeof (testcin[0][0]), // xStride
251+
sizeof (testcin[0][0]) * w, // yStride
252+
1, 1, 3.0)
253+
);
254+
255+
in.setFrameBuffer (fb);
256+
in.readPixels (dw.min.y, dw.max.y);
257+
for (int y = 0; y < h; ++y)
258+
{
259+
for (int x = 0; x < w; ++x)
260+
{
261+
assert (testcin[y][x] == 0.0);
262+
}
263+
}
264+
}
265+
}
216266
}
217267

218268
remove (fileName);
@@ -306,7 +356,8 @@ testChannels (const std::string& tempDir)
306356

307357
std::string filename = tempDir + "imf_test_channels.exr";
308358

309-
writeRead (ph1, ph2, filename.c_str (), W, H);
359+
writeRead (ph1, ph2, filename.c_str (), W, H, false);
360+
writeRead (ph1, ph2, filename.c_str (), W, H, true);
310361

311362
cout << "ok\n" << endl;
312363
}

0 commit comments

Comments
 (0)