1+ using System ;
2+ using System . Collections . Generic ;
3+ using Confuser . Core ;
4+ using Confuser . Renamer . BAML ;
5+ using dnlib . DotNet ;
6+
7+ namespace Confuser . Renamer . Analyzers {
8+ internal class JsonAnalyzer : IRenamer {
9+ public JsonAnalyzer ( ) {
10+ }
11+
12+ const string JsonProperty = "Newtonsoft.Json.JsonPropertyAttribute" ;
13+ const string JsonIgnore = "Newtonsoft.Json.JsonIgnoreAttribute" ;
14+ const string JsonObject = "Newtonsoft.Json.JsonObjectAttribute" ;
15+ static readonly HashSet < string > JsonContainers = new HashSet < string > {
16+ "Newtonsoft.Json.JsonArrayAttribute" ,
17+ "Newtonsoft.Json.JsonContainerAttribute" ,
18+ "Newtonsoft.Json.JsonDictionaryAttribute" ,
19+ "Newtonsoft.Json.JsonObjectAttribute"
20+ } ;
21+
22+ static CustomAttribute GetJsonContainerAttribute ( IHasCustomAttribute attrs ) {
23+ foreach ( var attr in attrs . CustomAttributes ) {
24+ if ( JsonContainers . Contains ( attr . TypeFullName ) )
25+ return attr ;
26+ }
27+ return null ;
28+ }
29+
30+ static bool ShouldExclude ( TypeDef type , IDnlibDef def ) {
31+ CustomAttribute attr ;
32+
33+ if ( def . CustomAttributes . IsDefined ( JsonProperty ) ) {
34+ attr = def . CustomAttributes . Find ( JsonProperty ) ;
35+ if ( attr . HasConstructorArguments || attr . GetProperty ( "PropertyName" ) != null )
36+ return false ;
37+ }
38+
39+ attr = GetJsonContainerAttribute ( type ) ;
40+ if ( attr == null || attr . TypeFullName != JsonObject )
41+ return false ;
42+
43+ if ( def . CustomAttributes . IsDefined ( JsonIgnore ) )
44+ return false ;
45+
46+ int serialization = 0 ;
47+ if ( attr . HasConstructorArguments && attr . ConstructorArguments [ 0 ] . Type . FullName == "Newtonsoft.Json.MemberSerialization" )
48+ serialization = ( int ) attr . ConstructorArguments [ 0 ] . Value ;
49+ else {
50+ foreach ( var property in attr . Properties ) {
51+ if ( property . Name == "MemberSerialization" )
52+ serialization = ( int ) property . Value ;
53+ }
54+ }
55+
56+ if ( serialization == 0 ) { // OptOut
57+ return ( def is PropertyDef && ( ( PropertyDef ) def ) . IsPublic ( ) ) ||
58+ ( def is FieldDef && ( ( FieldDef ) def ) . IsPublic ) ;
59+ }
60+ else if ( serialization == 1 ) // OptIn
61+ return false ;
62+ else if ( serialization == 2 ) // Fields
63+ return def is FieldDef ;
64+ else // Unknown
65+ return false ;
66+ }
67+
68+ public void Analyze ( ConfuserContext context , INameService service , ProtectionParameters parameters , IDnlibDef def ) {
69+ if ( def is TypeDef )
70+ Analyze ( context , service , ( TypeDef ) def , parameters ) ;
71+ else if ( def is MethodDef )
72+ Analyze ( context , service , ( MethodDef ) def , parameters ) ;
73+ else if ( def is PropertyDef )
74+ Analyze ( context , service , ( PropertyDef ) def , parameters ) ;
75+ else if ( def is FieldDef )
76+ Analyze ( context , service , ( FieldDef ) def , parameters ) ;
77+ }
78+
79+ void Analyze ( ConfuserContext context , INameService service , TypeDef type , ProtectionParameters parameters ) {
80+ var attr = GetJsonContainerAttribute ( type ) ;
81+ if ( attr == null )
82+ return ;
83+
84+ bool hasId = false ;
85+ if ( attr . HasConstructorArguments && attr . ConstructorArguments [ 0 ] . Type . FullName == "System.String" )
86+ hasId = true ;
87+ else {
88+ foreach ( var property in attr . Properties ) {
89+ if ( property . Name == "Id" )
90+ hasId = true ;
91+ }
92+ }
93+ if ( ! hasId )
94+ service . SetCanRename ( type , false ) ;
95+ }
96+
97+ void Analyze ( ConfuserContext context , INameService service , MethodDef method , ProtectionParameters parameters ) {
98+ if ( GetJsonContainerAttribute ( method . DeclaringType ) != null && method . IsConstructor ) {
99+ service . SetParam ( method , "renameArgs" , "false" ) ;
100+ }
101+ }
102+
103+ void Analyze ( ConfuserContext context , INameService service , PropertyDef property , ProtectionParameters parameters ) {
104+ if ( ShouldExclude ( property . DeclaringType , property ) ) {
105+ service . SetCanRename ( property , false ) ;
106+ }
107+ }
108+
109+ void Analyze ( ConfuserContext context , INameService service , FieldDef field , ProtectionParameters parameters ) {
110+ if ( ShouldExclude ( field . DeclaringType , field ) ) {
111+ service . SetCanRename ( field , false ) ;
112+ }
113+ }
114+
115+ public void PreRename ( ConfuserContext context , INameService service , ProtectionParameters parameters , IDnlibDef def ) {
116+ //
117+ }
118+
119+ public void PostRename ( ConfuserContext context , INameService service , ProtectionParameters parameters , IDnlibDef def ) {
120+ //
121+ }
122+ }
123+ }
0 commit comments