Skip to content

Commit

Permalink
properties: sanity check boxtype and UUID values
Browse files Browse the repository at this point in the history
  • Loading branch information
bradh committed Nov 30, 2024
1 parent 2f4fe06 commit f2cc919
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ set(AVIF_SRCS
src/io.c
src/mem.c
src/obu.c
src/properties.c
src/rawdata.c
src/read.c
src/reformat.c
Expand Down
5 changes: 5 additions & 0 deletions include/avif/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ AVIF_API avifResult avifImagePushProperty(avifImage * image,
const uint8_t * boxPayload,
size_t boxPayloadSize);

// Check if the FourCC property value is a known value
AVIF_NODISCARD avifBool avifIsKnownPropertyType(const uint8_t boxtype[4]);
// Check if the extended property (UUID) is valid
AVIF_NODISCARD avifBool avifIsValidUUID(const uint8_t uuid[16]);

// ---------------------------------------------------------------------------

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
Expand Down
6 changes: 6 additions & 0 deletions src/avif.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,18 @@ avifResult avifImagePushProperty(avifImage * image, const uint8_t boxtype[4], co
avifResult avifImageAddOpaqueProperty(avifImage * image, const uint8_t boxtype[4], const uint8_t * data, size_t dataSize)
{
const uint8_t uuid[16] = { 0 };
if (avifIsKnownPropertyType(boxtype)) {
return AVIF_RESULT_INVALID_ARGUMENT;
}
return avifImagePushProperty(image, boxtype, uuid, data, dataSize);
}

avifResult avifImageAddUUIDProperty(avifImage * image, const uint8_t uuid[16], const uint8_t * data, size_t dataSize)
{
const uint8_t boxtype[4] = { 'u', 'u', 'i', 'd' };
if (!avifIsValidUUID(uuid)) {
return AVIF_RESULT_INVALID_ARGUMENT;
}
return avifImagePushProperty(image, boxtype, uuid, data, dataSize);
}

Expand Down
54 changes: 54 additions & 0 deletions src/properties.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2024 Brad Hards. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/internal.h"
#include <string.h>

struct avifKnownProperty
{
const uint8_t fourcc[4];
};

static const struct avifKnownProperty avifKnownProperties[] = {
{ "ftyp" }, { "uuid" }, { "meta" }, { "hdlr" }, { "pitm" }, { "dinf" }, { "dref" }, { "idat" }, { "iloc" },
{ "iinf" }, { "infe" }, { "iprp" }, { "ipco" }, { "av1C" }, { "av2C" }, { "ispe" }, { "pixi" }, { "pasp" },
{ "colr" }, { "auxC" }, { "clap" }, { "irot" }, { "imir" }, { "clli" }, { "cclv" }, { "mdcv" }, { "amve" },
{ "reve" }, { "ndwt" }, { "a1op" }, { "lsel" }, { "a1lx" }, { "cmin" }, { "cmex" }, { "ipma" }, { "iref" },
{ "auxl" }, { "thmb" }, { "dimg" }, { "prem" }, { "cdsc" }, { "grpl" }, { "altr" }, { "ster" }, { "mdat" },
};

static const size_t numKnownProperties = sizeof(avifKnownProperties) / sizeof(avifKnownProperties[0]);

static const size_t FOURCC_BYTES = 4;
static const size_t UUID_BYTES = 16;

static const uint8_t ISO_UUID_SUFFIX[12] = { 0x00, 0x01, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9b, 0x71 };

avifBool avifIsKnownPropertyType(const uint8_t boxtype[4])
{
for (size_t i = 0; i < numKnownProperties; i++) {
if (memcmp(avifKnownProperties[i].fourcc, boxtype, FOURCC_BYTES) == 0) {
return AVIF_TRUE;
}
}
return AVIF_FALSE;
}

avifBool avifIsValidUUID(const uint8_t uuid[16])
{
for (size_t i = 0; i < numKnownProperties; i++) {
if ((memcmp(avifKnownProperties[i].fourcc, uuid, FOURCC_BYTES) == 0) &&
(memcmp(ISO_UUID_SUFFIX, uuid + FOURCC_BYTES, UUID_BYTES - FOURCC_BYTES) == 0)) {
return AVIF_FALSE;
}
}
uint8_t variant = uuid[8] >> 4;
if ((variant < 0x08) || (variant > 0x0b)) {
return AVIF_FALSE;
}
uint8_t version = uuid[6] >> 4;
if ((version < 1) || (version > 8)) {
return AVIF_FALSE;
}
return AVIF_TRUE;
}
4 changes: 4 additions & 0 deletions tests/gtest/avifpropertytest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ TEST(AvifPropertyTest, Serialise) {
ASSERT_EQ(avifImageAddOpaqueProperty(image.get(), (uint8_t*)"efgh",
efgh_data.data(), efgh_data.size()),
AVIF_RESULT_OK);
// Should not be added
ASSERT_EQ(avifImageAddOpaqueProperty(image.get(), (uint8_t*)"mdat",
efgh_data.data(), efgh_data.size()),
AVIF_RESULT_INVALID_ARGUMENT);
ASSERT_EQ(avifImageAddUUIDProperty(image.get(), uuid, uuid_data.data(),
uuid_data.size()),
AVIF_RESULT_OK);
Expand Down
54 changes: 54 additions & 0 deletions tests/gtest/avifpropinternaltest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause

#include <cmath>

#include "avif/internal.h"
#include "aviftest_helpers.h"
#include "gtest/gtest.h"

namespace avif {
namespace {

TEST(InternalPropertiesTest, KnownFound) {
const uint8_t FTYP[4]{'f', 't', 'y', 'p'};
ASSERT_EQ(avifIsKnownPropertyType(FTYP), AVIF_TRUE);
const uint8_t MDAT[4]{'m', 'd', 'a', 't'};
ASSERT_EQ(avifIsKnownPropertyType(MDAT), AVIF_TRUE);
const uint8_t ISPE[4]{'i', 's', 'p', 'e'};
ASSERT_EQ(avifIsKnownPropertyType(ISPE), AVIF_TRUE);
}

TEST(InternalPropertiesTest, UnknownNotFound) {
const uint8_t SIEP[4]{'s', 'i', 'e', 'p'};
ASSERT_EQ(avifIsKnownPropertyType(SIEP), AVIF_FALSE);
const uint8_t MTXF[4]{'m', 't', 'x', 'f'};
ASSERT_EQ(avifIsKnownPropertyType(MTXF), AVIF_FALSE);
}

TEST(InternalPropertiesTest, UuidValid) {
const uint8_t uuid[16]{0x98, 0x10, 0xd7, 0xfc, 0xa5, 0xd2, 0x4c, 0x4b,
0x9a, 0x4f, 0x05, 0x99, 0x02, 0xf4, 0x9b, 0xfd};
ASSERT_EQ(avifIsValidUUID(uuid), AVIF_TRUE);
}

TEST(InternalPropertiesTest, UuidInvalidISO) {
const uint8_t uuid[16]{'m', 'd', 'a', 't', 0x00, 0x01, 0x00, 0x10,
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};
ASSERT_EQ(avifIsValidUUID(uuid), AVIF_FALSE);
}

TEST(InternalPropertiesTest, UuidInvalidVariant) {
const uint8_t uuid[16]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ASSERT_EQ(avifIsValidUUID(uuid), AVIF_FALSE);
}

TEST(InternalPropertiesTest, UuidInvalidVersion) {
const uint8_t uuid[16]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00,
0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ASSERT_EQ(avifIsValidUUID(uuid), AVIF_FALSE);
}

} // namespace
} // namespace avif

0 comments on commit f2cc919

Please sign in to comment.