FlagsAttribute is removed on Enums

.NET obfuscator and automated error reporting

Moderators: Luke Jefferson, melvyn.harbour, dom.smith

FlagsAttribute is removed on Enums

Postby smuda » Sun Jan 22, 2012 8:01 am

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:

Code: Select all
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:
Code: Select all
FirstValue
SecondValue
FirstValue, SecondValue
ThirdValue
FirstValue, ThirdValue
SecondValue, ThirdValue
FirstValue, SecondValue, ThirdValue



Output after SA processing looks like:
Code: Select all
FirstValue
SecondValue
3
ThirdValue
5
6
7


Using Reflector before SA processing the FlagsTestEnum looks like:
Code: Select all
[Flags, DoNotObfuscateType]
private enum FlagsTestEnum
{
    FirstValue = 1,
    SecondValue = 2,
    ThirdValue = 4
}



Using Reflector after SA processing the FlagsTestEnum looks like:
Code: Select all
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
smuda
 
Posts: 18
Joined: Sun Jan 08, 2012 3:12 pm
Location: Sweden

Postby Brian Donahue » Mon Jan 23, 2012 4:00 pm

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.
Brian Donahue
 
Posts: 6668
Joined: Mon Aug 23, 2004 10:48 am

Postby smuda » Mon Jan 23, 2012 7:57 pm

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
smuda
 
Posts: 18
Joined: Sun Jan 08, 2012 3:12 pm
Location: Sweden

Postby Brian Donahue » Tue Jan 24, 2012 12:57 pm

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.
Brian Donahue
 
Posts: 6668
Joined: Mon Aug 23, 2004 10:48 am

Postby Brian Donahue » Tue Jan 24, 2012 4:59 pm

Hi,

You can try out ftp://support.red-gate.com/patches/smar ... 6.1.31.zip
This should sort out the enum flags problem.
Brian Donahue
 
Posts: 6668
Joined: Mon Aug 23, 2004 10:48 am

Postby smuda » Tue Jan 24, 2012 10:13 pm

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
smuda
 
Posts: 18
Joined: Sun Jan 08, 2012 3:12 pm
Location: Sweden

Postby jasonauk » Tue Feb 28, 2012 9:47 pm

Hello,

I am still having issues with this bug.

Code: Select all
    [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:

Code: Select all
   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.
jasonauk
 
Posts: 4
Joined: Tue Feb 28, 2012 9:40 pm

Postby smuda » Tue Feb 28, 2012 10:00 pm

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
smuda
 
Posts: 18
Joined: Sun Jan 08, 2012 3:12 pm
Location: Sweden

Postby jasonauk » Tue Feb 28, 2012 10:03 pm

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
jasonauk
 
Posts: 4
Joined: Tue Feb 28, 2012 9:40 pm

Postby smuda » Tue Feb 28, 2012 10:10 pm

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:
smuda
 
Posts: 18
Joined: Sun Jan 08, 2012 3:12 pm
Location: Sweden

Re:

Postby jasonauk » Tue Feb 28, 2012 10:19 pm

smuda wrote:Just another user... :wink:


Oops! A little confusion there! Sorry!
jasonauk
 
Posts: 4
Joined: Tue Feb 28, 2012 9:40 pm

Postby Simon C » Wed Feb 29, 2012 1:30 pm

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?
Simon C
 
Posts: 140
Joined: Tue Feb 26, 2008 4:56 pm
Location: Red Gate Software

Postby jasonauk » Wed Feb 29, 2012 2:19 pm

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
jasonauk
 
Posts: 4
Joined: Tue Feb 28, 2012 9:40 pm

Postby smuda » Wed Feb 29, 2012 3:15 pm

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
smuda
 
Posts: 18
Joined: Sun Jan 08, 2012 3:12 pm
Location: Sweden


Return to SmartAssembly 6

Who is online

Users browsing this forum: No registered users and 0 guests