Skip to content

Commit

Permalink
fix: implement expectedSize checks for co64, stss, trun
Browse files Browse the repository at this point in the history
  • Loading branch information
eric committed Jan 14, 2025
1 parent 3a94fb4 commit 45c6631
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 10 deletions.
18 changes: 14 additions & 4 deletions mp4/co64.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,18 @@ func DecodeCo64(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) {
func DecodeCo64SR(hdr BoxHeader, startPos uint64, sr bits.SliceReader) (Box, error) {
versionAndFlags := sr.ReadUint32()
nrEntries := sr.ReadUint32()

b := &Co64Box{
Version: byte(versionAndFlags >> 24),
Flags: versionAndFlags & flagsMask,
ChunkOffset: make([]uint64, nrEntries),
Version: byte(versionAndFlags >> 24),
Flags: versionAndFlags & flagsMask,
}

if hdr.Size != b.expectedSize(nrEntries) {
return nil, fmt.Errorf("expected size %d, got %d", b.expectedSize(nrEntries), hdr.Size)
}

b.ChunkOffset = make([]uint64, nrEntries)

for i := uint32(0); i < nrEntries; i++ {
b.ChunkOffset[i] = sr.ReadUint64()
if sr.AccError() != nil {
Expand All @@ -52,9 +58,13 @@ func (b *Co64Box) Type() string {
return "co64"
}

func (b *Co64Box) expectedSize(nrEntries uint32) uint64 {
return uint64(boxHeaderSize + 8 + nrEntries*8)
}

// Size - box-specific size
func (b *Co64Box) Size() uint64 {
return uint64(boxHeaderSize + 8 + len(b.ChunkOffset)*8)
return b.expectedSize(uint32(len(b.ChunkOffset)))
}

// Encode - write box to w
Expand Down
5 changes: 5 additions & 0 deletions mp4/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"io"
"os"
"runtime/debug"
"strings"
"testing"
)
Expand All @@ -27,7 +28,11 @@ func FuzzDecodeBox(f *testing.F) {
}
}

debug.SetMemoryLimit(500 * 1024 * 1024) // 500MB

f.Fuzz(func(t *testing.T, b []byte) {
debug.SetMemoryLimit(500 * 1024 * 1024) // 500MB

r := bytes.NewReader(b)

var pos uint64 = 0
Expand Down
19 changes: 15 additions & 4 deletions mp4/stss.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mp4

import (
"fmt"
"io"

"github.com/Eyevinn/mp4ff/bits"
Expand Down Expand Up @@ -32,10 +33,15 @@ func DecodeStssSR(hdr BoxHeader, startPos uint64, sr bits.SliceReader) (Box, err
versionAndFlags := sr.ReadUint32()
entryCount := sr.ReadUint32()
b := StssBox{
Version: byte(versionAndFlags >> 24),
Flags: versionAndFlags & flagsMask,
SampleNumber: make([]uint32, entryCount),
Version: byte(versionAndFlags >> 24),
Flags: versionAndFlags & flagsMask,
}

if hdr.Size != b.expectedSize(entryCount) {
return nil, fmt.Errorf("stss: expected size %d, got %d", b.expectedSize(entryCount), hdr.Size)
}

b.SampleNumber = make([]uint32, entryCount)
for i := 0; i < int(entryCount); i++ {
b.SampleNumber[i] = sr.ReadUint32()
}
Expand All @@ -54,7 +60,12 @@ func (b *StssBox) Type() string {

// Size - box-specific size
func (b *StssBox) Size() uint64 {
return uint64(boxHeaderSize + 8 + len(b.SampleNumber)*4)
return b.expectedSize(uint32(len(b.SampleNumber)))
}

// expectedSize - calculate size for a given entry count
func (b *StssBox) expectedSize(entryCount uint32) uint64 {
return uint64(boxHeaderSize + 8 + int(entryCount)*4)
}

// IsSyncSample - check if sample (one-based) sampleNr is a sync sample
Expand Down
2 changes: 2 additions & 0 deletions mp4/testdata/fuzz/FuzzDecodeBox/10b83fbad9664344
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\x00\x00\x04\x1cdrefurl \x00\x00\x00\x01\x00\x00\x017stbl\x00\x00\x00\xebstssed Caption\x00\x00\x00\x00\xa4minf\x00\x00\x00\fnmhd\x00\x00\x00\x00\x00\x00\x00$dinf\x00\x00\x00\x1cdref\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\furl \x00\x00\x00\x01\x00\x00\x00lstbl\x00\x00\x00 stsd\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x10c608\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x10stts\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10stsc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14stsz\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10stco\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Pudta\x00\x00\x00Hswre\x00\x00\x00\x00U\xc4mediafilesegmenter: Version 1.10.4 (524.12i-210805) Linux\x00\x00\x00\x00Hmvex\x00\x00\x00 trex\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 trex\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
2 changes: 2 additions & 0 deletions mp4/testdata/fuzz/FuzzDecodeBox/95c1a4c24dba32de
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0000traf\x00\x00\x01\x88trun00000\x00\x00]\x00\x00\x01\xd0\x00\x00\x01N\x00\x00\x01N\x00\x00\x01O\x00\x00\x01N\x00\x00\x01N\x00\x00\x01O\x00\x00\x01N\x00\x00\x01N\x00\x00\x01\x90\x00\x00\x01\xec\x00\x00\x01\xce\x00\x00\x01\xca\x00\x00\x01\xa7\x00\x00\x01\x91\x00\x00\x01\x88\x00\x00\x01{\x00\x00\x01n\x00\x00\x01t\x00\x00\x01h\x00\x00\x01^\x00\x00\x01l\x00\x00\x01a\x00\x00\x01M\x00\x00\x01T\x00\x00\x01Y\x00\x00\x01P\x00\x00\x01U\x00\x00\x010\x00\x00\x01I\x00\x00\x01Y\x00\x00\x01K\x00\x00\x01;\x00\x00\x01O\x00\x00\x01Q\x00\x00\x01J\x00\x00\x010\x00\x00\x01!\x00\x00\x01#\x00\x00\x01/\x00\x00\x011\x00\x00\x011\x00\x00\x01)\x00\x00\x01<\x00\x00\x01.\x00\x00\x01B\x00\x00\x01E\x00\x00\x01G\x00\x00\x01E\x00\x00\x01B\x00\x00\x01J\x00\x00\x01E\x00\x00\x01S\x00\x00\x01:\x00\x00\x01l\x00\x00\x01~\x00\x00\x01Q\x00\x00\x01E\x00\x00\x01R\x00\x00\x01N\x00\x00\x01Z\x00\x00\x017\x00\x00\x01S\x00\x00\x01a\x00\x00\x01W\x00\x00\x01B\x00\x00\x01G\x00\x00\x01M\x00\x00\x01B\x00\x00\x01H\x00\x00\x01P\x00\x00\x01I\x00\x00\x01=\x00\x00\x01Q\x00\x00\x01\x84\x00\x00\x01F\x00\x00\x01H\x00\x00\x01Q\x00\x00\x01q\x00\x00\x01:\x00\x00\x017\x00\x00\x01@\x00\x00\x019\x00\x00\x01J\x00\x00\x01B\x00\x00\x01e\x00\x00\x01X\x00\x00\x01K\x00\x00\x01Q\x00\x00\x01R\x00\x00\x01K\x00\x00\x01F\x00\x00\x019\x00\x00\x01:")
13 changes: 11 additions & 2 deletions mp4/trun.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ func DecodeTrun(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) {
Flags: versionAndFlags & flagsMask,
}

if hdr.Size != t.expectedSize(sampleCount) {
return nil, fmt.Errorf("trun: expected size %d, got %d", t.expectedSize(sampleCount), hdr.Size)
}

if t.HasDataOffset() {
t.DataOffset = s.ReadInt32()
}
Expand Down Expand Up @@ -235,7 +239,12 @@ func (t *TrunBox) Type() string {

// Size - return calculated size
func (t *TrunBox) Size() uint64 {
sz := boxHeaderSize + 8 // flags + entrycCount
return t.expectedSize(t.SampleCount())
}

// expectedSize - calculate size for a given sample count
func (t *TrunBox) expectedSize(sampleCount uint32) uint64 {
sz := boxHeaderSize + 8 // flags + entryCount
if t.HasDataOffset() {
sz += 4
}
Expand All @@ -255,7 +264,7 @@ func (t *TrunBox) Size() uint64 {
if t.HasSampleCompositionTimeOffset() {
bytesPerSample += 4
}
sz += int(t.SampleCount()) * bytesPerSample
sz += int(sampleCount) * bytesPerSample
return uint64(sz)
}

Expand Down

0 comments on commit 45c6631

Please sign in to comment.