Skip to content

Commit

Permalink
read.c: Validate that there is at least one trak box
Browse files Browse the repository at this point in the history
When parsing the 'moov' box, ensure that there is at least one
'trak' box that was successfully parsed. If not, report it as a
failure.
  • Loading branch information
vigneshvg committed May 6, 2024
1 parent f7dc78c commit caf027a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -3512,17 +3512,23 @@ static avifResult avifParseMovieBox(avifDecoderData * data,
{
BEGIN_STREAM(s, raw, rawLen, data->diag, "Box[moov]");

avifBool hasTrak = AVIF_FALSE;
while (avifROStreamHasBytesLeft(&s, 1)) {
avifBoxHeader header;
AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

if (!memcmp(header.type, "trak", 4)) {
AVIF_CHECKRES(
avifParseTrackBox(data, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, imageSizeLimit, imageDimensionLimit));
hasTrak = AVIF_TRUE;
}

AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
}
if (!hasTrak) {
avifDiagnosticsPrintf(data->diag, "moov box does not contain any tracks");
return AVIF_RESULT_BMFF_PARSE_FAILED;
}
return AVIF_RESULT_OK;
}

Expand Down
27 changes: 27 additions & 0 deletions tests/gtest/avifanimationtest.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause

#include <algorithm>

#include "avif/avif.h"
#include "aviftest_helpers.h"
#include "gtest/gtest.h"
Expand Down Expand Up @@ -74,6 +76,31 @@ TEST(AvifDecodeTest, AnimatedImageWithAlphaAndMetadata) {
EXPECT_EQ(decoder->image->xmp.size, 3898);
}

TEST(AvifDecodeTest, AnimatedImageWithoutTracksShouldFail) {
testutil::AvifRwData avif =
testutil::ReadFile(std::string(data_path) + "colors-animated-8bpc.avif");
// Edit the file to replace 'trak' box with a 'free' box. This way the file
// will not contain any 'trak' boxes.
const uint8_t* kTrak = reinterpret_cast<const uint8_t*>("trak");
uint8_t* trak_position =
std::search(avif.data, avif.data + avif.size, kTrak, kTrak + 4);
ASSERT_NE(trak_position, avif.data + avif.size);
trak_position[0] = static_cast<uint8_t>('f');
trak_position[1] = static_cast<uint8_t>('r');
trak_position[2] = static_cast<uint8_t>('e');
trak_position[3] = static_cast<uint8_t>('e');

for (auto source :
{AVIF_DECODER_SOURCE_PRIMARY_ITEM, AVIF_DECODER_SOURCE_TRACKS}) {
DecoderPtr decoder(avifDecoderCreate());
ASSERT_NE(decoder, nullptr);
ASSERT_EQ(avifDecoderSetIOMemory(decoder.get(), avif.data, avif.size),
AVIF_RESULT_OK);
ASSERT_EQ(avifDecoderSetSource(decoder.get(), source), AVIF_RESULT_OK);
ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_BMFF_PARSE_FAILED);
}
}

} // namespace
} // namespace avif

Expand Down

0 comments on commit caf027a

Please sign in to comment.