Description
We have a library that uses protobuf-net 2.4.x and we have an application which references the library and uses protobuf-net 3.x. Since the library has the DTO's and defines the enums, it's build with EnumPassthru = true attributes. When running the application, protobuf-net 3.x is loaded in as it's the latest version referenced. When the library receives a message with a tuple containing enums, protobuf-net 3 throws out CustomAttributeFormatException: 'EnumPassthru' property specified was not found.
error. In messages where the enums are not in a tuple then protobuf-net 3.x catches the error internally and continues to successfully parse the message.
I think one solution is to put a try catch block around model.FindOrAddAuto in the TupleSerializer, as that will be consistent with the behaviour in RuntimeTypeModel.GetServicesSlow, where the FindOrAddAuto is called from _ = this[type];
.
Alternatively, if EnumPassthru setter only threw if the value is false and to ignore it when it's true, it would solve the problem. Then there won't be any worries of other attributes not being parsed.
If either/both of these suggestions sound good to you I would be happy to create a pull request with the changes.
I have created a small repository which replicates this issue, which can be found here https://github.com/Nik-Rempel/Protobuf-issue-repro.
We got redirect bindings (with Dlls in different directories) to work with .NET4.7.2 but not with .NET core but we don't want to downgrade if possible.
Activity
mgravell commentedon Feb 10, 2022
Yes, this isn't ideal - thanks for spotting, and sorry for delay; I've implemented the "alternatively", as that seems to make a lot of sense here; happy to consider a more robust "handles anything" handler; can you point me at where you saw this being suppressed, if you recall?
Nik-Rempel commentedon Feb 11, 2022
Hi Marc, thanks for you're reply and for implementing it. After investigating this further, I found that I wasn't seeing the exception being thrown from EnumPassthru on enums but EnumPassthru on classes. In this case the exception is being suppressed by the try catch all block in RuntimeTypeModel.GetServicesSlow().
I know now that in the protobuf spec that's not valid and all instances of that have been removed on our side. But it's nice that it was able to ignore the attribute and deserialized into the class.
mgravell commentedon Feb 11, 2022
I'll check GetServiceSlow(), and see if we can do something similar there, too
fix protobuf-net#881; don't throw if EnumPassthru is explicitly set t…