mirror of https://github.com/dsoprea/go-exif.git
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
parent
15666b6093
commit
71d0c799d3
|
@ -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)
|
||||
}
|
||||
|
|
31
v2/tags.go
31
v2/tags.go
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue