Revert "type.go: Deinegrated `ErrUnhandledUnknownTypedTag`"

This reverts commit 4f2f9044e6.

Reintroduces errors from `UndefinedValue()` when the undefined-type is
unhandled.

- We now just return it rather than panic with it so that we can check
  for it directly rather than use `log.Is()`.

- We've updated the checks across the code accordingly.
pull/28/head
Dustin Oprea 2020-01-01 09:05:06 -05:00
parent 439148e767
commit 9aa2497f7b
8 changed files with 83 additions and 46 deletions

View File

@ -186,9 +186,13 @@ visitor := func(fqIfdPath string, ifdIndex int, tagId uint16, tagType exif.TagTy
valueString := "" valueString := ""
if tagType.Type() == exif.TypeUndefined { if tagType.Type() == exif.TypeUndefined {
value, err := exif.UndefinedValue(ifdPath, tagId, valueContext, tagType.ByteOrder()) value, err := exif.UndefinedValue(ifdPath, tagId, valueContext, tagType.ByteOrder())
log.PanicIf(err) if log.Is(err, exif.ErrUnhandledUnknownTypedTag) {
valueString = "!UNDEFINED!"
valueString = fmt.Sprintf("%v", value) } else if err != nil {
panic(err)
} else {
valueString = fmt.Sprintf("%v", value)
}
} else { } else {
valueString, err = tagType.ResolveAsString(valueContext, true) valueString, err = tagType.ResolveAsString(valueContext, true)
if err != nil { if err != nil {

View File

@ -109,7 +109,13 @@ func main() {
if tagType.Type() == exif.TypeUndefined { if tagType.Type() == exif.TypeUndefined {
var err error var err error
value, err = valueContext.Undefined() value, err = valueContext.Undefined()
log.PanicIf(err) if err != nil {
if err == exif.ErrUnhandledUnknownTypedTag {
value = nil
} else {
log.Panic(err)
}
}
valueString = fmt.Sprintf("%v", value) valueString = fmt.Sprintf("%v", value)
} else { } else {

View File

@ -82,7 +82,13 @@ func TestVisit(t *testing.T) {
valueString := "" valueString := ""
if tagType.Type() == TypeUndefined { if tagType.Type() == TypeUndefined {
value, err := valueContext.Undefined() value, err := valueContext.Undefined()
log.PanicIf(err) if err != nil {
if err == ErrUnhandledUnknownTypedTag {
valueString = "!UNDEFINED!"
} else {
log.Panic(err)
}
}
valueString = fmt.Sprintf("%v", value) valueString = fmt.Sprintf("%v", value)
} else { } else {

View File

@ -1119,20 +1119,19 @@ func (ib *IfdBuilder) AddTagsFromExisting(ifd *Ifd, itevr *IfdTagEntryValueResol
// It's an undefined-type value. Try to process, or skip if // It's an undefined-type value. Try to process, or skip if
// we don't know how to. // we don't know how to.
x, err := valueContext.Undefined() undefinedInterface, err := valueContext.Undefined()
log.PanicIf(err) if err != nil {
if err == ErrUnhandledUnknownTypedTag {
// It's an undefined-type tag that we don't handle. If
// we don't know how to handle it, we can't know how
// many bytes it is and we must skip it.
continue
}
// TODO(dustin): !! Add test for this. log.Panic(err)
_, isUnknownUndefined := x.(TagUnknownType_UnknownValue)
if isUnknownUndefined == true {
// It's an undefined-type tag that we don't handle. If we
// don't know how to handle it, we can't know how many bytes
// it is and we must skip it.
continue
} }
undefined, ok := x.(UnknownTagValue) undefined, ok := undefinedInterface.(UnknownTagValue)
if ok != true { if ok != true {
log.Panicf("unexpected value returned from undefined-value processor") log.Panicf("unexpected value returned from undefined-value processor")
} }

View File

@ -240,24 +240,31 @@ func (ie *IfdEnumerate) resolveTagValue(ite *IfdTagEntry) (valueBytes []byte, is
valueContext := ie.GetValueContext(ite) valueContext := ie.GetValueContext(ite)
value, err := valueContext.Undefined() value, err := valueContext.Undefined()
log.PanicIf(err) if err != nil {
if err == ErrUnhandledUnknownTypedTag {
valueBytes = []byte(UnparseableUnknownTagValuePlaceholder)
return valueBytes, true, nil
}
switch value.(type) { log.Panic(err)
case []byte: } else {
return value.([]byte), false, nil switch value.(type) {
case TagUnknownType_UnknownValue: case []byte:
b := []byte(value.(TagUnknownType_UnknownValue)) return value.([]byte), false, nil
return b, false, nil case TagUnknownType_UnknownValue:
case string: b := []byte(value.(TagUnknownType_UnknownValue))
return []byte(value.(string)), false, nil return b, false, nil
case UnknownTagValue: case string:
valueBytes, err := value.(UnknownTagValue).ValueBytes() return []byte(value.(string)), false, nil
log.PanicIf(err) case UnknownTagValue:
valueBytes, err := value.(UnknownTagValue).ValueBytes()
log.PanicIf(err)
return valueBytes, false, nil return valueBytes, false, nil
default: default:
// TODO(dustin): !! Finish translating the rest of the types (make reusable and replace into other similar implementations?) // TODO(dustin): !! Finish translating the rest of the types (make reusable and replace into other similar implementations?)
log.Panicf("can not produce bytes for unknown-type tag (0x%04x) (1): [%s]", ite.TagId, reflect.TypeOf(value)) log.Panicf("can not produce bytes for unknown-type tag (0x%04x) (1): [%s]", ite.TagId, reflect.TypeOf(value))
}
} }
} else { } else {
originalType := NewTagType(ite.TagType, ie.byteOrder) originalType := NewTagType(ite.TagType, ie.byteOrder)
@ -709,7 +716,13 @@ func (ifd *Ifd) printTagTree(populateValues bool, index, level int, nextLink boo
var err error var err error
value, err = ifd.TagValue(tag) value, err = ifd.TagValue(tag)
log.PanicIf(err) if err != nil {
if err == ErrUnhandledUnknownTypedTag {
value = UnparseableUnknownTagValuePlaceholder
} else {
log.Panic(err)
}
}
} }
fmt.Printf("%s - TAG: %s NAME=[%s] VALUE=[%v]\n", indent, tag, tagName, value) fmt.Printf("%s - TAG: %s NAME=[%s] VALUE=[%v]\n", indent, tag, tagName, value)

View File

@ -11,6 +11,10 @@ import (
"github.com/dsoprea/go-logging" "github.com/dsoprea/go-logging"
) )
const (
UnparseableUnknownTagValuePlaceholder = "!UNKNOWN"
)
const ( const (
TagUnknownType_9298_UserComment_Encoding_ASCII = iota TagUnknownType_9298_UserComment_Encoding_ASCII = iota
TagUnknownType_9298_UserComment_Encoding_JIS = iota TagUnknownType_9298_UserComment_Encoding_JIS = iota
@ -387,15 +391,7 @@ func UndefinedValue(ifdPath string, tagId uint16, valueContext interface{}, byte
// //
// 0xa40b is device-specific and unhandled. // 0xa40b is device-specific and unhandled.
// Return encapsulated data rather than an error so that we can at least // We have no choice but to return the error. We have no way of knowing how
// print/profile the opaque data. // much data there is without already knowing what data-type this tag is.
return nil, ErrUnhandledUnknownTypedTag
// TODO(dustin): This won't ever work. The unit-count isn't necessarily correct. Revert to returning an error.
valueContextPtr.SetUnknownValueType(TypeByte)
valueBytes, err := valueContextPtr.ReadBytes()
log.PanicIf(err)
tutuv := TagUnknownType_UnknownValue(valueBytes)
return tutuv, nil
} }

View File

@ -84,6 +84,11 @@ var (
// ErrWrongType is used when we try to parse anything other than the // ErrWrongType is used when we try to parse anything other than the
// current type. // current type.
ErrWrongType = errors.New("wrong type, can not parse") ErrWrongType = errors.New("wrong type, can not parse")
// ErrUnhandledUnknownTag is used when we try to parse a tag that's
// recorded as an "unknown" type but not a documented tag (therefore
// leaving us not knowning how to read it).
ErrUnhandledUnknownTypedTag = errors.New("not a standard unknown-typed tag")
) )
type Rational struct { type Rational struct {

View File

@ -182,10 +182,18 @@ func GetFlatExifData(exifData []byte) (exifTags []ExifTag, err error) {
} }
value, err := ifd.TagValue(ite) value, err := ifd.TagValue(ite)
log.PanicIf(err) if err != nil {
if err == ErrUnhandledUnknownTypedTag {
value = UnparseableUnknownTagValuePlaceholder
} else {
log.Panic(err)
}
}
valueBytes, err := ifd.TagValueBytes(ite) valueBytes, err := ifd.TagValueBytes(ite)
log.PanicIf(err) if err != nil && err != ErrUnhandledUnknownTypedTag {
log.Panic(err)
}
et := ExifTag{ et := ExifTag{
IfdPath: ifd.IfdPath, IfdPath: ifd.IfdPath,