Bugfix for some tags failing encoding due to more than one supported type

This was a recently introduced, preexisting bug caused by adding support
for multiple types for certain tags. This suddenly became an issue when
we added all remaining additional types and at least one of these was in
our testing data.
dustin/add_skipped_tags_tracking
Dustin Oprea 2020-05-19 02:32:43 -04:00
parent 15666b6093
commit 71d0c799d3
2 changed files with 35 additions and 5 deletions

View File

@ -185,9 +185,10 @@ func (bt *BuilderTag) SetValue(byteOrder binary.ByteOrder, value interface{}) (e
// NewStandardBuilderTag constructs a `BuilderTag` instance. The type is looked
// up. `ii` is the type of IFD that owns this tag.
func NewStandardBuilderTag(ifdPath string, it *IndexedTag, byteOrder binary.ByteOrder, value interface{}) *BuilderTag {
if len(it.SupportedTypes) != 1 {
log.Panicf("NewStandardBuilderTag() IndexedTag argument must have exactly one supported-type: %v", it.SupportedTypes)
}
// If there is more than one supported type, we'll go with the larger to
// encode with. It'll use the same amount of fixed-space, and we'll
// eliminate unnecessary overflows/issues.
tagType := it.WidestSupportedType()
var rawBytes []byte
if it.DoesSupportType(exifcommon.TypeUndefined) == true {
@ -211,7 +212,7 @@ func NewStandardBuilderTag(ifdPath string, it *IndexedTag, byteOrder binary.Byte
return NewBuilderTag(
ifdPath,
it.Id,
it.SupportedTypes[0],
tagType,
tagValue,
byteOrder)
}

View File

@ -111,6 +111,34 @@ func (it *IndexedTag) Is(ifdPath string, id uint16) bool {
return it.Id == id && it.IfdPath == ifdPath
}
func (it *IndexedTag) WidestSupportedType() exifcommon.TagTypePrimitive {
if len(it.SupportedTypes) == 0 {
log.Panicf("IndexedTag [%s] (%d) has no supported types.", it.IfdPath, it.Id)
} else if len(it.SupportedTypes) == 1 {
return it.SupportedTypes[0]
}
supportsLong := false
supportsShort := false
for _, supportedType := range it.SupportedTypes {
if supportedType == exifcommon.TypeLong {
supportsLong = true
} else if supportedType == exifcommon.TypeShort {
supportsShort = true
}
}
// If it supports both long and short ints. This is currently our common
// and only case. The moment more are added to our tags database, we'll have
// to add more checks here if we add more than just a LONG and just a SHORT.
if supportsLong == true && supportsShort == true {
return exifcommon.TypeLong
}
log.Panicf("WidestSupportedType() case is not handled for tag [%s] (0x%04x): %v", it.IfdPath, it.Id, it.SupportedTypes)
return 0
}
// DoesSupportType returns true if this tag can be found/decoded with this type.
func (it *IndexedTag) DoesSupportType(tagType exifcommon.TagTypePrimitive) bool {
// This is always a very small collection. So, we keep it unsorted.
@ -178,7 +206,8 @@ func (ti *TagIndex) Add(it *IndexedTag) (err error) {
return nil
}
// Get returns information about the non-IFD tag given a tag ID.
// Get returns information about the non-IFD tag given a tag ID. `ifdPath` must
// not be fully-qualified.
func (ti *TagIndex) Get(ifdPath string, id uint16) (it *IndexedTag, err error) {
defer func() {
if state := recover(); state != nil {