You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,383 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Dispatcher
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.ServiceModel.Description;
|
||||
|
||||
delegate object InvokeDelegate(object target, object[] inputs, object[] outputs);
|
||||
delegate IAsyncResult InvokeBeginDelegate(object target, object[] inputs, AsyncCallback asyncCallback, object state);
|
||||
delegate object InvokeEndDelegate(object target, object[] outputs, IAsyncResult result);
|
||||
delegate object CreateInstanceDelegate();
|
||||
|
||||
sealed class InvokerUtil
|
||||
{
|
||||
[Fx.Tag.SecurityNote(Critical = "Holds instance of CriticalHelper which keeps state that was produced within an assert.")]
|
||||
[SecurityCritical]
|
||||
CriticalHelper helper;
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
|
||||
Safe = "Doesn't leak anything.")]
|
||||
[SecuritySafeCritical]
|
||||
public InvokerUtil()
|
||||
{
|
||||
helper = new CriticalHelper();
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical helper class 'CriticalHelper'.",
|
||||
Safe = "Resultant delegate is self-contained and safe for general consumption, nothing else leaks.")]
|
||||
[SecuritySafeCritical]
|
||||
internal CreateInstanceDelegate GenerateCreateInstanceDelegate(Type type, ConstructorInfo constructor)
|
||||
{
|
||||
return helper.GenerateCreateInstanceDelegate(type, constructor);
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical helper class 'CriticalHelper'.",
|
||||
Safe = "Resultant delegate is self-contained and safe for general consumption, parameter counts are safe, nothing else leaks.")]
|
||||
[SecuritySafeCritical]
|
||||
internal InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount)
|
||||
{
|
||||
return helper.GenerateInvokeDelegate(method, out inputParameterCount, out outputParameterCount);
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical helper class 'CriticalHelper'.",
|
||||
Safe = "Resultant delegate is self-contained and safe for general consumption, parameter counts are safe, nothing else leaks.")]
|
||||
[SecuritySafeCritical]
|
||||
internal InvokeBeginDelegate GenerateInvokeBeginDelegate(MethodInfo method, out int inputParameterCount)
|
||||
{
|
||||
return helper.GenerateInvokeBeginDelegate(method, out inputParameterCount);
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical helper class 'CriticalHelper'.",
|
||||
Safe = "Resultant delegate is self-contained and safe for general consumption, parameter counts are safe, nothing else leaks.")]
|
||||
[SecuritySafeCritical]
|
||||
internal InvokeEndDelegate GenerateInvokeEndDelegate(MethodInfo method, out int outputParameterCount)
|
||||
{
|
||||
return helper.GenerateInvokeEndDelegate(method, out outputParameterCount);
|
||||
}
|
||||
|
||||
[Fx.Tag.SecurityNote(Critical = "Handles all aspects of IL generation including initializing the DynamicMethod, which requires an elevation."
|
||||
+ "Since the ILGenerator is created under an elevation, we lock down access to every aspect of the generation.")]
|
||||
#pragma warning disable 618 // have not moved to the v4 security model yet
|
||||
[SecurityCritical(SecurityCriticalScope.Everything)]
|
||||
#pragma warning restore 618
|
||||
class CriticalHelper
|
||||
{
|
||||
static Type TypeOfObject = typeof(object);
|
||||
|
||||
CodeGenerator ilg;
|
||||
|
||||
internal CreateInstanceDelegate GenerateCreateInstanceDelegate(Type type, ConstructorInfo constructor)
|
||||
{
|
||||
bool requiresMemberAccess = !IsTypeVisible(type) || ConstructorRequiresMemberAccess(constructor);
|
||||
|
||||
this.ilg = new CodeGenerator();
|
||||
try
|
||||
{
|
||||
ilg.BeginMethod("Create" + type.FullName, typeof(CreateInstanceDelegate), requiresMemberAccess);
|
||||
}
|
||||
catch (SecurityException securityException)
|
||||
{
|
||||
if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
|
||||
{
|
||||
DiagnosticUtility.TraceHandledException(securityException, TraceEventType.Warning);
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new SecurityException(SR.GetString(
|
||||
SR.PartialTrustServiceCtorNotVisible,
|
||||
type.FullName)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (type.IsValueType)
|
||||
{
|
||||
LocalBuilder instanceLocal = ilg.DeclareLocal(type, type.Name + "Instance");
|
||||
ilg.LoadZeroValueIntoLocal(type, instanceLocal);
|
||||
ilg.Load(instanceLocal);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.New(constructor);
|
||||
}
|
||||
ilg.ConvertValue(type, ilg.CurrentMethod.ReturnType);
|
||||
return (CreateInstanceDelegate)ilg.EndMethod();
|
||||
}
|
||||
|
||||
internal InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount)
|
||||
{
|
||||
bool requiresMemberAccess = MethodRequiresMemberAccess(method);
|
||||
|
||||
this.ilg = new CodeGenerator();
|
||||
try
|
||||
{
|
||||
this.ilg.BeginMethod("SyncInvoke" + method.Name, typeof(InvokeDelegate), requiresMemberAccess);
|
||||
}
|
||||
catch (SecurityException securityException)
|
||||
{
|
||||
if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
|
||||
{
|
||||
DiagnosticUtility.TraceHandledException(securityException, TraceEventType.Warning);
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new SecurityException(SR.GetString(
|
||||
SR.PartialTrustServiceMethodNotVisible,
|
||||
method.DeclaringType.FullName,
|
||||
method.Name)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
ArgBuilder targetArg = ilg.GetArg(0);
|
||||
ArgBuilder inputParametersArg = ilg.GetArg(1);
|
||||
ArgBuilder outputParametersArg = ilg.GetArg(2);
|
||||
|
||||
ParameterInfo[] parameters = method.GetParameters();
|
||||
LocalBuilder returnLocal = ilg.DeclareLocal(ilg.CurrentMethod.ReturnType, "returnParam");
|
||||
LocalBuilder[] parameterLocals = new LocalBuilder[parameters.Length];
|
||||
DeclareParameterLocals(parameters, parameterLocals);
|
||||
|
||||
LoadInputParametersIntoLocals(parameters, parameterLocals, inputParametersArg, out inputParameterCount);
|
||||
LoadTarget(targetArg, method.ReflectedType);
|
||||
LoadParameters(parameters, parameterLocals);
|
||||
InvokeMethod(method, returnLocal);
|
||||
LoadOutputParametersIntoArray(parameters, parameterLocals, outputParametersArg, out outputParameterCount);
|
||||
|
||||
ilg.Load(returnLocal);
|
||||
return (InvokeDelegate)this.ilg.EndMethod();
|
||||
}
|
||||
|
||||
internal InvokeBeginDelegate GenerateInvokeBeginDelegate(MethodInfo method, out int inputParameterCount)
|
||||
{
|
||||
bool requiresMemberAccess = MethodRequiresMemberAccess(method);
|
||||
|
||||
this.ilg = new CodeGenerator();
|
||||
try
|
||||
{
|
||||
this.ilg.BeginMethod("AsyncInvokeBegin" + method.Name, typeof(InvokeBeginDelegate), requiresMemberAccess);
|
||||
}
|
||||
catch (SecurityException securityException)
|
||||
{
|
||||
if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
|
||||
{
|
||||
DiagnosticUtility.TraceHandledException(securityException, TraceEventType.Warning);
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new SecurityException(SR.GetString(
|
||||
SR.PartialTrustServiceMethodNotVisible,
|
||||
method.DeclaringType.FullName,
|
||||
method.Name)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
ArgBuilder targetArg = ilg.GetArg(0);
|
||||
ArgBuilder inputParametersArg = ilg.GetArg(1);
|
||||
ArgBuilder callbackArg = ilg.GetArg(2);
|
||||
ArgBuilder stateArg = ilg.GetArg(3);
|
||||
|
||||
ParameterInfo[] parameters = method.GetParameters();
|
||||
LocalBuilder returnLocal = ilg.DeclareLocal(ilg.CurrentMethod.ReturnType, "returnParam");
|
||||
LocalBuilder[] parameterLocals = new LocalBuilder[parameters.Length - 2];
|
||||
DeclareParameterLocals(parameters, parameterLocals);
|
||||
|
||||
LoadInputParametersIntoLocals(parameters, parameterLocals, inputParametersArg, out inputParameterCount);
|
||||
LoadTarget(targetArg, method.ReflectedType);
|
||||
LoadParameters(parameters, parameterLocals);
|
||||
ilg.Load(callbackArg);
|
||||
ilg.Load(stateArg);
|
||||
InvokeMethod(method, returnLocal);
|
||||
|
||||
ilg.Load(returnLocal);
|
||||
return (InvokeBeginDelegate)this.ilg.EndMethod();
|
||||
}
|
||||
|
||||
internal InvokeEndDelegate GenerateInvokeEndDelegate(MethodInfo method, out int outputParameterCount)
|
||||
{
|
||||
bool requiresMemberAccess = MethodRequiresMemberAccess(method);
|
||||
|
||||
this.ilg = new CodeGenerator();
|
||||
try
|
||||
{
|
||||
this.ilg.BeginMethod("AsyncInvokeEnd" + method.Name, typeof(InvokeEndDelegate), requiresMemberAccess);
|
||||
}
|
||||
catch (SecurityException securityException)
|
||||
{
|
||||
if (requiresMemberAccess && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
|
||||
{
|
||||
DiagnosticUtility.TraceHandledException(securityException, TraceEventType.Warning);
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new SecurityException(SR.GetString(
|
||||
SR.PartialTrustServiceMethodNotVisible,
|
||||
method.DeclaringType.FullName,
|
||||
method.Name)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
ArgBuilder targetArg = ilg.GetArg(0);
|
||||
ArgBuilder outputParametersArg = ilg.GetArg(1);
|
||||
ArgBuilder resultArg = ilg.GetArg(2);
|
||||
|
||||
ParameterInfo[] parameters = method.GetParameters();
|
||||
LocalBuilder returnLocal = ilg.DeclareLocal(ilg.CurrentMethod.ReturnType, "returnParam");
|
||||
LocalBuilder[] parameterLocals = new LocalBuilder[parameters.Length - 1];
|
||||
DeclareParameterLocals(parameters, parameterLocals);
|
||||
|
||||
LoadZeroValueInputParametersIntoLocals(parameters, parameterLocals);
|
||||
LoadTarget(targetArg, method.ReflectedType);
|
||||
LoadParameters(parameters, parameterLocals);
|
||||
ilg.Load(resultArg);
|
||||
InvokeMethod(method, returnLocal);
|
||||
LoadOutputParametersIntoArray(parameters, parameterLocals, outputParametersArg, out outputParameterCount);
|
||||
|
||||
ilg.Load(returnLocal);
|
||||
return (InvokeEndDelegate)this.ilg.EndMethod();
|
||||
}
|
||||
|
||||
void DeclareParameterLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals)
|
||||
{
|
||||
for (int i = 0; i < parameterLocals.Length; i++)
|
||||
{
|
||||
parameterLocals[i] = ilg.DeclareLocal(TypeLoader.GetParameterType(parameters[i]), "param" + i.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
|
||||
void LoadInputParametersIntoLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals, ArgBuilder inputParametersArg, out int inputParameterCount)
|
||||
{
|
||||
inputParameterCount = 0;
|
||||
for (int i = 0; i < parameterLocals.Length; i++)
|
||||
{
|
||||
if (ServiceReflector.FlowsIn(parameters[i]))
|
||||
{
|
||||
Type parameterType = parameterLocals[i].LocalType;
|
||||
ilg.LoadArrayElement(inputParametersArg, inputParameterCount);
|
||||
if (!parameterType.IsValueType)
|
||||
{
|
||||
ilg.ConvertValue(TypeOfObject, parameterType);
|
||||
ilg.Store(parameterLocals[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Dup();
|
||||
ilg.If();
|
||||
ilg.ConvertValue(TypeOfObject, parameterType);
|
||||
ilg.Store(parameterLocals[i]);
|
||||
ilg.Else();
|
||||
ilg.Pop();
|
||||
ilg.LoadZeroValueIntoLocal(parameterType, parameterLocals[i]);
|
||||
ilg.EndIf();
|
||||
}
|
||||
inputParameterCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoadZeroValueInputParametersIntoLocals(ParameterInfo[] parameters, LocalBuilder[] parameterLocals)
|
||||
{
|
||||
for (int i = 0; i < parameterLocals.Length; i++)
|
||||
{
|
||||
if (ServiceReflector.FlowsIn(parameters[i]))
|
||||
{
|
||||
ilg.LoadZeroValueIntoLocal(parameterLocals[i].LocalType, parameterLocals[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoadTarget(ArgBuilder targetArg, Type targetType)
|
||||
{
|
||||
ilg.Load(targetArg);
|
||||
ilg.ConvertValue(targetArg.ArgType, targetType);
|
||||
if (targetType.IsValueType)
|
||||
{
|
||||
LocalBuilder targetLocal = ilg.DeclareLocal(targetType, "target");
|
||||
ilg.Store(targetLocal);
|
||||
ilg.LoadAddress(targetLocal);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadParameters(ParameterInfo[] parameters, LocalBuilder[] parameterLocals)
|
||||
{
|
||||
for (int i = 0; i < parameterLocals.Length; i++)
|
||||
{
|
||||
if (parameters[i].ParameterType.IsByRef)
|
||||
ilg.Ldloca(parameterLocals[i]);
|
||||
else
|
||||
ilg.Ldloc(parameterLocals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void InvokeMethod(MethodInfo method, LocalBuilder returnLocal)
|
||||
{
|
||||
ilg.Call(method);
|
||||
if (method.ReturnType == typeof(void))
|
||||
ilg.Load(null);
|
||||
else
|
||||
ilg.ConvertValue(method.ReturnType, ilg.CurrentMethod.ReturnType);
|
||||
ilg.Store(returnLocal);
|
||||
}
|
||||
|
||||
void LoadOutputParametersIntoArray(ParameterInfo[] parameters, LocalBuilder[] parameterLocals, ArgBuilder outputParametersArg, out int outputParameterCount)
|
||||
{
|
||||
outputParameterCount = 0;
|
||||
for (int i = 0; i < parameterLocals.Length; i++)
|
||||
{
|
||||
if (ServiceReflector.FlowsOut(parameters[i]))
|
||||
{
|
||||
ilg.Load(outputParametersArg);
|
||||
ilg.Load(outputParameterCount);
|
||||
ilg.Load(parameterLocals[i]);
|
||||
ilg.ConvertValue(parameterLocals[i].LocalType, TypeOfObject);
|
||||
ilg.Stelem(TypeOfObject);
|
||||
outputParameterCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsTypeVisible(Type t)
|
||||
{
|
||||
if (t.Module == typeof(InvokerUtil).Module)
|
||||
return true;
|
||||
|
||||
if (!t.IsVisible)
|
||||
return false;
|
||||
|
||||
foreach (Type genericType in t.GetGenericArguments())
|
||||
{
|
||||
if (!genericType.IsGenericParameter && !IsTypeVisible(genericType))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ConstructorRequiresMemberAccess(ConstructorInfo ctor)
|
||||
{
|
||||
return ctor != null && (!ctor.IsPublic || !IsTypeVisible(ctor.DeclaringType)) && ctor.Module != typeof(InvokerUtil).Module;
|
||||
}
|
||||
|
||||
static bool MethodRequiresMemberAccess(MethodInfo method)
|
||||
{
|
||||
return method != null && (!method.IsPublic || !IsTypeVisible(method.DeclaringType)) && method.Module != typeof(InvokerUtil).Module;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user