FlagsAttribute is removed on Enums
Hi!
I use a lot of enums with FlagsAttribute which is displayed to the user.
It seems however that SA removes the FlagsAttribute when processing the assembly. I created a short console app:
Output before SA processing looks like:
Output after SA processing looks like:
Using Reflector before SA processing the FlagsTestEnum looks like:
Using Reflector after SA processing the FlagsTestEnum looks like:
Best Regards,
John
I use a lot of enums with FlagsAttribute which is displayed to the user.
It seems however that SA removes the FlagsAttribute when processing the assembly. I created a short console app:
static void Main() { for (var i = 1; i <= 7; i++) { Console.WriteLine((FlagsTestEnum) i); } } [DoNotObfuscateType] [Flags] private enum FlagsTestEnum { FirstValue = 1, SecondValue = 2, ThirdValue = 4 }
Output before SA processing looks like:
FirstValue SecondValue FirstValue, SecondValue ThirdValue FirstValue, ThirdValue SecondValue, ThirdValue FirstValue, SecondValue, ThirdValue
Output after SA processing looks like:
FirstValue SecondValue 3 ThirdValue 5 6 7
Using Reflector before SA processing the FlagsTestEnum looks like:
[Flags, DoNotObfuscateType] private enum FlagsTestEnum { FirstValue = 1, SecondValue = 2, ThirdValue = 4 }
Using Reflector after SA processing the FlagsTestEnum looks like:
private enum FlagsTestEnum { FirstValue = 1, SecondValue = 2, ThirdValue = 4 }As you can see, the FlagsAttribute is missing. How can I put it back?
Best Regards,
John
Comments
You did however put me on the right track, it's the pruning the creates the issue. Enabling pruning creates the issue, disabling it removes the issue.
In SA I can add pruning exception on the "Flags" attribute which makes me able to enable pruning without creating the issue. However, programmaticly adding DoNotPrune or DoNotPruneType doesn't remove the issue.
I think that removing the Flags attribute when both DoNotPruneAttribute and DoNotPruneTypeAttribute are set is an error. What do you think?
SA automaticly detect the ToString() being used on the enum and do not obfuscate the names but still prune the FlagsAttribute. I think that is an error. What do you think?
Best Regards,
John
You can try out ftp://support.red-gate.com/patches/smar ... 6.1.31.zip
This should sort out the enum flags problem.
Patch works nicely, thanks for your help!:D
Best Regards,
John
I am still having issues with this bug.
still results in:
I have the latest version: 6.6.2.35.
I also noticed that the latest version (6.6.2.35) seems to have re-introduced it so my latest release of my software was, well, not as good as it was meant to be. I actually trusted SmartAssembly and didn't test my obfuscated release thoroughly. My bad. :oops:
I found out that you now at least could get it to work by adding the DoNotPrune attribute, that didn't work before. I've added that to all my flags-enums (which I use ToString() on) and is as happy as a bird.
Best Regards,
John
Thanks for your prompt reply. I did just do that, and it worked . At least I can configure SmartAssembly to prune that one class rather than everything.
When can we expect a proper fix? It does seem slightly worrying that we can end up with broken builds if we upgrade SmartAssembly and trust it to work!
Jason
My experience is that Red-Gate has been really responsive so far, so I'd expect they'll respond in the morning.
John
Just another user...
Oops! A little confusion there! Sorry!
I've just had a look at this, and 6.6.1.31 has the same behaviour as 6.6.2.35:
- by default, FlagsAttribute is removed from enums by pruning if they aren't publically accessible on a dll. This is because it doesn't affect the operation of the attribute (apart from ToString) and gives information away about how the attribute is meant to be used
- DoNotPruneAttribute specified on a type stops all attributes from being removed from that type, including FlagsAttribute
- Obfuscation does not affect FlagsAttribute
The fix that went into 6.6.1.31 was that SA was removing attributes even when DoNotPrune was specified.
If this is different to what you are experiencing, do let us know. In particular, project settings or exclusions and whether it's a dll or an exe could be affecting the behaviour. If that is the case, please do email support and they'll have a closer look at what's going on.
With regards to the current behaviour, what do you think SA should do? Should it not remove FlagsAttribute at all (and thus leak information about how it is used), should it try and work out when ToString is used on an enum, similar to the heuristics we use to guess when an enum shouldn't be obfuscated, or some other behaviour?
My [Flags] attribute is used on an Enum which is in turn used by a class (marked as Serialisable) that is serialised to XML. When the object to written the XML the DaysOfWeek property should be written as "Monday Tuesday Wednesday Thursday Friday" for those chosen days. After it has been processed by SmartAssembly, as the [Flags] attribute is no longer there, it fails to serialise/deserialse and results in a crash.
Jason
The vote from the John'ian jury is:
When the heuristics says it's not to be obfuscated (i.e. ToString is used) the flags attribute is to be kept.
Haven't tried HasFlag on an enum that isn't flag, but that obviously has to work regardless.
Best Regards,
John