Skip to content

Commit e6f0fc9

Browse files
committed
#4802 Handle KDU crashes
1 parent 29335d2 commit e6f0fc9

1 file changed

Lines changed: 75 additions & 4 deletions

File tree

indra/llkdu/llimagej2ckdu.cpp

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ class LLKDUDecodeState
174174
kdu_tile mTile;
175175
kdu_byte *mBuf;
176176
S32 mRowGap;
177+
178+
// wrappers
179+
bool kduPullSafe(kdu_pull_ifc& engine, kdu_line_buf& line);
180+
bool kduConvertYccSafe(kdu_line_buf& line0, kdu_line_buf& line1, kdu_line_buf& line2);
181+
177182
};
178183

179184
// Stuff for new kdu error handling
@@ -282,10 +287,16 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
282287

283288
try
284289
{
285-
286290
S32 data_size = base.getDataSize();
287291
S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
288292

293+
// Data sanity checks
294+
// 0 data size appears to be valid.
295+
if (data_size < 0 || data_size > 128 * 1024 * 1024) // 128MB
296+
{
297+
LLTHROW(KDUError(STRINGIZE("Invalid data size: " << data_size)));
298+
}
299+
289300
//
290301
// Initialization
291302
//
@@ -385,7 +396,8 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
385396
catch (std::bad_alloc&)
386397
{
387398
// we are in a thread, can't show an 'out of memory' here,
388-
// main thread will keep going
399+
// as main thread will keep going
400+
// Todo: should cause main thread to stop and show an error.
389401
throw;
390402
}
391403
catch (...)
@@ -1302,6 +1314,11 @@ all necessary level shifting, type conversion, rounding and truncation. */
13021314
LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap,
13031315
kdu_codestream* codestreamp)
13041316
{
1317+
if (!buf)
1318+
{
1319+
LLTHROW(KDUError("Null buffer passed to LLKDUDecodeState"));
1320+
}
1321+
13051322
S32 c;
13061323

13071324
mTile = tile;
@@ -1311,6 +1328,11 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap,
13111328
mNumComponents = tile.get_num_components();
13121329

13131330
llassert(mNumComponents <= 4);
1331+
if (mNumComponents <= 0 || mNumComponents > 4)
1332+
{
1333+
LL_WARNS() << "Invalid component count: " << mNumComponents << ", clamping to valid range" << LL_ENDL;
1334+
mNumComponents = llclamp(mNumComponents, 1, 4);
1335+
}
13141336
mUseYCC = tile.get_ycc();
13151337

13161338
for (c = 0; c < 4; ++c)
@@ -1383,14 +1405,27 @@ separation between consecutive rows in the real buffer. */
13831405
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - pull");
13841406
for (c = 0; c < mNumComponents; c++)
13851407
{
1386-
mEngines[c].pull(mLines[c]);
1408+
if (!kduPullSafe(mEngines[c], mLines[c]))
1409+
{
1410+
std::string error_message = "kdu's pull failed for component " +
1411+
std::to_string(c) + " at position " +
1412+
std::to_string(mTile.get_tile_idx().x) + "," + std::to_string(mTile.get_tile_idx().y);
1413+
LLTHROW(KDUError(error_message));
1414+
return false;
1415+
}
13871416
}
13881417
}
13891418

13901419
if ((mNumComponents >= 3) && mUseYCC)
13911420
{
13921421
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("kduptc - convert");
1393-
kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]);
1422+
if (!kduConvertYccSafe(mLines[0], mLines[1], mLines[2]))
1423+
{
1424+
std::string error_message = "kdu_convert_ycc_to_rgb() failed for tile at position " +
1425+
std::to_string(mTile.get_tile_idx().x) + "," + std::to_string(mTile.get_tile_idx().y);
1426+
LLTHROW(KDUError(error_message));
1427+
return false;
1428+
}
13941429
}
13951430

13961431
{
@@ -1412,6 +1447,42 @@ separation between consecutive rows in the real buffer. */
14121447
return true;
14131448
}
14141449

1450+
bool LLKDUDecodeState::kduPullSafe(kdu_pull_ifc& engine, kdu_line_buf& line)
1451+
{
1452+
#ifdef LL_WINDOWS
1453+
__try
1454+
{
1455+
engine.pull(line);
1456+
return true;
1457+
}
1458+
__except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
1459+
{
1460+
return false;
1461+
}
1462+
#else
1463+
engine.pull(line);
1464+
return true;
1465+
#endif
1466+
}
1467+
1468+
bool LLKDUDecodeState::kduConvertYccSafe(kdu_line_buf& line0, kdu_line_buf& line1, kdu_line_buf& line2)
1469+
{
1470+
#ifdef LL_WINDOWS
1471+
__try
1472+
{
1473+
kdu_convert_ycc_to_rgb(line0, line1, line2);
1474+
return true;
1475+
}
1476+
__except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
1477+
{
1478+
return false;
1479+
}
1480+
#else
1481+
kdu_convert_ycc_to_rgb(line0, line1, line2);
1482+
return true;
1483+
#endif
1484+
}
1485+
14151486
// kdc_flow_control
14161487

14171488
kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_codestream codestream)

0 commit comments

Comments
 (0)