@@ -123,7 +123,7 @@ SampleTable::SampleTable(const sp<DataSource> &source)
123
123
mNumSampleSizes(0 ),
124
124
mHasTimeToSample(false ),
125
125
mTimeToSampleCount(0 ),
126
- mTimeToSample(),
126
+ mTimeToSample(NULL ),
127
127
mSampleTimeEntries(NULL ),
128
128
mCompositionTimeDeltaEntries(NULL ),
129
129
mNumCompositionTimeDeltaEntries(0 ),
@@ -132,7 +132,8 @@ SampleTable::SampleTable(const sp<DataSource> &source)
132
132
mNumSyncSamples(0 ),
133
133
mSyncSamples(NULL ),
134
134
mLastSyncSampleIndex(0 ),
135
- mSampleToChunkEntries(NULL ) {
135
+ mSampleToChunkEntries(NULL ),
136
+ mTotalSize(0 ) {
136
137
mSampleIterator = new SampleIterator (this );
137
138
}
138
139
@@ -143,6 +144,9 @@ SampleTable::~SampleTable() {
143
144
delete[] mSyncSamples ;
144
145
mSyncSamples = NULL ;
145
146
147
+ delete[] mTimeToSample ;
148
+ mTimeToSample = NULL ;
149
+
146
150
delete mCompositionDeltaLookup ;
147
151
mCompositionDeltaLookup = NULL ;
148
152
@@ -233,11 +237,43 @@ status_t SampleTable::setSampleToChunkParams(
233
237
return ERROR_MALFORMED;
234
238
}
235
239
236
- if (SIZE_MAX / sizeof (SampleToChunkEntry) <= mNumSampleToChunkOffsets )
240
+ if ((uint64_t )SIZE_MAX / sizeof (SampleToChunkEntry) <=
241
+ (uint64_t )mNumSampleToChunkOffsets ) {
242
+ ALOGE (" Sample-to-chunk table size too large." );
237
243
return ERROR_OUT_OF_RANGE;
244
+ }
245
+
246
+ mTotalSize += (uint64_t )mNumSampleToChunkOffsets *
247
+ sizeof (SampleToChunkEntry);
248
+ if (mTotalSize > kMaxTotalSize ) {
249
+ ALOGE (" Sample-to-chunk table size would make sample table too large.\n "
250
+ " Requested sample-to-chunk table size = %llu\n "
251
+ " Eventual sample table size >= %llu\n "
252
+ " Allowed sample table size = %llu\n " ,
253
+ (unsigned long long )mNumSampleToChunkOffsets *
254
+ sizeof (SampleToChunkEntry),
255
+ (unsigned long long )mTotalSize ,
256
+ (unsigned long long )kMaxTotalSize );
257
+ return ERROR_OUT_OF_RANGE;
258
+ }
238
259
239
260
mSampleToChunkEntries =
240
- new SampleToChunkEntry[mNumSampleToChunkOffsets ];
261
+ new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets ];
262
+ if (!mSampleToChunkEntries ) {
263
+ ALOGE (" Cannot allocate sample-to-chunk table with %llu entries." ,
264
+ (unsigned long long )mNumSampleToChunkOffsets );
265
+ return ERROR_OUT_OF_RANGE;
266
+ }
267
+
268
+ if (mNumSampleToChunkOffsets == 0 ) {
269
+ return OK;
270
+ }
271
+
272
+ if ((off64_t )(SIZE_MAX - 8 -
273
+ ((mNumSampleToChunkOffsets - 1 ) * sizeof (SampleToChunkEntry)))
274
+ < mSampleToChunkOffset ) {
275
+ return ERROR_MALFORMED;
276
+ }
241
277
242
278
for (uint32_t i = 0 ; i < mNumSampleToChunkOffsets ; ++i) {
243
279
uint8_t buffer[12 ];
@@ -246,8 +282,11 @@ status_t SampleTable::setSampleToChunkParams(
246
282
!= (ssize_t )sizeof (buffer)) {
247
283
return ERROR_IO;
248
284
}
249
-
250
- CHECK (U32_AT (buffer) >= 1 ); // chunk index is 1 based in the spec.
285
+ // chunk index is 1 based in the spec.
286
+ if (U32_AT (buffer) < 1 ) {
287
+ ALOGE (" b/23534160" );
288
+ return ERROR_OUT_OF_RANGE;
289
+ }
251
290
252
291
// We want the chunk index to be 0-based.
253
292
mSampleToChunkEntries [i].startChunk = U32_AT (buffer) - 1 ;
@@ -347,20 +386,41 @@ status_t SampleTable::setTimeToSampleParams(
347
386
// 2) mTimeToSampleCount is the number of entries of the time-to-sample
348
387
// table.
349
388
// 3) We hope that the table size does not exceed UINT32_MAX.
350
- ALOGE (" Error: Time-to-sample table size too large." );
389
+ ALOGE (" Time-to-sample table size too large." );
351
390
return ERROR_OUT_OF_RANGE;
352
391
}
353
392
354
393
// Note: At this point, we know that mTimeToSampleCount * 2 will not
355
394
// overflow because of the above condition.
356
- if (!mDataSource ->getVector (data_offset + 8 , &mTimeToSample ,
357
- mTimeToSampleCount * 2 )) {
358
- ALOGE (" Error: Incomplete data read for time-to-sample table." );
395
+
396
+ uint64_t allocSize = (uint64_t )mTimeToSampleCount * 2 * sizeof (uint32_t );
397
+ mTotalSize += allocSize;
398
+ if (mTotalSize > kMaxTotalSize ) {
399
+ ALOGE (" Time-to-sample table size would make sample table too large.\n "
400
+ " Requested time-to-sample table size = %llu\n "
401
+ " Eventual sample table size >= %llu\n "
402
+ " Allowed sample table size = %llu\n " ,
403
+ (unsigned long long )allocSize,
404
+ (unsigned long long )mTotalSize ,
405
+ (unsigned long long )kMaxTotalSize );
406
+ return ERROR_OUT_OF_RANGE;
407
+ }
408
+
409
+ mTimeToSample = new (std::nothrow) uint32_t [mTimeToSampleCount * 2 ];
410
+ if (!mTimeToSample ) {
411
+ ALOGE (" Cannot allocate time-to-sample table with %llu entries." ,
412
+ (unsigned long long )mTimeToSampleCount );
413
+ return ERROR_OUT_OF_RANGE;
414
+ }
415
+
416
+ if (mDataSource ->readAt (data_offset + 8 , mTimeToSample ,
417
+ (size_t )allocSize) < (ssize_t )allocSize) {
418
+ ALOGE (" Incomplete data read for time-to-sample table." );
359
419
return ERROR_IO;
360
420
}
361
421
362
- for (size_t i = 0 ; i < mTimeToSample . size () ; ++i) {
363
- mTimeToSample . editItemAt (i) = ntohl (mTimeToSample [i]);
422
+ for (size_t i = 0 ; i < mTimeToSampleCount * 2 ; ++i) {
423
+ mTimeToSample [i] = ntohl (mTimeToSample [i]);
364
424
}
365
425
366
426
mHasTimeToSample = true ;
@@ -396,14 +456,31 @@ status_t SampleTable::setCompositionTimeToSampleParams(
396
456
mNumCompositionTimeDeltaEntries = numEntries;
397
457
uint64_t allocSize = (uint64_t )numEntries * 2 * sizeof (uint32_t );
398
458
if (allocSize > SIZE_MAX) {
459
+ ALOGE (" Composition-time-to-sample table size too large." );
460
+ return ERROR_OUT_OF_RANGE;
461
+ }
462
+
463
+ mTotalSize += allocSize;
464
+ if (mTotalSize > kMaxTotalSize ) {
465
+ ALOGE (" Composition-time-to-sample table would make sample table too large.\n "
466
+ " Requested composition-time-to-sample table size = %llu\n "
467
+ " Eventual sample table size >= %llu\n "
468
+ " Allowed sample table size = %llu\n " ,
469
+ (unsigned long long )allocSize,
470
+ (unsigned long long )mTotalSize ,
471
+ (unsigned long long )kMaxTotalSize );
399
472
return ERROR_OUT_OF_RANGE;
400
473
}
401
474
402
- mCompositionTimeDeltaEntries = new uint32_t [2 * numEntries];
475
+ mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t [2 * numEntries];
476
+ if (!mCompositionTimeDeltaEntries ) {
477
+ ALOGE (" Cannot allocate composition-time-to-sample table with %llu "
478
+ " entries." , (unsigned long long )numEntries);
479
+ return ERROR_OUT_OF_RANGE;
480
+ }
403
481
404
- if (mDataSource ->readAt (
405
- data_offset + 8 , mCompositionTimeDeltaEntries , numEntries * 8 )
406
- < (ssize_t )numEntries * 8 ) {
482
+ if (mDataSource ->readAt (data_offset + 8 , mCompositionTimeDeltaEntries ,
483
+ (size_t )allocSize) < (ssize_t )allocSize) {
407
484
delete[] mCompositionTimeDeltaEntries ;
408
485
mCompositionTimeDeltaEntries = NULL ;
409
486
@@ -444,15 +521,33 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size)
444
521
ALOGV (" Table of sync samples is empty or has only a single entry!" );
445
522
}
446
523
447
- uint64_t allocSize = mNumSyncSamples * ( uint64_t ) sizeof (uint32_t );
524
+ uint64_t allocSize = ( uint64_t ) mNumSyncSamples * sizeof (uint32_t );
448
525
if (allocSize > SIZE_MAX) {
526
+ ALOGE (" Sync sample table size too large." );
527
+ return ERROR_OUT_OF_RANGE;
528
+ }
529
+
530
+ mTotalSize += allocSize;
531
+ if (mTotalSize > kMaxTotalSize ) {
532
+ ALOGE (" Sync sample table size would make sample table too large.\n "
533
+ " Requested sync sample table size = %llu\n "
534
+ " Eventual sample table size >= %llu\n "
535
+ " Allowed sample table size = %llu\n " ,
536
+ (unsigned long long )allocSize,
537
+ (unsigned long long )mTotalSize ,
538
+ (unsigned long long )kMaxTotalSize );
539
+ return ERROR_OUT_OF_RANGE;
540
+ }
541
+
542
+ mSyncSamples = new (std::nothrow) uint32_t [mNumSyncSamples ];
543
+ if (!mSyncSamples ) {
544
+ ALOGE (" Cannot allocate sync sample table with %llu entries." ,
545
+ (unsigned long long )mNumSyncSamples );
449
546
return ERROR_OUT_OF_RANGE;
450
547
}
451
548
452
- mSyncSamples = new uint32_t [mNumSyncSamples ];
453
- size_t size = mNumSyncSamples * sizeof (uint32_t );
454
- if (mDataSource ->readAt (mSyncSampleOffset + 8 , mSyncSamples , size)
455
- != (ssize_t )size) {
549
+ if (mDataSource ->readAt (mSyncSampleOffset + 8 , mSyncSamples ,
550
+ (size_t )allocSize) != (ssize_t )allocSize) {
456
551
return ERROR_IO;
457
552
}
458
553
@@ -517,7 +612,24 @@ void SampleTable::buildSampleEntriesTable() {
517
612
return ;
518
613
}
519
614
520
- mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes ];
615
+ mTotalSize += (uint64_t )mNumSampleSizes * sizeof (SampleTimeEntry);
616
+ if (mTotalSize > kMaxTotalSize ) {
617
+ ALOGE (" Sample entry table size would make sample table too large.\n "
618
+ " Requested sample entry table size = %llu\n "
619
+ " Eventual sample table size >= %llu\n "
620
+ " Allowed sample table size = %llu\n " ,
621
+ (unsigned long long )mNumSampleSizes * sizeof (SampleTimeEntry),
622
+ (unsigned long long )mTotalSize ,
623
+ (unsigned long long )kMaxTotalSize );
624
+ return ;
625
+ }
626
+
627
+ mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes ];
628
+ if (!mSampleTimeEntries ) {
629
+ ALOGE (" Cannot allocate sample entry table with %llu entries." ,
630
+ (unsigned long long )mNumSampleSizes );
631
+ return ;
632
+ }
521
633
522
634
uint32_t sampleIndex = 0 ;
523
635
uint32_t sampleTime = 0 ;
0 commit comments