forked from Taritsyn/JavaScriptEngineSwitcher
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCustomTypeResolvers.cs
More file actions
103 lines (79 loc) · 2.79 KB
/
CustomTypeResolvers.cs
File metadata and controls
103 lines (79 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using OriginalTypeResolver = Jint.Runtime.Interop.TypeResolver;
namespace JavaScriptEngineSwitcher.Jint
{
/// <summary>
/// Interop strategies for different values of the <see cref="JintSettings.AllowReflection"/> configuration property
/// </summary>
internal static class CustomTypeResolvers
{
private static readonly PropertyInfo[] _disallowedProperties =
{
typeof(Delegate).GetProperty("Method"),
typeof(Exception).GetProperty("TargetSite")
};
private static readonly MethodInfo[] _disallowedMethods =
{
typeof(object).GetMethod("GetType"),
typeof(Exception).GetMethod("GetType")
};
private static readonly Lazy<OriginalTypeResolver> _allowingReflection = new Lazy<OriginalTypeResolver>(
() => new OriginalTypeResolver() { MemberFilter = _ => true });
private static readonly Lazy<OriginalTypeResolver> _disallowingReflection = new Lazy<OriginalTypeResolver>(
() => new OriginalTypeResolver() { MemberFilter = IsAllowedMember });
/// <summary>
/// Gets a interop strategy that allows the usage of reflection API in the script code
/// </summary>
public static OriginalTypeResolver AllowingReflection => _allowingReflection.Value;
/// <summary>
/// Gets a interop strategy that disallows the usage of reflection API in the script code
/// </summary>
public static OriginalTypeResolver DisallowingReflection => _disallowingReflection.Value;
private static bool IsAllowedMember(MemberInfo member)
{
bool isAllowed = true;
if (member is PropertyInfo)
{
isAllowed = IsAllowedProperty((PropertyInfo)member);
}
else if (member is MethodInfo)
{
isAllowed = IsAllowedMethod((MethodInfo)member);
}
return isAllowed;
}
[MethodImpl((MethodImplOptions)256 /* AggressiveInlining */)]
private static bool IsAllowedProperty(PropertyInfo property)
{
bool isAllowed = !_disallowedProperties.Contains(property, MemberComparer<PropertyInfo>.Instance);
return isAllowed;
}
[MethodImpl((MethodImplOptions)256 /* AggressiveInlining */)]
private static bool IsAllowedMethod(MethodInfo method)
{
bool isAllowed = !_disallowedMethods.Contains(method, MemberComparer<MethodInfo>.Instance);
return isAllowed;
}
private sealed class MemberComparer<T> : EqualityComparer<T>
where T : MemberInfo
{
public static MemberComparer<T> Instance { get; } = new MemberComparer<T>();
private MemberComparer()
{ }
#region MemberComparer overrides
public override bool Equals(T x, T y)
{
return x.Module == y.Module && x.MetadataToken == y.MetadataToken;
}
public override int GetHashCode(T obj)
{
return obj != null ? obj.GetHashCode() : 0;
}
#endregion
}
}
}