Optimize SampleSizeBox parsing when sample_size>0, fixes OOM oss-fuzz issue #5192805347753984
diff --git a/src/read.c b/src/read.c
index aaa4b90..697b591 100644
--- a/src/read.c
+++ b/src/read.c
@@ -181,6 +181,7 @@
     avifSampleTableSampleSizeArray sampleSizes;
     avifSampleTableTimeToSampleArray timeToSamples;
     avifSyncSampleArray syncSamples;
+    uint32_t allSamplesSize; // If this is non-zero, sampleSizes will be empty and all samples will be this size
 } avifSampleTable;
 
 static avifSampleTable * avifSampleTableCreate()
@@ -305,23 +306,26 @@
 
         uint64_t sampleOffset = chunk->offset;
         for (uint32_t sampleIndex = 0; sampleIndex < sampleCount; ++sampleIndex) {
-            if (sampleSizeIndex >= sampleTable->sampleSizes.count) {
-                // We've run out of samples to sum
-                return AVIF_FALSE;
+            uint32_t sampleSize = sampleTable->allSamplesSize;
+            if (sampleSize == 0) {
+                if (sampleSizeIndex >= sampleTable->sampleSizes.count) {
+                    // We've run out of samples to sum
+                    return AVIF_FALSE;
+                }
+                avifSampleTableSampleSize * sampleSizePtr = &sampleTable->sampleSizes.sampleSize[sampleSizeIndex];
+                sampleSize = sampleSizePtr->size;
             }
 
-            avifSampleTableSampleSize * sampleSize = &sampleTable->sampleSizes.sampleSize[sampleSizeIndex];
-
             avifSample * sample = (avifSample *)avifArrayPushPtr(&decodeInput->samples);
             sample->data.data = rawInput->data + sampleOffset;
-            sample->data.size = sampleSize->size;
+            sample->data.size = sampleSize;
             sample->sync = AVIF_FALSE; // to potentially be set to true following the outer loop
 
             if (sampleOffset > (uint64_t)rawInput->size) {
                 return AVIF_FALSE;
             }
 
-            sampleOffset += sampleSize->size;
+            sampleOffset += sampleSize;
             ++sampleSizeIndex;
         }
     }
@@ -1112,17 +1116,16 @@
 
     CHECK(avifROStreamReadAndEnforceVersion(&s, 0));
 
-    uint32_t allSamplesSize, entryCount;
+    uint32_t allSamplesSize, sampleCount;
     CHECK(avifROStreamReadU32(&s, &allSamplesSize)); // unsigned int(32) sample_size;
-    CHECK(avifROStreamReadU32(&s, &entryCount));     // unsigned int(32) entry_count;
+    CHECK(avifROStreamReadU32(&s, &sampleCount));    // unsigned int(32) sample_count;
 
-    for (uint32_t i = 0; i < entryCount; ++i) {
-        avifSampleTableSampleSize * sampleSize = (avifSampleTableSampleSize *)avifArrayPushPtr(&sampleTable->sampleSizes);
-        if (allSamplesSize == 0) {
+    if (allSamplesSize > 0) {
+        sampleTable->allSamplesSize = allSamplesSize;
+    } else {
+        for (uint32_t i = 0; i < sampleCount; ++i) {
+            avifSampleTableSampleSize * sampleSize = (avifSampleTableSampleSize *)avifArrayPushPtr(&sampleTable->sampleSizes);
             CHECK(avifROStreamReadU32(&s, &sampleSize->size)); // unsigned int(32) entry_size;
-        } else {
-            // This could be done more efficiently, memory-wise.
-            sampleSize->size = allSamplesSize;
         }
     }
     return AVIF_TRUE;