Skip to content

Commit 0a18d75

Browse files
committed
fix: reject extended size for all boxes but mdat
1 parent b19abb4 commit 0a18d75

File tree

8 files changed

+41
-21
lines changed

8 files changed

+41
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
### Fixed
2121

2222
- duration is printed by `MdhdBox.Info()`
23+
- extended size usage only allowed for `mdat` boxes
2324

2425
## [0.50.0] - 2025-09-05
2526

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ open-docs:
3434
.PHONY: coverage
3535
coverage:
3636
# Ignore (allow) packages without any tests
37-
go test ./... -coverprofile coverage.out
37+
go test -coverpkg=./... -coverprofile coverage.out ./...
3838
go tool cover -html=coverage.out -o coverage.html
3939
go tool cover -func coverage.out -o coverage.txt
4040
tail -1 coverage.txt

mp4/box.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ func DecodeHeader(r io.Reader) (BoxHeader, error) {
214214
headerLen := boxHeaderSize
215215
switch size {
216216
case 1: // size 1 means large size in next 8 bytes
217+
boxType := string(buf[4:8])
218+
if boxType != "mdat" {
219+
return BoxHeader{}, fmt.Errorf("extended size not supported for box type %s", boxType)
220+
}
217221
buf := make([]byte, largeSizeLen)
218222
_, err = io.ReadFull(r, buf)
219223
if err != nil {

mp4/box_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,15 @@ func TestDecodeHeader(t *testing.T) {
7575
wantErr: true,
7676
},
7777
{
78-
name: "extended size with sufficient bytes",
79-
data: []byte{0x00, 0x00, 0x00, 0x01, 't', 'e', 's', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
78+
name: "extended size with sufficient bytes for mdat",
79+
data: []byte{0x00, 0x00, 0x00, 0x01, 'm', 'd', 'a', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
8080
wantErr: false,
8181
},
82+
{
83+
name: "extended size rejected for non-mdat",
84+
data: []byte{0x00, 0x00, 0x00, 0x01, 't', 'e', 's', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
85+
wantErr: true,
86+
},
8287
{
8388
name: "zero size not supported",
8489
data: []byte{0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't'},

mp4/boxsr.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ func DecodeHeaderSR(sr bits.SliceReader) (BoxHeader, error) {
186186
headerLen := boxHeaderSize
187187
switch size {
188188
case 1: // size 1 means large size in next 8 bytes
189+
if boxType != "mdat" {
190+
return BoxHeader{}, fmt.Errorf("extended size not supported for box type %s", boxType)
191+
}
189192
size = sr.ReadUint64()
190193
headerLen += largeSizeLen
191194
case 0: // size 0 means to end of file

mp4/boxsr_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,15 @@ func TestDecodeHeaderSRInsufficientBytes(t *testing.T) {
3232
wantErr: true,
3333
},
3434
{
35-
name: "extended size with sufficient bytes",
36-
data: []byte{0x00, 0x00, 0x00, 0x01, 't', 'e', 's', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
35+
name: "extended size with sufficient bytes for mdat",
36+
data: []byte{0x00, 0x00, 0x00, 0x01, 'm', 'd', 'a', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
3737
wantErr: false,
3838
},
39+
{
40+
name: "extended size rejected for non-mdat",
41+
data: []byte{0x00, 0x00, 0x00, 0x01, 't', 'e', 's', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
42+
wantErr: true,
43+
},
3944
{
4045
name: "zero size not supported",
4146
data: []byte{0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't'},

mp4/senc.go

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ func (s *SencBox) ReadButNotParsed() bool {
109109

110110
// DecodeSenc - box-specific decode
111111
func DecodeSenc(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) {
112-
if hdr.Size < 16 {
113-
return nil, fmt.Errorf("box size %d less than min size 16", hdr.Size)
112+
if hdr.payloadLen() < 8 {
113+
return nil, fmt.Errorf("payload size %d less than min size 8", hdr.payloadLen())
114114
}
115115
data, err := readBoxBody(r, hdr)
116116
if err != nil {
@@ -125,10 +125,6 @@ func DecodeSenc(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) {
125125
}
126126
sampleCount := binary.BigEndian.Uint32(data[4:8])
127127

128-
if len(data) < 8 {
129-
return nil, fmt.Errorf("senc: box size %d less than 16", hdr.Size)
130-
}
131-
132128
senc := SencBox{
133129
Version: version,
134130
rawData: data[8:], // After the first 8 bytes of box content
@@ -140,8 +136,8 @@ func DecodeSenc(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) {
140136
}
141137

142138
if flags&UseSubSampleEncryption != 0 && (len(senc.rawData) < 2*int(sampleCount)) {
143-
return nil, fmt.Errorf("box size %d too small for %d samples and subSampleEncryption",
144-
hdr.Size, sampleCount)
139+
return nil, fmt.Errorf("payload size %d too small for %d samples and subSampleEncryption",
140+
hdr.payloadLen(), sampleCount)
145141
}
146142

147143
if senc.SampleCount == 0 || len(senc.rawData) == 0 {
@@ -153,9 +149,10 @@ func DecodeSenc(hdr BoxHeader, startPos uint64, r io.Reader) (Box, error) {
153149

154150
// DecodeSencSR - box-specific decode
155151
func DecodeSencSR(hdr BoxHeader, startPos uint64, sr bits.SliceReader) (Box, error) {
156-
if hdr.Size < 16 {
157-
return nil, fmt.Errorf("box size %d less than min size 16", hdr.Size)
152+
if hdr.payloadLen() < 8 {
153+
return nil, fmt.Errorf("payload size %d less than min size 8", hdr.payloadLen())
158154
}
155+
payloadLen := uint64(hdr.payloadLen())
159156

160157
versionAndFlags := sr.ReadUint32()
161158
version := byte(versionAndFlags >> 24)
@@ -165,14 +162,14 @@ func DecodeSencSR(hdr BoxHeader, startPos uint64, sr bits.SliceReader) (Box, err
165162
flags := versionAndFlags & flagsMask
166163
sampleCount := sr.ReadUint32()
167164

168-
if flags&UseSubSampleEncryption != 0 && ((hdr.Size - 16) < 2*uint64(sampleCount)) {
169-
return nil, fmt.Errorf("box size %d too small for %d samples and subSampleEncryption",
170-
hdr.Size, sampleCount)
165+
if flags&UseSubSampleEncryption != 0 && ((payloadLen - 8) < 2*uint64(sampleCount)) {
166+
return nil, fmt.Errorf("payload size %d too small for %d samples and subSampleEncryption",
167+
hdr.payloadLen(), sampleCount)
171168
}
172169

173170
senc := SencBox{
174171
Version: version,
175-
rawData: sr.ReadBytes(hdr.payloadLen() - 8), // After the first 8 bytes of box content
172+
rawData: sr.ReadBytes(int(payloadLen - 8)), // After the first 8 bytes of box content
176173
Flags: flags,
177174
StartPos: startPos,
178175
SampleCount: sampleCount,

mp4/senc_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func TestBadSencData(t *testing.T) {
179179
{
180180
desc: "too short",
181181
raw: []byte{0x00, 0x00, 0x00, 0x0f, 's', 'e', 'n', 'c', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
182-
err: "decode senc pos 0: box size 15 less than min size 16",
182+
err: "decode senc pos 0: payload size 7 less than min size 8",
183183
},
184184
{
185185
desc: "v1 not supported",
@@ -189,7 +189,12 @@ func TestBadSencData(t *testing.T) {
189189
{
190190
desc: "too short for subsample encryption",
191191
raw: []byte{0x00, 0x00, 0x00, 0x10, 's', 'e', 'n', 'c', 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff},
192-
err: "decode senc pos 0: box size 16 too small for 255 samples and subSampleEncryption",
192+
err: "decode senc pos 0: payload size 8 too small for 255 samples and subSampleEncryption",
193+
},
194+
{
195+
desc: "extended size rejected for senc (issue 479)",
196+
raw: []byte{0x00, 0x00, 0x00, 0x01, 's', 'e', 'n', 'c', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
197+
err: "extended size not supported for box type senc",
193198
},
194199
}
195200

0 commit comments

Comments
 (0)