Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exif struct broken for Go #622

Open
insomniacslk opened this issue Aug 29, 2022 · 2 comments
Open

Exif struct broken for Go #622

insomniacslk opened this issue Aug 29, 2022 · 2 comments

Comments

@insomniacslk
Copy link

insomniacslk commented Aug 29, 2022

Hi, I noticed that image/exif.ksy is broken for Go, the generated files yield the following errors:

./exif.go:164:28: this._parent._is_le undefined (type interface {} is interface with no methods)
./exif.go:853:24: invalid operation: this.Length * tmp27 (mismatched types uint32 and int8)

The type of Exif_ExifBody_Ifd._parent is interface{}, hence the instruction this._is_le = this._parent._is_le fails because it is generated as AnyType instead of being converted to Exif_ExifBody_Ifd.

This happens with both Go 1.17 and Go 1.18.

The issue can be reproduced with the following commands:

curl https://raw.githubusercontent.com/kaitai-io/kaitai_struct_formats/master/image/exif.ksy -o exif.ksy`
ksc -t go --go-package=main exif.ksy
cd main
go mod init test
go mod tidy
go build

I don't have experience with Scala, or I'd have submitted a PR, let me know if I should provide more information.

Thanks!

@insomniacslk
Copy link
Author

I just realized that the compiler cannot infer the right type, because parent could be more than one type (that is, either Exif_ExifBody or Exif_ExifBody_Ifd), so interface{} is the most appropriate here, then it requires runtime type casting to read _is_le properly

@insomniacslk
Copy link
Author

Another (ugly) option is to use reflection. If the type is unknown, the attribute can be resolved at runtime like this:

	// Using reflection to read this._parent._is_le, because this._parent could
	// be one of Exif_ExifBody or Exif_ExifBody_Ifd .
	// Elem() is called two more times, first to resolve the interface, and then to resolve the pointer.
	this._is_le = int(reflect.ValueOf(&this._parent).Elem().Elem().Elem().FieldByName("_is_le").Int())

but I hope there's a better option

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant