@@ -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. */
13021314LLKDUDecodeState::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
14171488kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_codestream codestream)
0 commit comments