Options

FlagsAttribute is removed on Enums

smudasmuda Posts: 24
edited February 29, 2012 9:15AM in SmartAssembly
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:
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

  • Options
    Brian DonahueBrian Donahue Posts: 6,590 Bronze 1
    I am unable to reproduce this issue - are you using obfuscation (name changing) pruning, and what version of SmartAssembly are you using? I think we had a problems with enums in an older version.
  • Options
    I'm using version 6.6.0.144, which I don't think qualify for "older version". :-)

    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
  • Options
    Brian DonahueBrian Donahue Posts: 6,590 Bronze 1
    I'll upload a private build of SmartAssembly that should fix the problem -- I'll send you an email with the download link once I can make the patch available.
  • Options
    Brian DonahueBrian Donahue Posts: 6,590 Bronze 1
    Hi,

    You can try out ftp://support.red-gate.com/patches/smar ... 6.1.31.zip
    This should sort out the enum flags problem.
  • Options
    I have to admit that was really fast of you to deliver a fix within one working day, well done! :o

    Patch works nicely, thanks for your help!:D

    Best Regards,

    John
  • Options
    Hello,

    I am still having issues with this bug.
        [Flags]
        public enum DaysOfWeekFlags
        {
            NotSet = 0,
            Monday = 1,
            Tuesday = 2,
            Wednesday = 4,
            Thursday = 8,
            Friday = 16,
            Saturday = 32,
            Sunday = 64,
            Every = 127
        }
    

    still results in:
    	public enum DaysOfWeekFlags
    	{
    		NotSet,
    		Monday,
    		Tuesday,
    		Wednesday = 4,
    		Thursday = 8,
    		Friday = 16,
    		Saturday = 32,
    		Sunday = 64,
    		Every = 127
    	}
    

    I have the latest version: 6.6.2.35.
  • Options
    Jasonauk,

    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
  • Options
    Hi 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
  • Options
    Good thing it worked for you! It always feels good helping someone else in the community... :)

    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... :wink:
  • Options
    smuda wrote:
    Just another user... :wink:

    Oops! A little confusion there! Sorry!
  • Options
    Hi smuda, jasonauk.

    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?
  • Options
    Hi Simon,

    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
  • Options
    Hi!

    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
Sign In or Register to comment.