made Spring.NET partial trust ready

This commit is contained in:
eeichinger
2009-05-19 04:09:27 +00:00
parent 04ff7801f7
commit c356bc76a0
41 changed files with 3264 additions and 2120 deletions

View File

@@ -21,19 +21,19 @@ public partial class DataBinding_EmployeeInfo_Default : Spring.Web.UI.Page
/// </summary>
protected override void InitializeDataBindings()
{
BindingManager.AddBinding("txtId.Text", "Employee.Id");
BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth");
BindingManager.AddBinding("txtSalary.Text", "Employee.Salary");
BindingManager.AddBinding("rbgGender.Value", "Employee.Gender");
BindingManager.AddBinding("ddlAddressType.SelectedValue", "Employee.MailingAddress.AddressType");
BindingManager.AddBinding("txtStreet1.Text", "Employee.MailingAddress.Street1");
BindingManager.AddBinding("txtStreet2.Text", "Employee.MailingAddress.Street2");
BindingManager.AddBinding("txtCity.Text", "Employee.MailingAddress.City");
BindingManager.AddBinding("txtState.Text", "Employee.MailingAddress.State");
BindingManager.AddBinding("txtPostalCode.Text", "Employee.MailingAddress.PostalCode");
BindingManager.AddBinding("txtCountry.Text", "Employee.MailingAddress.Country");
BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id");
BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
BindingManager.AddBinding("FindControl('txtLastName').Text", "Employee.LastName");
BindingManager.AddBinding("FindControl('txtDOB').Text", "Employee.DateOfBirth");
BindingManager.AddBinding("FindControl('txtSalary').Text", "Employee.Salary");
BindingManager.AddBinding("FindControl('rbgGender').Value", "Employee.Gender");
BindingManager.AddBinding("FindControl('ddlAddressType').SelectedValue", "Employee.MailingAddress.AddressType");
BindingManager.AddBinding("FindControl('txtStreet1').Text", "Employee.MailingAddress.Street1");
BindingManager.AddBinding("FindControl('txtStreet2').Text", "Employee.MailingAddress.Street2");
BindingManager.AddBinding("FindControl('txtCity').Text", "Employee.MailingAddress.City");
BindingManager.AddBinding("FindControl('txtState').Text", "Employee.MailingAddress.State");
BindingManager.AddBinding("FindControl('txtPostalCode').Text", "Employee.MailingAddress.PostalCode");
BindingManager.AddBinding("FindControl('txtCountry').Text", "Employee.MailingAddress.Country");
}
protected void Page_Load(object sender, EventArgs e)

View File

@@ -1,4 +1,4 @@
<%@ Page Language="C#" EnableViewState="false" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="DataBinding_EventHandling_Default" %>
<%@ Page Language="C#" Debug="true" EnableViewState="false" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="DataBinding_EventHandling_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

View File

@@ -1,4 +1,5 @@
using System;
using System.Web.UI.WebControls;
using Spring.DataBinding;
/// <summary>
@@ -22,8 +23,8 @@ public partial class DataBinding_EventHandling_Default : Spring.Web.UI.Page
/// </summary>
protected override void InitializeDataBindings()
{
BindingManager.AddBinding("txtName.Text", "Name");
BindingManager.AddBinding("lblName.Text", "Name", BindingDirection.TargetToSource);
BindingManager.AddBinding("FindControl('txtName').Text", "Name");
BindingManager.AddBinding("FindControl('lblName').Text", "Name", BindingDirection.TargetToSource);
}
protected void Page_Load(object sender, EventArgs e)

View File

@@ -22,8 +22,8 @@ public partial class DataBinding_HelloWorld_Default : Spring.Web.UI.Page
/// </summary>
protected override void InitializeDataBindings()
{
BindingManager.AddBinding("txtName.Text", "Name");
BindingManager.AddBinding("lblName.Text", "Name", BindingDirection.TargetToSource);
BindingManager.AddBinding("FindControl('txtName').Text", "Name");
BindingManager.AddBinding("FindControl('lblName').Text", "Name", BindingDirection.TargetToSource);
}
protected void Page_Load(object sender, EventArgs e)

View File

@@ -26,19 +26,19 @@ public partial class DataBinding_Lists_Default : Page
/// </summary>
protected override void InitializeDataBindings()
{
BindingManager.AddBinding("txtId.Text", "Employee.Id");
BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id");
BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
// this is rather verbose to show how it works
// the formatter must convert between ListControl values and domain objects identified by these values (e.g. a key)
IFormatter dsFormatter = new DataSourceItemFormatter("DataSource", "DataValueField");
// bind the lstHobbies control to Employee.Hobbies IList
MultipleSelectionListControlBinding listBinding = new MultipleSelectionListControlBinding("lstHobbies", "Employee.Hobbies", BindingDirection.Bidirectional, dsFormatter);
MultipleSelectionListControlBinding listBinding = new MultipleSelectionListControlBinding("FindControl('lstHobbies')", "Employee.Hobbies", BindingDirection.Bidirectional, dsFormatter);
BindingManager.AddBinding(listBinding);
// use simple name=value binding
BindingManager.AddBinding(new MultipleSelectionListControlBinding("lstFavoriteFood", "Employee.FavoriteFood", BindingDirection.Bidirectional, new NullFormatter()));
BindingManager.AddBinding(new MultipleSelectionListControlBinding("FindControl('lstFavoriteFood')", "Employee.FavoriteFood", BindingDirection.Bidirectional, new NullFormatter()));
}
protected override void OnInitializeControls(EventArgs e)

View File

@@ -18,22 +18,22 @@ public partial class EmployeeInfoEditor : Spring.Web.UI.UserControl
/// </summary>
protected override void InitializeDataBindings()
{
BindingManager.AddBinding("txtId.Text", "Employee.Id")
BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id")
.SetErrorMessage("ID has to be an integer", "id.errors", "summary");
BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth")
BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
BindingManager.AddBinding("FindControl('txtLastName').Text", "Employee.LastName");
BindingManager.AddBinding("FindControl('txtDOB').Text", "Employee.DateOfBirth")
.SetErrorMessage("Invalid date value", "dob.errors", "summary");
BindingManager.AddBinding("txtSalary.Text", "Employee.Salary", new CurrencyFormatter())
BindingManager.AddBinding("FindControl('txtSalary').Text", "Employee.Salary", new CurrencyFormatter())
.SetErrorMessage("Salary must be a valid currency value.", "salary.errors", "summary");
BindingManager.AddBinding("rbgGender.Value", "Employee.Gender");
BindingManager.AddBinding("ddlAddressType.SelectedValue", "Employee.MailingAddress.AddressType");
BindingManager.AddBinding("txtStreet1.Text", "Employee.MailingAddress.Street1");
BindingManager.AddBinding("txtStreet2.Text", "Employee.MailingAddress.Street2");
BindingManager.AddBinding("txtCity.Text", "Employee.MailingAddress.City");
BindingManager.AddBinding("txtState.Text", "Employee.MailingAddress.State");
BindingManager.AddBinding("txtPostalCode.Text", "Employee.MailingAddress.PostalCode");
BindingManager.AddBinding("txtCountry.Text", "Employee.MailingAddress.Country");
BindingManager.AddBinding("FindControl('rbgGender').Value", "Employee.Gender");
BindingManager.AddBinding("FindControl('ddlAddressType').SelectedValue", "Employee.MailingAddress.AddressType");
BindingManager.AddBinding("FindControl('txtStreet1').Text", "Employee.MailingAddress.Street1");
BindingManager.AddBinding("FindControl('txtStreet2').Text", "Employee.MailingAddress.Street2");
BindingManager.AddBinding("FindControl('txtCity').Text", "Employee.MailingAddress.City");
BindingManager.AddBinding("FindControl('txtState').Text", "Employee.MailingAddress.State");
BindingManager.AddBinding("FindControl('txtPostalCode').Text", "Employee.MailingAddress.PostalCode");
BindingManager.AddBinding("FindControl('txtCountry').Text", "Employee.MailingAddress.Country");
}
protected void btnSave_Click(object sender, EventArgs e)

View File

@@ -34,7 +34,7 @@
so you can see how Employee object was populated by the framework.
</p>
<!-- this summary control captures validation errors on this page -->
<spring:ValidationSummary ID="summary" Provider="summary" ValidationContainerName="Editor" runat="server" />
<spring:ValidationSummary ID="summary" Provider="summary" runat="server" />
<table cellpadding="3" cellspacing="3" border="0">
<tr>
<td>Employee ID:</td>

View File

@@ -22,22 +22,26 @@ public partial class DataBinding_RobustEmployeeInfo_Default : Spring.Web.UI.Page
/// </summary>
protected override void InitializeDataBindings()
{
BindingManager.AddBinding("txtId.Text", "Employee.Id")
// the line below would also work in full trusted environments due to control members
// being generated as protected members by ASP.NET:
// BindingManager.AddBinding("txtId.Text", "Employee.Id")
BindingManager.AddBinding("FindControl('txtId').Text", "Employee.Id")
.SetErrorMessage("ID has to be an integer", "id.errors"); // send msg to "id.errors" provider
BindingManager.AddBinding("txtFirstName.Text", "Employee.FirstName");
BindingManager.AddBinding("txtLastName.Text", "Employee.LastName");
BindingManager.AddBinding("txtDOB.Text", "Employee.DateOfBirth")
BindingManager.AddBinding("FindControl('txtFirstName').Text", "Employee.FirstName");
BindingManager.AddBinding("FindControl('txtLastName').Text", "Employee.LastName");
BindingManager.AddBinding("FindControl('txtDOB').Text", "Employee.DateOfBirth")
.SetErrorMessage("Invalid date value", "dob.errors");
BindingManager.AddBinding("txtSalary.Text", "Employee.Salary", new CurrencyFormatter())
BindingManager.AddBinding("FindControl('txtSalary').Text", "Employee.Salary", new CurrencyFormatter())
.SetErrorMessage("Salary must be a valid currency value.", "salary.errors");
BindingManager.AddBinding("rbgGender.Value", "Employee.Gender");
BindingManager.AddBinding("ddlAddressType.SelectedValue", "Employee.MailingAddress.AddressType");
BindingManager.AddBinding("txtStreet1.Text", "Employee.MailingAddress.Street1");
BindingManager.AddBinding("txtStreet2.Text", "Employee.MailingAddress.Street2");
BindingManager.AddBinding("txtCity.Text", "Employee.MailingAddress.City");
BindingManager.AddBinding("txtState.Text", "Employee.MailingAddress.State");
BindingManager.AddBinding("txtPostalCode.Text", "Employee.MailingAddress.PostalCode");
BindingManager.AddBinding("txtCountry.Text", "Employee.MailingAddress.Country");
BindingManager.AddBinding("FindControl('rbgGender').Value", "Employee.Gender");
BindingManager.AddBinding("FindControl('ddlAddressType').SelectedValue", "Employee.MailingAddress.AddressType");
BindingManager.AddBinding("FindControl('txtStreet1').Text", "Employee.MailingAddress.Street1");
BindingManager.AddBinding("FindControl('txtStreet2').Text", "Employee.MailingAddress.Street2");
BindingManager.AddBinding("FindControl('txtCity').Text", "Employee.MailingAddress.City");
BindingManager.AddBinding("FindControl('txtState').Text", "Employee.MailingAddress.State");
BindingManager.AddBinding("FindControl('txtPostalCode').Text", "Employee.MailingAddress.PostalCode");
BindingManager.AddBinding("FindControl('txtCountry').Text", "Employee.MailingAddress.Country");
}
protected void Page_Load(object sender, EventArgs e)

View File

@@ -7,7 +7,7 @@
Spring.Web allows for "symbolic" names for navigation targets and navigate to such a target by
calling SetResult( symbolicName ) on the page object.
</p>
<spring:DataBindingPanel runat="server">
<spring:DataBindingPanel ID="ctlDataBindingPanel" runat="server">
<table cellpadding="3" cellspacing="3" border="0">
<spring:Panel VisibleIf="Context.Request['fromInvalidInput'] != null" runat="server">
<tr>

View File

@@ -2,11 +2,11 @@
<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web" requirePermission="false"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" requirePermission="false"/>
</sectionGroup>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" requirePermission="false"/>
</sectionGroup>
</configSections>
<!-- to see logging output in the attached debugger -->
@@ -18,6 +18,13 @@
</logging>
</common>
<system.web>
<securityPolicy>
<trustLevel name="Custom" policyFile="web_mediumtrust.config"/>
</securityPolicy>
<trust level="Full" /> <!-- install Spring assemblies in GAC and change to level to 'Custom' to run in partial trust -->
<globalization culture="en-US" uiCulture="en-US"/>
<customErrors mode="Off"/>
<compilation debug="true">
</compilation>
@@ -31,9 +38,9 @@
-->
<httpModules>
<add name="SpringModule" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
<add name="HtmlCommentAppender" type="HtmlCommentAppenderModule"/>
<!-- this custom module is only for DI demonstration purposes -->
</httpModules>
<!-- this custom module is only for DI demonstration purposes -->
<add name="HtmlCommentAppender" type="HtmlCommentAppenderModule"/>
</httpModules>
<httpHandlers>
<add verb="*" path="*.aspx" type="Spring.Web.Support.PageHandlerFactory, Spring.Web"/>
</httpHandlers>

View File

@@ -0,0 +1,74 @@
<configuration>
<mscorlib>
<security>
<policy>
<PolicyLevel version="1">
<SecurityClasses>
<SecurityClass Name="AllMembershipCondition" Description="System.Security.Policy.AllMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="AspNetHostingPermission" Description="System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="DnsPermission" Description="System.Net.DnsPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="EnvironmentPermission" Description="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="FileIOPermission" Description="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="FirstMatchCodeGroup" Description="System.Security.Policy.FirstMatchCodeGroup, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="IsolatedStorageFilePermission" Description="System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="NamedPermissionSet" Description="System.Security.NamedPermissionSet"/>
<SecurityClass Name="PrintingPermission" Description="System.Drawing.Printing.PrintingPermission, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
<SecurityClass Name="SecurityPermission" Description="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="SmtpPermission" Description="System.Net.Mail.SmtpPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="SqlClientPermission" Description="System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="StrongNameMembershipCondition" Description="System.Security.Policy.StrongNameMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="UIPermission" Description="System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="UnionCodeGroup" Description="System.Security.Policy.UnionCodeGroup, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="UrlMembershipCondition" Description="System.Security.Policy.UrlMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="WebPermission" Description="System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="ZoneMembershipCondition" Description="System.Security.Policy.ZoneMembershipCondition, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<SecurityClass Name="ReflectionPermission" Description="System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/></SecurityClasses>
<NamedPermissionSets>
<PermissionSet class="NamedPermissionSet" version="1" Unrestricted="true" Name="FullTrust" Description="Allows full access to all resources"/>
<PermissionSet class="NamedPermissionSet" version="1" Name="Nothing" Description="Denies all resources, including the right to execute"/>
<PermissionSet class="NamedPermissionSet" version="1" Name="ASP.Net">
<IPermission class="AspNetHostingPermission" version="1" Level="Medium"/>
<IPermission class="DnsPermission" version="1" Unrestricted="true"/>
<IPermission class="EnvironmentPermission" version="1" Read="TEMP;TMP;USERNAME;OS;COMPUTERNAME"/>
<IPermission class="FileIOPermission" version="1" Read="$AppDir$" Write="$AppDir$" Append="$AppDir$" PathDiscovery="$AppDir$"/>
<IPermission class="IsolatedStorageFilePermission" version="1" Allowed="AssemblyIsolationByUser" UserQuota="9223372036854775807"/>
<IPermission class="PrintingPermission" version="1" Level="DefaultPrinting"/>
<IPermission class="SecurityPermission" version="1" Flags="Assertion, Execution, ControlThread, ControlPrincipal, RemotingConfiguration"/>
<IPermission class="SmtpPermission" version="1" Access="Connect"/>
<IPermission class="SqlClientPermission" version="1" Unrestricted="true"/>
<IPermission class="WebPermission" version="1">
<ConnectAccess>
<URI uri="$OriginHost$"/>
</ConnectAccess>
</IPermission>
<IPermission class="ReflectionPermission" version="1" Flags="RestrictedMemberAccess"/></PermissionSet>
</NamedPermissionSets>
<CodeGroup class="FirstMatchCodeGroup" version="1" PermissionSetName="Nothing">
<IMembershipCondition class="AllMembershipCondition" version="1"/>
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="NetCommon_Strong_Name" Description="This code group grants code signed with the NetCommon strong name full trust. ">
<IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100f14d9774aa0ccf08735569d219a51874fc424da7375e4951e1be94416cd27ad28615485a08145acad9b624e0d71f78972051eba675e203eff9b72710b5b68ba970afdccdec36f5ccc4ae30f2962915333fbaba9801da256f0382e201b025b7bb22a835be59cca993e2dec9b8c2ce4738b697087430a37470d0889987b0af8fab"/>
</CodeGroup>
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Spring_Strong_Name" Description="This code group grants code signed with the Spring.NET strong name full trust. ">
<IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="0024000004800000940000000602000000240000525341310004000001000100b5af6fc0c5a1a93adbee2cb424fe0a23ca6430fe0620dd9a00393be236e5d8ab481c8ad4a68c35a62e474695d63658313e4f35a2f29cd38c072f73227eaec5f0b6fb6f9e0ed6ab4f105a393f709eae6cfd010febebb004dd230d51b5e8aec839b6832c21ec7ac3b6cadba8d9b8870b1ab1507cabea54dcacd2c74ea45231a3bd"/>
</CodeGroup>
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="ASP.Net">
<IMembershipCondition class="UrlMembershipCondition" version="1" Url="$AppDirUrl$/*"/>
</CodeGroup>
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="ASP.Net">
<IMembershipCondition class="UrlMembershipCondition" version="1" Url="$CodeGen$/*"/>
</CodeGroup>
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="Nothing">
<IMembershipCondition class="ZoneMembershipCondition" version="1" Zone="MyComputer"/>
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Microsoft_Strong_Name" Description="This code group grants code signed with the Microsoft strong name full trust. ">
<IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293"/>
</CodeGroup>
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust" Name="Ecma_Strong_Name" Description="This code group grants code signed with the ECMA strong name full trust. ">
<IMembershipCondition class="StrongNameMembershipCondition" version="1" PublicKeyBlob="00000000000000000400000000000000"/>
</CodeGroup>
</CodeGroup>
</CodeGroup>
</PolicyLevel>
</policy>
</security>
</mscorlib>
</configuration>

View File

@@ -18,9 +18,10 @@
#endregion
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security;
[assembly: ComVisible(false)]
[assembly: AssemblyTitle("Spring.Core")]
@@ -29,7 +30,24 @@ using System.Security.Permissions;
//
// Security Permissions
//
// we need full, unrestricted access to reflection metadata...
[assembly: ReflectionPermission(SecurityAction.RequestMinimum, Unrestricted=true)]
// we need full, unrestricted access to reflection metadata...
//[assembly: ReflectionPermission(SecurityAction.RequestMinimum, Unrestricted = true)]
//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")]
//[assembly: AssemblyKeyFile(@"C:\projects\Spring.Net\Spring.Net.snk")]
//[assembly: AssemblyKeyFile(@"C:\projects\Spring.Net\Spring.Net.snk")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityCritical]
#if NET_1_0 || NET_1_1
namespace System.Security
{
///<summary>
///</summary>
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method)]
internal class SecurityCriticalAttribute : Attribute
{ }
[AttributeUsage(AttributeTargets.Method)]
internal class SecurityTreatAsSafeAttribute : Attribute
{ }
}
#endif

View File

@@ -1,5 +1,5 @@
#region License
#region License
/*
* Copyright 2002-2004 the original author or authors.
*
@@ -14,273 +14,277 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;
using System.Collections;
using System.Reflection;
using Spring.Context.Support;
using Spring.Core.TypeResolution;
using Spring.Util;
using Spring.Reflection.Dynamic;
namespace Spring.Core.IO
{
/// <summary>
/// Registry class that allows users to register and retrieve protocol handlers.
/// </summary>
/// <remarks>
/// <para>
/// Resource handler is an implementation of <see cref="IResource"/> interface
/// that should be used to process resources with the specified protocol.
/// </para>
/// <para>
/// They are used throughout the framework to access resources from various
/// sources. For example, application context loads object definitions from the resources
/// that are processed using one of the registered resource handlers.
/// </para>
/// <para>Following resource handlers are registered by default:</para>
/// <list type="table">
/// <listheader>
/// <term>Protocol</term>
/// <term>Handler Type</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <description>config</description>
/// <description><see cref="Spring.Core.IO.ConfigSectionResource"/></description>
/// <description>Resolves the resources by loading specified configuration section from the standard .NET config file.</description>
/// </item>
/// <item>
/// <description>file</description>
/// <description><see cref="Spring.Core.IO.FileSystemResource"/></description>
/// <description>Resolves filesystem resources.</description>
/// </item>
/// <item>
/// <description>http</description>
/// <description><see cref="Spring.Core.IO.UrlResource"/></description>
/// <description>Resolves remote web resources.</description>
/// </item>
/// <item>
/// <description>https</description>
/// <description><see cref="Spring.Core.IO.UrlResource"/></description>
/// <description>Resolves remote web resources via HTTPS.</description>
/// </item>
/// <item>
/// <description>ftp</description>
/// <description><see cref="Spring.Core.IO.UrlResource"/></description>
/// <description>Resolves ftp resources.</description>
/// </item>
/// <item>
/// <description>assembly</description>
/// <description><see cref="Spring.Core.IO.AssemblyResource"/></description>
/// <description>Resolves resources that are embedded into an assembly.</description>
/// </item>
/// <item>
/// <description>web</description>
/// <description><c>Spring.Core.IO.WebResource, Spring.Web</c>*</description>
/// <description>Resolves resources relative to the web application's virtual directory.</description>
/// </item>
/// </list>
/// * only available in web applications.
/// <para>
/// Users can create and register their own protocol handlers by implementing <see cref="IResource"/> interface
/// and mapping custom protocol name to that implementation. See <see cref="ResourceHandlersSectionHandler"/> for details
/// on how to register custom protocol handler.
/// </para>
/// </remarks>
/// <author>Aleksandar Seovic</author>
public class ResourceHandlerRegistry
{
/// <summary>
/// Name of the .Net config section that contains definitions
/// for custom resource handlers.
/// </summary>
private const string ResourcesSectionName = "spring/resourceHandlers";
private static IDictionary resourceHandlers = new Hashtable();
/// <summary>
/// Registers standard and user-configured resource handlers.
/// </summary>
static ResourceHandlerRegistry()
{
lock (resourceHandlers.SyncRoot)
{
RegisterResourceHandler("config", typeof(ConfigSectionResource));
RegisterResourceHandler("file", typeof(FileSystemResource));
RegisterResourceHandler("http", typeof(UrlResource));
RegisterResourceHandler("https", typeof(UrlResource));
#if NET_2_0
RegisterResourceHandler("ftp", typeof(UrlResource));
#endif
RegisterResourceHandler("assembly", typeof(AssemblyResource));
// register custom resource handlers
ConfigurationUtils.GetSection(ResourcesSectionName);
}
}
/// <summary>
/// Returns resource handler for the specified protocol name.
/// </summary>
/// <remarks>
/// <para>
/// This method returns <see cref="ConstructorInfo"/> object that should be used
/// to create an instance of the <see cref="IResource"/>-derived type by passing
/// resource location as a parameter.
/// </para>
/// </remarks>
/// <param name="protocolName">Name of the protocol to get the handler for.</param>
/// <returns>Resource handler constructor for the specified protocol name.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="protocolName"/> is <c>null</c>.</exception>
public static IDynamicConstructor GetResourceHandler(string protocolName)
{
AssertUtils.ArgumentNotNull(protocolName, "protocolName");
return (IDynamicConstructor) resourceHandlers[protocolName];
}
/// <summary>
/// Returns <c>true</c> if a handler is registered for the specified protocol,
/// <c>false</c> otherwise.
/// </summary>
/// <param name="protocolName">Name of the protocol.</param>
/// <returns>
/// <c>true</c> if a handler is registered for the specified protocol, <c>false</c> otherwise.
/// </returns>
/// <exception cref="ArgumentNullException">If <paramref name="protocolName"/> is <c>null</c>.</exception>
public static bool IsHandlerRegistered(string protocolName)
{
return resourceHandlers.Contains(protocolName);
}
/// <summary>
/// Registers resource handler and maps it to the specified protocol name.
/// </summary>
/// <remarks>
/// <p>
/// If the mapping already exists, the existing mapping will be
/// silently overwritten with the new mapping.
/// </p>
/// </remarks>
/// <param name="protocolName">
/// The protocol to add (or override).
/// </param>
/// <param name="handlerTypeName">
/// The type name of the concrete implementation of the
/// <see cref="Spring.Core.IO.IResource"/> interface that will handle
/// the specified protocol.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="protocolName"/> is
/// <see langword="null"/> or contains only whitespace character(s); or
/// if the supplied <paramref name="handlerTypeName"/> is
/// <see langword="null"/>.
/// </exception>
/// <exception cref="System.ArgumentException">
/// If the supplied <paramref name="handlerTypeName"/> is not a
/// <see cref="Type"/> that derives from the
/// <see cref="Spring.Core.IO.IResource"/> interface; or (having passed
/// this first check), the supplied <paramref name="handlerTypeName"/>
/// does not expose a constructor that takes a single
/// <see cref="System.String"/> parameter.
/// </exception>
public static void RegisterResourceHandler(string protocolName, string handlerTypeName)
{
AssertUtils.ArgumentHasText(protocolName, "protocolName");
AssertUtils.ArgumentHasText(handlerTypeName, "handlerTypeName");
Type handlerType = TypeResolutionUtils.ResolveType(handlerTypeName);
RegisterResourceHandler(protocolName, handlerType);
}
/// <summary>
/// Registers resource handler and maps it to the specified protocol name.
/// </summary>
/// <remarks>
/// <p>
/// If the mapping already exists, the existing mapping will be
/// silently overwritten with the new mapping.
/// </p>
/// </remarks>
/// <param name="protocolName">
/// The protocol to add (or override).
/// </param>
/// <param name="handlerType">
/// The concrete implementation of the
/// <see cref="Spring.Core.IO.IResource"/> interface that will handle
/// the specified protocol.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="protocolName"/> is
/// <see langword="null"/> or contains only whitespace character(s); or
/// if the supplied <paramref name="handlerType"/> is
/// <see langword="null"/>.
/// </exception>
/// <exception cref="System.ArgumentException">
/// If the supplied <paramref name="handlerType"/> is not a
/// <see cref="Type"/> that derives from the
/// <see cref="Spring.Core.IO.IResource"/> interface; or (having passed
/// this first check), the supplied <paramref name="handlerType"/>
/// does not expose a constructor that takes a single
/// <see cref="System.String"/> parameter.
/// </exception>
public static void RegisterResourceHandler(string protocolName, Type handlerType)
{
#region Sanity Checks
AssertUtils.ArgumentHasText(protocolName, "protocolName");
AssertUtils.ArgumentNotNull(handlerType, "handlerType");
if (!typeof(IResource).IsAssignableFrom(handlerType))
{
throw new ArgumentException(
string.Format("[{0}] does not implement [{1}] interface (it must).", handlerType.FullName, typeof(IResource).FullName));
}
#endregion
lock (resourceHandlers.SyncRoot)
{
#if NET_2_0
// register generic uri parser for this scheme
if (!UriParser.IsKnownScheme(protocolName))
*/
#endregion
using System;
using System.Collections;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using Spring.Context.Support;
using Spring.Core.TypeResolution;
using Spring.Util;
using Spring.Reflection.Dynamic;
namespace Spring.Core.IO
{
/// <summary>
/// Registry class that allows users to register and retrieve protocol handlers.
/// </summary>
/// <remarks>
/// <para>
/// Resource handler is an implementation of <see cref="IResource"/> interface
/// that should be used to process resources with the specified protocol.
/// </para>
/// <para>
/// They are used throughout the framework to access resources from various
/// sources. For example, application context loads object definitions from the resources
/// that are processed using one of the registered resource handlers.
/// </para>
/// <para>Following resource handlers are registered by default:</para>
/// <list type="table">
/// <listheader>
/// <term>Protocol</term>
/// <term>Handler Type</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <description>config</description>
/// <description><see cref="Spring.Core.IO.ConfigSectionResource"/></description>
/// <description>Resolves the resources by loading specified configuration section from the standard .NET config file.</description>
/// </item>
/// <item>
/// <description>file</description>
/// <description><see cref="Spring.Core.IO.FileSystemResource"/></description>
/// <description>Resolves filesystem resources.</description>
/// </item>
/// <item>
/// <description>http</description>
/// <description><see cref="Spring.Core.IO.UrlResource"/></description>
/// <description>Resolves remote web resources.</description>
/// </item>
/// <item>
/// <description>https</description>
/// <description><see cref="Spring.Core.IO.UrlResource"/></description>
/// <description>Resolves remote web resources via HTTPS.</description>
/// </item>
/// <item>
/// <description>ftp</description>
/// <description><see cref="Spring.Core.IO.UrlResource"/></description>
/// <description>Resolves ftp resources.</description>
/// </item>
/// <item>
/// <description>assembly</description>
/// <description><see cref="Spring.Core.IO.AssemblyResource"/></description>
/// <description>Resolves resources that are embedded into an assembly.</description>
/// </item>
/// <item>
/// <description>web</description>
/// <description><c>Spring.Core.IO.WebResource, Spring.Web</c>*</description>
/// <description>Resolves resources relative to the web application's virtual directory.</description>
/// </item>
/// </list>
/// * only available in web applications.
/// <para>
/// Users can create and register their own protocol handlers by implementing <see cref="IResource"/> interface
/// and mapping custom protocol name to that implementation. See <see cref="ResourceHandlersSectionHandler"/> for details
/// on how to register custom protocol handler.
/// </para>
/// </remarks>
/// <author>Aleksandar Seovic</author>
public class ResourceHandlerRegistry
{
/// <summary>
/// Name of the .Net config section that contains definitions
/// for custom resource handlers.
/// </summary>
private const string ResourcesSectionName = "spring/resourceHandlers";
private static IDictionary resourceHandlers = new Hashtable();
/// <summary>
/// Registers standard and user-configured resource handlers.
/// </summary>
static ResourceHandlerRegistry()
{
lock (resourceHandlers.SyncRoot)
{
RegisterResourceHandler("config", typeof(ConfigSectionResource));
RegisterResourceHandler("file", typeof(FileSystemResource));
RegisterResourceHandler("http", typeof(UrlResource));
RegisterResourceHandler("https", typeof(UrlResource));
#if NET_2_0
RegisterResourceHandler("ftp", typeof(UrlResource));
#endif
RegisterResourceHandler("assembly", typeof(AssemblyResource));
// register custom resource handlers
ConfigurationUtils.GetSection(ResourcesSectionName);
}
}
/// <summary>
/// Returns resource handler for the specified protocol name.
/// </summary>
/// <remarks>
/// <para>
/// This method returns <see cref="ConstructorInfo"/> object that should be used
/// to create an instance of the <see cref="IResource"/>-derived type by passing
/// resource location as a parameter.
/// </para>
/// </remarks>
/// <param name="protocolName">Name of the protocol to get the handler for.</param>
/// <returns>Resource handler constructor for the specified protocol name.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="protocolName"/> is <c>null</c>.</exception>
public static IDynamicConstructor GetResourceHandler(string protocolName)
{
AssertUtils.ArgumentNotNull(protocolName, "protocolName");
return (IDynamicConstructor)resourceHandlers[protocolName];
}
/// <summary>
/// Returns <c>true</c> if a handler is registered for the specified protocol,
/// <c>false</c> otherwise.
/// </summary>
/// <param name="protocolName">Name of the protocol.</param>
/// <returns>
/// <c>true</c> if a handler is registered for the specified protocol, <c>false</c> otherwise.
/// </returns>
/// <exception cref="ArgumentNullException">If <paramref name="protocolName"/> is <c>null</c>.</exception>
public static bool IsHandlerRegistered(string protocolName)
{
return resourceHandlers.Contains(protocolName);
}
/// <summary>
/// Registers resource handler and maps it to the specified protocol name.
/// </summary>
/// <remarks>
/// <p>
/// If the mapping already exists, the existing mapping will be
/// silently overwritten with the new mapping.
/// </p>
/// </remarks>
/// <param name="protocolName">
/// The protocol to add (or override).
/// </param>
/// <param name="handlerTypeName">
/// The type name of the concrete implementation of the
/// <see cref="Spring.Core.IO.IResource"/> interface that will handle
/// the specified protocol.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="protocolName"/> is
/// <see langword="null"/> or contains only whitespace character(s); or
/// if the supplied <paramref name="handlerTypeName"/> is
/// <see langword="null"/>.
/// </exception>
/// <exception cref="System.ArgumentException">
/// If the supplied <paramref name="handlerTypeName"/> is not a
/// <see cref="Type"/> that derives from the
/// <see cref="Spring.Core.IO.IResource"/> interface; or (having passed
/// this first check), the supplied <paramref name="handlerTypeName"/>
/// does not expose a constructor that takes a single
/// <see cref="System.String"/> parameter.
/// </exception>
public static void RegisterResourceHandler(string protocolName, string handlerTypeName)
{
AssertUtils.ArgumentHasText(protocolName, "protocolName");
AssertUtils.ArgumentHasText(handlerTypeName, "handlerTypeName");
Type handlerType = TypeResolutionUtils.ResolveType(handlerTypeName);
RegisterResourceHandler(protocolName, handlerType);
}
/// <summary>
/// Registers resource handler and maps it to the specified protocol name.
/// </summary>
/// <remarks>
/// <p>
/// If the mapping already exists, the existing mapping will be
/// silently overwritten with the new mapping.
/// </p>
/// </remarks>
/// <param name="protocolName">
/// The protocol to add (or override).
/// </param>
/// <param name="handlerType">
/// The concrete implementation of the
/// <see cref="Spring.Core.IO.IResource"/> interface that will handle
/// the specified protocol.
/// </param>
/// <exception cref="System.ArgumentNullException">
/// If the supplied <paramref name="protocolName"/> is
/// <see langword="null"/> or contains only whitespace character(s); or
/// if the supplied <paramref name="handlerType"/> is
/// <see langword="null"/>.
/// </exception>
/// <exception cref="System.ArgumentException">
/// If the supplied <paramref name="handlerType"/> is not a
/// <see cref="Type"/> that derives from the
/// <see cref="Spring.Core.IO.IResource"/> interface; or (having passed
/// this first check), the supplied <paramref name="handlerType"/>
/// does not expose a constructor that takes a single
/// <see cref="System.String"/> parameter.
/// </exception>
public static void RegisterResourceHandler(string protocolName, Type handlerType)
{
#region Sanity Checks
AssertUtils.ArgumentHasText(protocolName, "protocolName");
AssertUtils.ArgumentNotNull(handlerType, "handlerType");
if (!typeof(IResource).IsAssignableFrom(handlerType))
{
throw new ArgumentException(
string.Format("[{0}] does not implement [{1}] interface (it must).", handlerType.FullName, typeof(IResource).FullName));
}
#endregion
lock (resourceHandlers.SyncRoot)
{
#if NET_2_0
SecurityCritical.ExecutePrivileged( new SecurityPermission(SecurityPermissionFlag.Infrastructure), delegate
{
UriParser.Register(new TolerantUriParser(), protocolName, 0);
}
#endif
IDynamicConstructor ctor = GetResourceConstructor(handlerType);
resourceHandlers[protocolName] = ctor;
}
}
#if NET_2_0
// register generic uri parser for this scheme
if (!UriParser.IsKnownScheme(protocolName))
{
UriParser.Register(new TolerantUriParser(), protocolName, 0);
}
});
#endif
IDynamicConstructor ctor = GetResourceConstructor(handlerType);
resourceHandlers[protocolName] = ctor;
}
}
#if NET_2_0
/// <summary>
/// Allows to create any arbitrary Url format
/// </summary>
private class TolerantUriParser : GenericUriParser
/// </summary>
private class TolerantUriParser : GenericUriParser
{
private const GenericUriParserOptions DefaultOptions = GenericUriParserOptions.Default
|GenericUriParserOptions.GenericAuthority
|GenericUriParserOptions.AllowEmptyAuthority;
| GenericUriParserOptions.GenericAuthority
| GenericUriParserOptions.AllowEmptyAuthority;
public TolerantUriParser()
public TolerantUriParser()
: base(DefaultOptions)
{}
}
#endif
private static IDynamicConstructor GetResourceConstructor(Type handlerType)
{
ConstructorInfo ctor = handlerType.GetConstructor(new Type[] {typeof(string)});
if (ctor == null)
{
throw new ArgumentException(
string.Format("[{0}] does not have a constructor that takes a single string as an argument (it must).", handlerType.FullName));
}
return DynamicConstructor.Create(ctor);
}
}
{ }
}
#endif
private static IDynamicConstructor GetResourceConstructor(Type handlerType)
{
ConstructorInfo ctor = handlerType.GetConstructor(new Type[] { typeof(string) });
if (ctor == null)
{
throw new ArgumentException(
string.Format("[{0}] does not have a constructor that takes a single string as an argument (it must).", handlerType.FullName));
}
return new SafeConstructor(ctor);
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections;
using System.Reflection;
using Common.Logging;
using Spring.Globalization;
using Spring.Validation;
@@ -13,6 +15,7 @@ namespace Spring.DataBinding
{
#region Fields
private readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IFormatter formatter;
#endregion
@@ -132,8 +135,9 @@ namespace Spring.DataBinding
{
DoBindTargetToSource(source, target, variables);
}
catch (Exception)
catch (Exception ex)
{
log.Warn(string.Format("Failed binding[{0}]:{1}", this.Id, ex));
if (!SetInvalid(validationErrors)) throw;
}
}

View File

@@ -273,16 +273,21 @@ namespace Spring.Expressions
{
if (indexer == null)
{
Type contextType = context.GetType();
Type[] argTypes = ReflectionUtils.GetTypes(indices);
PropertyInfo indexerProperty = context.GetType().GetProperty("Item", BINDING_FLAGS, null, null, argTypes, null);
string defaultMember = "Item";
object[] atts = contextType.GetCustomAttributes(typeof(DefaultMemberAttribute), true);
if (atts != null && atts.Length > 0)
{
defaultMember = ((DefaultMemberAttribute) atts[0]).MemberName;
}
PropertyInfo indexerProperty = contextType.GetProperty(defaultMember, BINDING_FLAGS, null, null, argTypes, null);
if (indexerProperty == null)
{
throw new ArgumentException("Indexer property with specified number and types of arguments does not exist.");
}
else
{
indexer = new SafeProperty(indexerProperty);
}
indexer = new SafeProperty(indexerProperty);
}
}
}

View File

@@ -25,6 +25,9 @@ using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using Spring.Util;
#if NET_2_0
@@ -40,14 +43,14 @@ namespace Spring.Reflection.Dynamic
/// </summary>
/// <param name="target">the target instance when calling an instance method</param>
/// <returns>the value return by the Get method</returns>
public delegate object FieldGetterDelegate( object target );
public delegate object FieldGetterDelegate(object target);
/// <summary>
/// Represents a Set method
/// </summary>
/// <param name="target">the target instance when calling an instance method</param>
/// <param name="value">the value to be set</param>
public delegate void FieldSetterDelegate( object target, object value );
public delegate void FieldSetterDelegate(object target, object value);
/// <summary>
/// Represents an Indexer Get method
@@ -55,7 +58,7 @@ namespace Spring.Reflection.Dynamic
/// <param name="target">the target instance when calling an instance method</param>
/// <param name="index"></param>
/// <returns>the value return by the Get method</returns>
public delegate object PropertyGetterDelegate( object target, params object[] index );
public delegate object PropertyGetterDelegate(object target, params object[] index);
/// <summary>
/// Represents a Set method
@@ -63,7 +66,7 @@ namespace Spring.Reflection.Dynamic
/// <param name="target">the target instance when calling an instance method</param>
/// <param name="value">the value to be set</param>
/// <param name="index"></param>
public delegate void PropertySetterDelegate( object target, object value, params object[] index );
public delegate void PropertySetterDelegate(object target, object value, params object[] index);
/// <summary>
/// Represents a method
@@ -71,35 +74,35 @@ namespace Spring.Reflection.Dynamic
/// <param name="target">the target instance when calling an instance method</param>
/// <param name="args">arguments to be passed to the method</param>
/// <returns>the value return by the method. <value>null</value> when calling a void method</returns>
public delegate object FunctionDelegate( object target, params object[] args );
public delegate object FunctionDelegate(object target, params object[] args);
/// <summary>
/// Represents a constructor
/// </summary>
/// <param name="args">arguments to be passed to the method</param>
/// <returns>the new object instance</returns>
public delegate object ConstructorDelegate( params object[] args );
public delegate object ConstructorDelegate(params object[] args);
/// <summary>
/// Represents a callback method used to create an <see cref="IDynamicProperty"/> from a <see cref="PropertyInfo"/> instance.
/// </summary>
internal delegate IDynamicProperty CreatePropertyCallback( PropertyInfo property );
internal delegate IDynamicProperty CreatePropertyCallback(PropertyInfo property);
/// <summary>
/// Represents a callback method used to create an <see cref="IDynamicField"/> from a <see cref="FieldInfo"/> instance.
/// </summary>
internal delegate IDynamicField CreateFieldCallback( FieldInfo property );
internal delegate IDynamicField CreateFieldCallback(FieldInfo property);
/// <summary>
/// Represents a callback method used to create an <see cref="IDynamicMethod"/> from a <see cref="MethodInfo"/> instance.
/// </summary>
internal delegate IDynamicMethod CreateMethodCallback( MethodInfo method );
internal delegate IDynamicMethod CreateMethodCallback(MethodInfo method);
/// <summary>
/// Represents a callback method used to create an <see cref="IDynamicConstructor"/> from a <see cref="ConstructorInfo"/> instance.
/// </summary>
internal delegate IDynamicConstructor CreateConstructorCallback( ConstructorInfo constructor );
internal delegate IDynamicConstructor CreateConstructorCallback(ConstructorInfo constructor);
/// <summary>
/// Represents a callback method used to create an <see cref="IDynamicIndexer"/> from a <see cref="PropertyInfo"/> instance.
/// </summary>
internal delegate IDynamicIndexer CreateIndexerCallback( PropertyInfo indexer );
internal delegate IDynamicIndexer CreateIndexerCallback(PropertyInfo indexer);
/// <summary>
/// Allows easy access to existing and creation of new dynamic relection members.
@@ -156,14 +159,14 @@ namespace Spring.Reflection.Dynamic
/// The base name to use for the reflection type name.
/// </param>
/// <returns>The type builder to use.</returns>
internal static TypeBuilder CreateTypeBuilder( string name )
internal static TypeBuilder CreateTypeBuilder(string name)
{
// Generates type name
string typeName = String.Format( "{0}.{1}_{2}",
ASSEMBLY_NAME, name, Guid.NewGuid().ToString( "N" ) );
string typeName = String.Format("{0}.{1}_{2}",
ASSEMBLY_NAME, name, Guid.NewGuid().ToString("N"));
ModuleBuilder module = DynamicCodeManager.GetModuleBuilder( ASSEMBLY_NAME );
return module.DefineType( typeName, TYPE_ATTRIBUTES );
ModuleBuilder module = DynamicCodeManager.GetModuleBuilder(ASSEMBLY_NAME);
return module.DefineType(typeName, TYPE_ATTRIBUTES);
}
/// <summary>
@@ -172,14 +175,14 @@ namespace Spring.Reflection.Dynamic
/// <param name="property">Property to look up.</param>
/// <param name="createCallback">callback function that will be called to create the dynamic property</param>
/// <returns>An <see cref="IDynamicProperty"/> for the given property info.</returns>
internal static IDynamicProperty GetDynamicProperty( PropertyInfo property, CreatePropertyCallback createCallback )
internal static IDynamicProperty GetDynamicProperty(PropertyInfo property, CreatePropertyCallback createCallback)
{
lock (propertyCache.SyncRoot)
{
IDynamicProperty dynamicProperty = (IDynamicProperty)propertyCache[property];
if (dynamicProperty == null)
{
dynamicProperty = createCallback( property );
dynamicProperty = createCallback(property);
propertyCache[property] = dynamicProperty;
}
return dynamicProperty;
@@ -192,14 +195,14 @@ namespace Spring.Reflection.Dynamic
/// <param name="field">Field to look up.</param>
/// <param name="createCallback">callback function that will be called to create the dynamic field</param>
/// <returns>An <see cref="IDynamicField"/> for the given field info.</returns>
internal static IDynamicField GetDynamicField( FieldInfo field, CreateFieldCallback createCallback )
internal static IDynamicField GetDynamicField(FieldInfo field, CreateFieldCallback createCallback)
{
lock (fieldCache.SyncRoot)
{
IDynamicField dynamicField = (IDynamicField)fieldCache[field];
if (dynamicField == null)
{
dynamicField = createCallback( field );
dynamicField = createCallback(field);
fieldCache[field] = dynamicField;
}
return dynamicField;
@@ -212,14 +215,14 @@ namespace Spring.Reflection.Dynamic
/// <param name="indexer">Indexer to look up.</param>
/// <param name="createCallback">callback function that will be called to create the dynamic indexer</param>
/// <returns>An <see cref="IDynamicIndexer"/> for the given indexer.</returns>
internal static IDynamicIndexer GetDynamicIndexer( PropertyInfo indexer, CreateIndexerCallback createCallback )
internal static IDynamicIndexer GetDynamicIndexer(PropertyInfo indexer, CreateIndexerCallback createCallback)
{
lock (indexerCache.SyncRoot)
{
IDynamicIndexer dynamicIndexer = (IDynamicIndexer)indexerCache[indexer];
if (dynamicIndexer == null)
{
dynamicIndexer = createCallback( indexer );
dynamicIndexer = createCallback(indexer);
indexerCache[indexer] = dynamicIndexer;
}
return dynamicIndexer;
@@ -232,14 +235,14 @@ namespace Spring.Reflection.Dynamic
/// <param name="method">Method to look up.</param>
/// <param name="createCallback">callback function that will be called to create the dynamic method</param>
/// <returns>An <see cref="IDynamicMethod"/> for the given method.</returns>
internal static IDynamicMethod GetDynamicMethod( MethodInfo method, CreateMethodCallback createCallback )
internal static IDynamicMethod GetDynamicMethod(MethodInfo method, CreateMethodCallback createCallback)
{
lock (methodCache.SyncRoot)
{
IDynamicMethod dynamicMethod = (IDynamicMethod)methodCache[method];
if (dynamicMethod == null)
{
dynamicMethod = createCallback( method );
dynamicMethod = createCallback(method);
methodCache[method] = dynamicMethod;
}
return dynamicMethod;
@@ -252,14 +255,14 @@ namespace Spring.Reflection.Dynamic
/// <param name="constructor">Constructor to look up.</param>
/// <param name="createCallback">callback function that will be called to create the dynamic constructor</param>
/// <returns>An <see cref="IDynamicConstructor"/> for the given constructor.</returns>
internal static IDynamicConstructor GetDynamicConstructor( ConstructorInfo constructor, CreateConstructorCallback createCallback )
internal static IDynamicConstructor GetDynamicConstructor(ConstructorInfo constructor, CreateConstructorCallback createCallback)
{
lock (constructorCache.SyncRoot)
{
IDynamicConstructor dynamicConstructor = (IDynamicConstructor)constructorCache[constructor];
if (dynamicConstructor == null)
{
dynamicConstructor = createCallback( constructor );
dynamicConstructor = createCallback(constructor);
constructorCache[constructor] = dynamicConstructor;
}
return dynamicConstructor;
@@ -270,10 +273,10 @@ namespace Spring.Reflection.Dynamic
/// Saves dynamically generated assembly to disk.
/// Can only be called in DEBUG mode, per ConditionalAttribute rules.
/// </summary>
[Conditional( "DEBUG_DYNAMIC" )]
[Conditional("DEBUG_DYNAMIC")]
public static void SaveAssembly()
{
DynamicCodeManager.SaveAssembly( ASSEMBLY_NAME );
DynamicCodeManager.SaveAssembly(ASSEMBLY_NAME);
}
#endregion
@@ -284,14 +287,16 @@ namespace Spring.Reflection.Dynamic
/// </summary>
/// <param name="fieldInfo">the field to create the delegate for</param>
/// <returns>a delegate that can be used to read the field</returns>
public static FieldGetterDelegate CreateFieldGetter( FieldInfo fieldInfo )
public static FieldGetterDelegate CreateFieldGetter(FieldInfo fieldInfo)
{
AssertUtils.ArgumentNotNull( fieldInfo, "You cannot create a delegate for a null value." );
AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value.");
System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod( "getter", typeof( object ), new Type[] { typeof( object ) }, fieldInfo.DeclaringType.Module, true );
bool skipVisibility = !IsPublic(fieldInfo);
Type[] argumentTypes = new Type[] { typeof(object) };
System.Reflection.Emit.DynamicMethod dmGetter = CreateDynamicMethod("get_" + fieldInfo.Name, typeof(object), argumentTypes, fieldInfo, skipVisibility);
ILGenerator il = dmGetter.GetILGenerator();
EmitFieldGetter( il, fieldInfo, false );
return (FieldGetterDelegate)dmGetter.CreateDelegate( typeof( FieldGetterDelegate ) );
EmitFieldGetter(il, fieldInfo, false);
return (FieldGetterDelegate)dmGetter.CreateDelegate(typeof(FieldGetterDelegate));
}
/// <summary>
@@ -303,14 +308,15 @@ namespace Spring.Reflection.Dynamic
/// If the field's <see cref="FieldInfo.IsLiteral"/> returns true, the returned method
/// will throw an <see cref="InvalidOperationException"/> when called.
/// </remarks>
public static FieldSetterDelegate CreateFieldSetter( FieldInfo fieldInfo )
public static FieldSetterDelegate CreateFieldSetter(FieldInfo fieldInfo)
{
AssertUtils.ArgumentNotNull( fieldInfo, "You cannot create a delegate for a null value." );
AssertUtils.ArgumentNotNull(fieldInfo, "You cannot create a delegate for a null value.");
System.Reflection.Emit.DynamicMethod dmSetter = new System.Reflection.Emit.DynamicMethod( "setter", null, new Type[] { typeof( object ), typeof( object ) }, fieldInfo.DeclaringType.Module, true );
bool skipVisibility = !IsPublic(fieldInfo);
System.Reflection.Emit.DynamicMethod dmSetter = CreateDynamicMethod("set_" + fieldInfo.Name, null, new Type[] { typeof(object), typeof(object) }, fieldInfo, skipVisibility);
ILGenerator il = dmSetter.GetILGenerator();
EmitFieldSetter( il, fieldInfo, false );
return (FieldSetterDelegate)dmSetter.CreateDelegate( typeof( FieldSetterDelegate ) );
EmitFieldSetter(il, fieldInfo, false);
return (FieldSetterDelegate)dmSetter.CreateDelegate(typeof(FieldSetterDelegate));
}
/// <summary>
@@ -322,14 +328,16 @@ namespace Spring.Reflection.Dynamic
/// If the property's <see cref="PropertyInfo.CanRead"/> returns false, the returned method
/// will throw an <see cref="InvalidOperationException"/> when called.
/// </remarks>
public static PropertyGetterDelegate CreatePropertyGetter( PropertyInfo propertyInfo )
public static PropertyGetterDelegate CreatePropertyGetter(PropertyInfo propertyInfo)
{
AssertUtils.ArgumentNotNull( propertyInfo, "You cannot create a delegate for a null value." );
AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value.");
NetDynamicMethod dm = new NetDynamicMethod( string.Empty, typeof( object ), new Type[] { typeof( object ), typeof( object[] ) }, propertyInfo.DeclaringType.Module, true );
MethodInfo getMethod = propertyInfo.GetGetMethod();
bool skipVisibility = (null == getMethod || !IsPublic(getMethod)); // getter is public
NetDynamicMethod dm = CreateDynamicMethod("get_" + propertyInfo.Name, typeof(object), new Type[] { typeof(object), typeof(object[]) }, propertyInfo, skipVisibility);
ILGenerator il = dm.GetILGenerator();
EmitPropertyGetter( il, propertyInfo, false );
return (PropertyGetterDelegate)dm.CreateDelegate( typeof( PropertyGetterDelegate ) );
EmitPropertyGetter(il, propertyInfo, false);
return (PropertyGetterDelegate)dm.CreateDelegate(typeof(PropertyGetterDelegate));
}
/// <summary>
@@ -341,14 +349,17 @@ namespace Spring.Reflection.Dynamic
/// If the property's <see cref="PropertyInfo.CanWrite"/> returns false, the returned method
/// will throw an <see cref="InvalidOperationException"/> when called.
/// </remarks>
public static PropertySetterDelegate CreatePropertySetter( PropertyInfo propertyInfo )
public static PropertySetterDelegate CreatePropertySetter(PropertyInfo propertyInfo)
{
AssertUtils.ArgumentNotNull( propertyInfo, "You cannot create a delegate for a null value." );
AssertUtils.ArgumentNotNull(propertyInfo, "You cannot create a delegate for a null value.");
NetDynamicMethod dm = new NetDynamicMethod( string.Empty, null, new Type[] { typeof( object ), typeof( object ), typeof( object[] ) }, propertyInfo.DeclaringType.Module, true );
MethodInfo setMethod = propertyInfo.GetSetMethod();
bool skipVisibility = (null == setMethod || !IsPublic(setMethod)); // setter is public
Type[] argumentTypes = new Type[] { typeof(object), typeof(object), typeof(object[]) };
NetDynamicMethod dm = CreateDynamicMethod("set_" + propertyInfo.Name, null, argumentTypes, propertyInfo, skipVisibility);
ILGenerator il = dm.GetILGenerator();
EmitPropertySetter( il, propertyInfo, false );
return (PropertySetterDelegate)dm.CreateDelegate( typeof( PropertySetterDelegate ) );
EmitPropertySetter(il, propertyInfo, false);
return (PropertySetterDelegate)dm.CreateDelegate(typeof(PropertySetterDelegate));
}
/// <summary>
@@ -356,14 +367,15 @@ namespace Spring.Reflection.Dynamic
/// </summary>
/// <param name="methodInfo">the method to create the delegate for</param>
/// <returns>a delegate that can be used to invoke the method.</returns>
public static FunctionDelegate CreateMethod( MethodInfo methodInfo )
public static FunctionDelegate CreateMethod(MethodInfo methodInfo)
{
AssertUtils.ArgumentNotNull( methodInfo, "You cannot create a delegate for a null value." );
AssertUtils.ArgumentNotNull(methodInfo, "You cannot create a delegate for a null value.");
NetDynamicMethod dm = new NetDynamicMethod( string.Empty, typeof( object ), new Type[] { typeof( object ), typeof( object[] ) }, methodInfo.DeclaringType.Module, true );
bool skipVisibility = !IsPublic(methodInfo);
NetDynamicMethod dm = CreateDynamicMethod(methodInfo.Name, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo, skipVisibility);
ILGenerator il = dm.GetILGenerator();
EmitInvokeMethod( il, methodInfo, false );
return (FunctionDelegate)dm.CreateDelegate( typeof( FunctionDelegate ) );
EmitInvokeMethod(il, methodInfo, false);
return (FunctionDelegate)dm.CreateDelegate(typeof(FunctionDelegate));
}
///<summary>
@@ -371,45 +383,140 @@ namespace Spring.Reflection.Dynamic
///</summary>
///<param name="constructorInfo">the constructor to create the delegate for</param>
///<returns>delegate that can be used to invoke the constructor.</returns>
public static ConstructorDelegate CreateConstructor(ConstructorInfo constructorInfo)
public static ConstructorDelegate CreateConstructor(ConstructorInfo constructorInfo)
{
AssertUtils.ArgumentNotNull(constructorInfo, "You cannot create a dynamic constructor for a null value.");
AssertUtils.ArgumentNotNull(constructorInfo, "You cannot create a dynamic constructor for a null value.");
System.Reflection.Emit.DynamicMethod dmGetter = new System.Reflection.Emit.DynamicMethod( string.Empty, typeof( object ), new Type[] { typeof( object[] ) }, constructorInfo.DeclaringType.Module, true );
bool skipVisibility = !IsPublic(constructorInfo);
System.Reflection.Emit.DynamicMethod dmGetter;
Type[] argumentTypes = new Type[] { typeof(object[]) };
dmGetter = CreateDynamicMethod(constructorInfo.Name, typeof(object), argumentTypes, constructorInfo, skipVisibility);
ILGenerator il = dmGetter.GetILGenerator();
EmitInvokeConstructor( il, constructorInfo, false );
ConstructorDelegate ctor = (ConstructorDelegate)dmGetter.CreateDelegate( typeof( ConstructorDelegate ) );
EmitInvokeConstructor(il, constructorInfo, false);
ConstructorDelegate ctor = (ConstructorDelegate)dmGetter.CreateDelegate(typeof(ConstructorDelegate));
return ctor;
}
/// <summary>
/// Creates a <see cref="System.Reflection.Emit.DynamicMethod"/> instance with the highest possible code access security.
/// </summary>
/// <remarks>
/// If allowed by security policy, associates the method with the <paramref name="member"/>s declaring type.
/// Otherwise associates the dynamic method with <see cref="DynamicReflectionManager"/>.
/// </remarks>
[MethodImpl(MethodImplOptions.NoInlining)]
private static NetDynamicMethod CreateDynamicMethod(string methodName, Type returnType, Type[] argumentTypes, MemberInfo member, bool skipVisibility)
{
NetDynamicMethod dmGetter = null;
methodName = "_dynamic_" + member.DeclaringType.Name + "." + methodName;
try
{
new PermissionSet(PermissionState.Unrestricted).Demand();
dmGetter = CreateDynamicMethodInternal(methodName, returnType, argumentTypes, member, skipVisibility);
}
catch(SecurityException)
{
dmGetter = CreateDynamicMethodInternal(methodName, returnType, argumentTypes, MethodBase.GetCurrentMethod(), false);
}
return dmGetter;
}
private static NetDynamicMethod CreateDynamicMethodInternal(string methodName, Type returnType, Type[] argumentTypes, MemberInfo member, bool skipVisibility)
{
NetDynamicMethod dm;
dm = new NetDynamicMethod(methodName, returnType, argumentTypes, member.Module, skipVisibility);
// if (member is FieldInfo)
// {
// // workaround for DynamicMethod bug not invoking type initializer before accessing static field
// // it seems all works correct if the DM is created with limited accessibility
// bool isStatic = (((FieldInfo) member).IsStatic);
// if (isStatic)
// {
// new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).PermitOnly();
// }
// dm = new NetDynamicMethod(methodName, returnType, argumentTypes, member.DeclaringType, true);
// if (isStatic)
// {
// CodeAccessPermission.RevertPermitOnly();
// }
// }
// else
// {
// dm = new NetDynamicMethod(methodName, returnType, argumentTypes, member.DeclaringType, true);
// }
return dm;
}
private static bool IsPublic(MemberInfo member)
{
if (member == null) return true;
switch(member.MemberType)
{
case MemberTypes.Event:
{
bool isPublic = ((EventInfo) member).GetAddMethod() != null;
return isPublic && IsPublic(member.DeclaringType);
}
case MemberTypes.Field:
{
bool isPublic = ((FieldInfo)member).IsPublic;
return isPublic && IsPublic(member.DeclaringType);
}
case MemberTypes.Property:
{
throw new NotSupportedException();
}
case MemberTypes.Constructor:
case MemberTypes.Method:
{
bool isPublic = ((MethodBase)member).IsPublic;
return isPublic && IsPublic(member.DeclaringType);
}
case MemberTypes.NestedType:
{
bool isPublic = ((Type)member).IsPublic;
return isPublic && IsPublic(member.DeclaringType);
}
case MemberTypes.TypeInfo:
{
bool isPublic = ((Type)member).IsPublic;
return isPublic;
}
default:
throw new NotSupportedException();
}
}
#endif
#region Shared Code Generation
private static void EmitFieldGetter( ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod )
private static void EmitFieldGetter(ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod)
{
if (fieldInfo.IsLiteral)
{
object value = fieldInfo.GetValue( null );
EmitConstant( il, value );
object value = fieldInfo.GetValue(null);
EmitConstant(il, value);
}
else if (fieldInfo.IsStatic)
{
il.Emit( OpCodes.Ldsfld, fieldInfo );
// object v = fieldInfo.GetValue(null); // ensure type is initialized...
il.Emit(OpCodes.Ldsfld, fieldInfo);
}
else
{
EmitTarget( il, fieldInfo.DeclaringType, isInstanceMethod );
il.Emit( OpCodes.Ldfld, fieldInfo );
EmitTarget(il, fieldInfo.DeclaringType, isInstanceMethod);
il.Emit(OpCodes.Ldfld, fieldInfo);
}
if (fieldInfo.FieldType.IsValueType)
{
il.Emit( OpCodes.Box, fieldInfo.FieldType );
il.Emit(OpCodes.Box, fieldInfo.FieldType);
}
il.Emit( OpCodes.Ret );
il.Emit(OpCodes.Ret);
}
internal static void EmitFieldSetter( ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod )
internal static void EmitFieldSetter(ILGenerator il, FieldInfo fieldInfo, bool isInstanceMethod)
{
if (!fieldInfo.IsLiteral
&& !fieldInfo.IsInitOnly
@@ -417,51 +524,51 @@ namespace Spring.Reflection.Dynamic
{
if (!fieldInfo.IsStatic)
{
EmitTarget( il, fieldInfo.DeclaringType, isInstanceMethod );
EmitTarget(il, fieldInfo.DeclaringType, isInstanceMethod);
}
il.Emit( OpCodes.Ldarg_1 );
il.Emit(OpCodes.Ldarg_1);
if (fieldInfo.FieldType.IsValueType)
{
EmitUnbox( il, fieldInfo.FieldType );
EmitUnbox(il, fieldInfo.FieldType);
}
else
{
il.Emit( OpCodes.Castclass, fieldInfo.FieldType );
il.Emit(OpCodes.Castclass, fieldInfo.FieldType);
}
if (fieldInfo.IsStatic)
{
il.Emit( OpCodes.Stsfld, fieldInfo );
il.Emit(OpCodes.Stsfld, fieldInfo);
}
else
{
il.Emit( OpCodes.Stfld, fieldInfo );
il.Emit(OpCodes.Stfld, fieldInfo);
}
il.Emit( OpCodes.Ret );
il.Emit(OpCodes.Ret);
}
else
{
EmitThrowInvalidOperationException( il, string.Format( "Cannot write to read-only field '{0}.{1}'", fieldInfo.DeclaringType.FullName, fieldInfo.Name ) );
EmitThrowInvalidOperationException(il, string.Format("Cannot write to read-only field '{0}.{1}'", fieldInfo.DeclaringType.FullName, fieldInfo.Name));
}
}
internal static void EmitPropertyGetter( ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod )
internal static void EmitPropertyGetter(ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod)
{
if (propertyInfo.CanRead)
{
MethodInfo getMethod = propertyInfo.GetGetMethod( true );
EmitInvokeMethod( il, getMethod, isInstanceMethod );
MethodInfo getMethod = propertyInfo.GetGetMethod(true);
EmitInvokeMethod(il, getMethod, isInstanceMethod);
}
else
{
EmitThrowInvalidOperationException( il, string.Format( "Cannot read from write-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name ) );
EmitThrowInvalidOperationException(il, string.Format("Cannot read from write-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name));
}
}
internal static void EmitPropertySetter( ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod )
internal static void EmitPropertySetter(ILGenerator il, PropertyInfo propertyInfo, bool isInstanceMethod)
{
MethodInfo method = propertyInfo.GetSetMethod( true );
MethodInfo method = propertyInfo.GetSetMethod(true);
if (propertyInfo.CanWrite
&& !(propertyInfo.DeclaringType.IsValueType && !method.IsStatic))
@@ -475,184 +582,184 @@ namespace Spring.Reflection.Dynamic
ParameterInfo[] args = propertyInfo.GetIndexParameters(); // get indexParameters here!
for (int i = 0; i < args.Length; i++)
{
SetupOutputArgument( il, paramsArrayPosition, args[i], outArgs );
SetupOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
// load target
if (!method.IsStatic)
{
EmitTarget( il, method.DeclaringType, isInstanceMethod );
EmitTarget(il, method.DeclaringType, isInstanceMethod);
}
// load indexer arguments
for (int i = 0; i < args.Length; i++)
{
SetupMethodArgument( il, paramsArrayPosition, args[i], outArgs );
SetupMethodArgument(il, paramsArrayPosition, args[i], outArgs);
}
// load value
il.Emit( OpCodes.Ldarg_1 );
il.Emit(OpCodes.Ldarg_1);
if (propertyInfo.PropertyType.IsValueType)
{
EmitUnbox( il, propertyInfo.PropertyType );
EmitUnbox(il, propertyInfo.PropertyType);
}
else
{
il.Emit( OpCodes.Castclass, propertyInfo.PropertyType );
il.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
}
// call setter
EmitCall( il, method );
EmitCall(il, method);
for (int i = 0; i < args.Length; i++)
{
ProcessOutputArgument( il, paramsArrayPosition, args[i], outArgs );
ProcessOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
il.Emit( OpCodes.Ret );
il.Emit(OpCodes.Ret);
}
else
{
EmitThrowInvalidOperationException( il, string.Format( "Cannot write to read-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name ) );
EmitThrowInvalidOperationException(il, string.Format("Cannot write to read-only property '{0}.{1}'", propertyInfo.DeclaringType.FullName, propertyInfo.Name));
}
}
/// <summary>
/// Delegates a Method(object target, params object[] args) call to the actual underlying method.
/// </summary>
internal static void EmitInvokeMethod( ILGenerator il, MethodInfo method, bool isInstanceMethod )
internal static void EmitInvokeMethod(ILGenerator il, MethodInfo method, bool isInstanceMethod)
{
int paramsArrayPosition = (isInstanceMethod) ? 2 : 1;
ParameterInfo[] args = method.GetParameters();
IDictionary outArgs = new Hashtable();
for (int i = 0; i < args.Length; i++)
{
SetupOutputArgument( il, paramsArrayPosition, args[i], outArgs );
SetupOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
if (!method.IsStatic)
{
EmitTarget( il, method.DeclaringType, isInstanceMethod );
EmitTarget(il, method.DeclaringType, isInstanceMethod);
}
for (int i = 0; i < args.Length; i++)
{
SetupMethodArgument( il, paramsArrayPosition, args[i], outArgs );
SetupMethodArgument(il, paramsArrayPosition, args[i], outArgs);
}
EmitCall( il, method );
EmitCall(il, method);
for (int i = 0; i < args.Length; i++)
{
ProcessOutputArgument( il, paramsArrayPosition, args[i], outArgs );
ProcessOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
EmitMethodReturn( il, method.ReturnType );
EmitMethodReturn(il, method.ReturnType);
}
internal static void EmitInvokeConstructor(ILGenerator il, ConstructorInfo constructor, bool isInstanceMethod)
{
int paramsArrayPosition = (isInstanceMethod) ? 1 : 0;
ParameterInfo[] args = constructor.GetParameters();
ParameterInfo[] args = constructor.GetParameters();
IDictionary outArgs = new Hashtable();
for (int i = 0; i < args.Length; i++)
{
SetupOutputArgument( il, paramsArrayPosition, args[i], outArgs );
SetupOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
for (int i = 0; i < args.Length; i++)
{
SetupMethodArgument(il, paramsArrayPosition, args[i], null);
}
il.Emit(OpCodes.Newobj, constructor);
for (int i = 0; i < args.Length; i++)
{
ProcessOutputArgument( il, paramsArrayPosition, args[i], outArgs );
SetupMethodArgument(il, paramsArrayPosition, args[i], null);
}
EmitMethodReturn(il, constructor.DeclaringType);
}
il.Emit(OpCodes.Newobj, constructor);
for (int i = 0; i < args.Length; i++)
{
ProcessOutputArgument(il, paramsArrayPosition, args[i], outArgs);
}
EmitMethodReturn(il, constructor.DeclaringType);
}
#endregion
private static OpCode[] LdArgOpCodes = { OpCodes.Ldarg_0, OpCodes.Ldarg_1, OpCodes.Ldarg_2 };
private static void SetupOutputArgument( ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs )
private static void SetupOutputArgument(ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs)
{
if (!IsOutputOrRefArgument( argInfo ))
if (!IsOutputOrRefArgument(argInfo))
return;
Type argType = argInfo.ParameterType.GetElementType();
LocalBuilder lb = il.DeclareLocal( argType );
LocalBuilder lb = il.DeclareLocal(argType);
if (!argInfo.IsOut)
{
PushParamsArgumentValue( il, paramsArrayPosition, argType, argInfo.Position );
il.Emit( OpCodes.Stloc, lb );
PushParamsArgumentValue(il, paramsArrayPosition, argType, argInfo.Position);
il.Emit(OpCodes.Stloc, lb);
}
outArgs[argInfo.Position] = lb;
}
private static bool IsOutputOrRefArgument( ParameterInfo argInfo )
private static bool IsOutputOrRefArgument(ParameterInfo argInfo)
{
return argInfo.IsOut || argInfo.ParameterType.Name.EndsWith( "&" );
return argInfo.IsOut || argInfo.ParameterType.Name.EndsWith("&");
}
private static void ProcessOutputArgument( ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs )
private static void ProcessOutputArgument(ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs)
{
if (!IsOutputOrRefArgument( argInfo ))
if (!IsOutputOrRefArgument(argInfo))
return;
Type argType = argInfo.ParameterType.GetElementType();
il.Emit( LdArgOpCodes[paramsArrayPosition] );
il.Emit( OpCodes.Ldc_I4, argInfo.Position );
il.Emit( OpCodes.Ldloc, (LocalBuilder)outArgs[argInfo.Position] );
il.Emit(LdArgOpCodes[paramsArrayPosition]);
il.Emit(OpCodes.Ldc_I4, argInfo.Position);
il.Emit(OpCodes.Ldloc, (LocalBuilder)outArgs[argInfo.Position]);
if (argType.IsValueType)
{
il.Emit( OpCodes.Box, argType );
il.Emit(OpCodes.Box, argType);
}
il.Emit( OpCodes.Stelem_Ref );
il.Emit(OpCodes.Stelem_Ref);
}
private static void SetupMethodArgument( ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs )
private static void SetupMethodArgument(ILGenerator il, int paramsArrayPosition, ParameterInfo argInfo, IDictionary outArgs)
{
if ( IsOutputOrRefArgument( argInfo ))
if (IsOutputOrRefArgument(argInfo))
{
il.Emit( OpCodes.Ldloca_S, (LocalBuilder)outArgs[argInfo.Position] );
il.Emit(OpCodes.Ldloca_S, (LocalBuilder)outArgs[argInfo.Position]);
}
else
{
PushParamsArgumentValue( il, paramsArrayPosition, argInfo.ParameterType, argInfo.Position );
PushParamsArgumentValue(il, paramsArrayPosition, argInfo.ParameterType, argInfo.Position);
}
}
private static void PushParamsArgumentValue( ILGenerator il, int paramsArrayPosition, Type argumentType, int argumentPosition )
private static void PushParamsArgumentValue(ILGenerator il, int paramsArrayPosition, Type argumentType, int argumentPosition)
{
il.Emit( LdArgOpCodes[paramsArrayPosition] );
il.Emit( OpCodes.Ldc_I4, argumentPosition );
il.Emit( OpCodes.Ldelem_Ref );
il.Emit(LdArgOpCodes[paramsArrayPosition]);
il.Emit(OpCodes.Ldc_I4, argumentPosition);
il.Emit(OpCodes.Ldelem_Ref);
if (argumentType.IsValueType)
{
// call ConvertArgumentIfNecessary() to convert e.g. int32 to double if necessary
il.Emit( OpCodes.Ldtoken, argumentType );
EmitCall( il, FnGetTypeFromHandle );
il.Emit( OpCodes.Ldc_I4, argumentPosition );
EmitCall( il, FnConvertArgumentIfNecessary );
EmitUnbox( il, argumentType );
il.Emit(OpCodes.Ldtoken, argumentType);
EmitCall(il, FnGetTypeFromHandle);
il.Emit(OpCodes.Ldc_I4, argumentPosition);
EmitCall(il, FnConvertArgumentIfNecessary);
EmitUnbox(il, argumentType);
}
else
{
il.Emit( OpCodes.Castclass, argumentType );
il.Emit(OpCodes.Castclass, argumentType);
}
}
private static void EmitUnbox( ILGenerator il, Type argumentType )
private static void EmitUnbox(ILGenerator il, Type argumentType)
{
#if NET_2_0
il.Emit( OpCodes.Unbox_Any, argumentType );
il.Emit(OpCodes.Unbox_Any, argumentType);
#else
il.Emit(OpCodes.Unbox, argumentType);
il.Emit(OpCodes.Ldobj, argumentType);
@@ -664,23 +771,23 @@ namespace Spring.Reflection.Dynamic
/// </summary>
/// <param name="il">IL generator to use.</param>
/// <param name="returnValueType">Type of the return value.</param>
private static void EmitMethodReturn( ILGenerator il, Type returnValueType )
private static void EmitMethodReturn(ILGenerator il, Type returnValueType)
{
if (returnValueType == typeof( void ))
if (returnValueType == typeof(void))
{
il.Emit( OpCodes.Ldnull );
il.Emit(OpCodes.Ldnull);
}
else if (returnValueType.IsValueType)
{
il.Emit( OpCodes.Box, returnValueType );
il.Emit(OpCodes.Box, returnValueType);
}
il.Emit( OpCodes.Ret );
il.Emit(OpCodes.Ret);
}
private delegate Type GetTypeFromHandleDelegate( RuntimeTypeHandle handle );
private static readonly MethodInfo FnGetTypeFromHandle = new GetTypeFromHandleDelegate( Type.GetTypeFromHandle ).Method;
private delegate object ChangeTypeDelegate( object value, Type targetType, int argIndex );
private static readonly MethodInfo FnConvertArgumentIfNecessary = new ChangeTypeDelegate( ConvertValueTypeArgumentIfNecessary ).Method;
private delegate Type GetTypeFromHandleDelegate(RuntimeTypeHandle handle);
private static readonly MethodInfo FnGetTypeFromHandle = new GetTypeFromHandleDelegate(Type.GetTypeFromHandle).Method;
private delegate object ChangeTypeDelegate(object value, Type targetType, int argIndex);
private static readonly MethodInfo FnConvertArgumentIfNecessary = new ChangeTypeDelegate(ConvertValueTypeArgumentIfNecessary).Method;
/// <summary>
/// Converts <paramref name="value"/> to an instance of <paramref name="targetType"/> if necessary to
@@ -696,7 +803,7 @@ namespace Spring.Reflection.Dynamic
/// Note: <paramref name="targetType"/> is expected to be a value type!
/// </para>
/// </remarks>
public static object ConvertValueTypeArgumentIfNecessary( object value, Type targetType, int argIndex )
public static object ConvertValueTypeArgumentIfNecessary(object value, Type targetType, int argIndex)
{
if (value == null)
{
@@ -704,12 +811,12 @@ namespace Spring.Reflection.Dynamic
{
return null;
}
throw new InvalidCastException( string.Format( "Cannot convert NULL at position {0} to argument type {1}", argIndex, targetType.FullName ) );
throw new InvalidCastException(string.Format("Cannot convert NULL at position {0} to argument type {1}", argIndex, targetType.FullName));
}
Type valueType = value.GetType();
#if NET_2_0
if (ReflectionUtils.IsNullableType( targetType ))
if (ReflectionUtils.IsNullableType(targetType))
{
targetType = Nullable.GetUnderlyingType(targetType);
}
@@ -723,47 +830,47 @@ namespace Spring.Reflection.Dynamic
if (!valueType.IsValueType)
{
// we're facing a reftype/valuetype mix that never can convert
throw new InvalidCastException( string.Format( "Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName ) );
throw new InvalidCastException(string.Format("Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName));
}
// we're dealing only with ValueType's now - try to convert them
try
{
// TODO: allow widening conversions only
return Convert.ChangeType( value, targetType );
return Convert.ChangeType(value, targetType);
}
catch (Exception ex)
{
throw new InvalidCastException( string.Format( "Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName ), ex );
throw new InvalidCastException(string.Format("Cannot convert value '{0}' of type {1} at position {2} to argument type {3}", value, valueType.FullName, argIndex, targetType.FullName), ex);
}
}
private static void EmitTarget( ILGenerator il, Type targetType, bool isInstanceMethod )
private static void EmitTarget(ILGenerator il, Type targetType, bool isInstanceMethod)
{
il.Emit( (isInstanceMethod) ? OpCodes.Ldarg_1 : OpCodes.Ldarg_0 );
il.Emit((isInstanceMethod) ? OpCodes.Ldarg_1 : OpCodes.Ldarg_0);
if (targetType.IsValueType)
{
LocalBuilder local = il.DeclareLocal( targetType );
EmitUnbox( il, targetType );
il.Emit( OpCodes.Stloc_0 );
il.Emit( OpCodes.Ldloca_S, 0 );
LocalBuilder local = il.DeclareLocal(targetType);
EmitUnbox(il, targetType);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldloca_S, 0);
}
else
{
il.Emit( OpCodes.Castclass, targetType );
il.Emit(OpCodes.Castclass, targetType);
}
}
private static void EmitCall( ILGenerator il, MethodInfo method )
private static void EmitCall(ILGenerator il, MethodInfo method)
{
il.EmitCall( (method.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, method, null );
il.EmitCall((method.IsVirtual) ? OpCodes.Callvirt : OpCodes.Call, method, null);
}
private static void EmitConstant( ILGenerator il, object value )
private static void EmitConstant(ILGenerator il, object value)
{
if (value is String)
{
il.Emit( OpCodes.Ldstr, (string)value );
il.Emit(OpCodes.Ldstr, (string)value);
return;
}
@@ -771,78 +878,78 @@ namespace Spring.Reflection.Dynamic
{
if ((bool)value)
{
il.Emit( OpCodes.Ldc_I4_1 );
il.Emit(OpCodes.Ldc_I4_1);
}
else
{
il.Emit( OpCodes.Ldc_I4_0 );
il.Emit(OpCodes.Ldc_I4_0);
}
return;
}
if (value is Char)
{
il.Emit( OpCodes.Ldc_I4, (Char)value );
il.Emit( OpCodes.Conv_I2 );
il.Emit(OpCodes.Ldc_I4, (Char)value);
il.Emit(OpCodes.Conv_I2);
return;
}
if (value is byte)
{
il.Emit( OpCodes.Ldc_I4, (byte)value );
il.Emit( OpCodes.Conv_I1 );
il.Emit(OpCodes.Ldc_I4, (byte)value);
il.Emit(OpCodes.Conv_I1);
}
else if (value is Int16)
{
il.Emit( OpCodes.Ldc_I4, (Int16)value );
il.Emit( OpCodes.Conv_I2 );
il.Emit(OpCodes.Ldc_I4, (Int16)value);
il.Emit(OpCodes.Conv_I2);
}
else if (value is Int32)
{
il.Emit( OpCodes.Ldc_I4, (Int32)value );
il.Emit(OpCodes.Ldc_I4, (Int32)value);
}
else if (value is Int64)
{
il.Emit( OpCodes.Ldc_I8, (Int64)value );
il.Emit(OpCodes.Ldc_I8, (Int64)value);
}
else if (value is UInt16)
{
il.Emit( OpCodes.Ldc_I4, (UInt16)value );
il.Emit( OpCodes.Conv_U2 );
il.Emit(OpCodes.Ldc_I4, (UInt16)value);
il.Emit(OpCodes.Conv_U2);
}
else if (value is UInt32)
{
il.Emit( OpCodes.Ldc_I4, (UInt32)value );
il.Emit( OpCodes.Conv_U4 );
il.Emit(OpCodes.Ldc_I4, (UInt32)value);
il.Emit(OpCodes.Conv_U4);
}
else if (value is UInt64)
{
il.Emit( OpCodes.Ldc_I8, (UInt64)value );
il.Emit( OpCodes.Conv_U8 );
il.Emit(OpCodes.Ldc_I8, (UInt64)value);
il.Emit(OpCodes.Conv_U8);
}
else if (value is Single)
{
il.Emit( OpCodes.Ldc_R4, (Single)value );
il.Emit(OpCodes.Ldc_R4, (Single)value);
}
else if (value is Double)
{
il.Emit( OpCodes.Ldc_R8, (Double)value );
il.Emit(OpCodes.Ldc_R8, (Double)value);
}
}
private static readonly ConstructorInfo NewInvalidOperationException =
typeof( InvalidOperationException ).GetConstructor( new Type[] { typeof( string ) } );
typeof(InvalidOperationException).GetConstructor(new Type[] { typeof(string) });
/// <summary>
/// Generates code that throws <see cref="InvalidOperationException"/>.
/// </summary>
/// <param name="il">IL generator to use.</param>
/// <param name="message">Error message to use.</param>
private static void EmitThrowInvalidOperationException( ILGenerator il, string message )
private static void EmitThrowInvalidOperationException(ILGenerator il, string message)
{
il.Emit( OpCodes.Ldstr, message );
il.Emit( OpCodes.Newobj, NewInvalidOperationException );
il.Emit( OpCodes.Throw );
il.Emit(OpCodes.Ldstr, message);
il.Emit(OpCodes.Newobj, NewInvalidOperationException);
il.Emit(OpCodes.Throw);
}
}
}

View File

@@ -11,8 +11,6 @@
<AssemblyKeyContainerName>
</AssemblyKeyContainerName>
<AssemblyName>Spring.Core</AssemblyName>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
<DefaultClientScript>JScript</DefaultClientScript>
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
<DefaultTargetSchema>IE50</DefaultTargetSchema>
@@ -38,6 +36,8 @@
<IsWebBootstrapper>true</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\..\Spring.Net.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2008\Spring.Core\Debug\</OutputPath>
@@ -1013,6 +1013,7 @@
<Compile Include="Util\ITextPosition.cs" />
<Compile Include="Util\ObjectUtils.cs" />
<Compile Include="Util\ReflectionException.cs" />
<Compile Include="Util\SecurityCritical.cs" />
<Compile Include="Util\SystemUtils.cs" />
<Compile Include="Util\DynamicCodeManager.cs" />
<Compile Include="Util\Generic\CollectionUtils.cs" />

View File

@@ -247,8 +247,7 @@ namespace Spring.Util
#endif
try
{
// replaced with SafeConstructor() to avoid nasty "TargetInvocationException"s
//return constructor.Invoke(arguments);
// replaced with SafeConstructor() to avoid nasty "TargetInvocationException"s in NET >= 2.0
return (new SafeConstructor(constructor)).Invoke(arguments);
}
catch (Exception ex)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
#region License
/*
* Copyright <20> 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System.Runtime.CompilerServices;
using System.Security;
namespace Spring.Util
{
/// <summary>
/// Utility class to be used from within this assembly for executing security critical code
/// NEVER EVER MAKE THIS PUBLIC!
/// </summary>
/// <author>Erich Eichinger</author>
internal class SecurityCritical
{
internal delegate void PrivilegedCallback();
[SecurityCritical, SecurityTreatAsSafe]
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ExecutePrivileged(IStackWalk permission, PrivilegedCallback callback)
{
permission.Assert();
try
{
callback();
}
finally
{
CodeAccessPermission.RevertAssert();
}
}
}
}

View File

@@ -21,10 +21,8 @@
#region Imports
using System;
using System.Configuration;
using System.Reflection;
using System.Reflection;
using System.Threading;
using System.Xml;
#endregion

View File

@@ -233,7 +233,7 @@ namespace Spring.EnterpriseServices
}
///<summary>
/// Use Spring context to configure the serviced components.
/// Use Spring context to configure the serviced components within COM.
///</summary>
public bool UseSpring
{

View File

@@ -1,7 +1,24 @@
using System.Reflection;
using System.Security;
using System.Web.UI;
[assembly: AssemblyTitle("Spring.Web")]
[assembly: AssemblyDescription("Interfaces and classes that provide web application support in Spring.Net")]
[assembly: TagPrefix("Spring.Web.UI.Controls", "spring")]
//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")]
//[assembly: AssemblyKeyFile(@"C:\users\aseovic\projects\OpenSource\Spring.Net\Spring.Net.PrivateKey.keys")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityCritical]
#if NET_1_0 || NET_1_1
namespace System.Security
{
///<summary>
///</summary>
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method)]
internal class SecurityCriticalAttribute : Attribute
{ }
[AttributeUsage(AttributeTargets.Method)]
internal class SecurityTreatAsSafeAttribute : Attribute
{ }
}
#endif

View File

@@ -23,6 +23,8 @@
using System;
using System.Globalization;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Web;
using System.Web.Caching;
using System.Web.SessionState;
@@ -80,8 +82,8 @@ namespace Spring.Context.Support
private static CacheItemRemovedCallback s_originalCallback;
#if NET_2_0
// required to enable accessing HttpContext.Request during IHttpModule.Init() in integrated mode
private static readonly FieldInfo fiHideRequestResponse = typeof(HttpContext).GetField("HideRequestResponse", BindingFlags.Instance|BindingFlags.NonPublic);
private static readonly SafeField ContextHideRequestResponse = (fiHideRequestResponse!=null)?new SafeField(fiHideRequestResponse):null;
private static readonly FieldInfo fiHideRequestResponse;
private static readonly SafeField ContextHideRequestResponse;
#endif
/// <summary>
@@ -95,6 +97,20 @@ namespace Spring.Context.Support
static WebSupportModule()
{
s_log = LogManager.GetLogger(typeof(WebSupportModule));
#if NET_2_0
// required to enable accessing HttpContext.Request during IHttpModule.Init() in integrated mode
ContextHideRequestResponse = null;
try
{
fiHideRequestResponse = typeof(HttpContext).GetField("HideRequestResponse", BindingFlags.Instance|BindingFlags.NonPublic);
// fiHideRequestResponse.SetValue(HttpContext.Current, false);
ContextHideRequestResponse = (fiHideRequestResponse!=null)?new SafeField(fiHideRequestResponse):null;
}
catch(SecurityException sec)
{
s_log.Warn(string.Format("failed reflecting field HttpContext.HideRequestResponse due to security restrictions {0}", sec));
}
#endif
// register additional resource handler
ResourceHandlerRegistry.RegisterResourceHandler(WebUtils.DEFAULT_RESOURCE_PROTOCOL, typeof(WebResource));

View File

@@ -23,6 +23,8 @@
<StartupObject>
</StartupObject>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\..\Spring.Net.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\..\..\build\VS.Net.2008\Spring.Web\Debug\</OutputPath>
@@ -124,6 +126,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Util\ISessionState.cs" />
<Compile Include="Util\SecurityCritical.cs" />
<Compile Include="Web\Support\DefaultHandlerFactory.cs" />
<Compile Include="Web\Support\DefaultResultFactory.cs" />
<Compile Include="Web\Support\HandlerMap.cs" />

View File

@@ -0,0 +1,66 @@
#region License
/*
* Copyright © 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System.Runtime.CompilerServices;
using System.Security;
namespace Spring.Util
{
/// <summary>
/// Utility class to be used from within this assembly for executing security critical code
/// NEVER EVER MAKE THIS PUBLIC!
/// </summary>
/// <author>Erich Eichinger</author>
internal class SecurityCritical
{
internal delegate void PrivilegedCallback();
[SecurityCritical, SecurityTreatAsSafe]
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ExecutePrivileged(IStackWalk permission, PrivilegedCallback callback)
{
permission.Assert();
try
{
callback();
}
finally
{
CodeAccessPermission.RevertAssert();
}
}
// internal delegate TResult PrivilegedCallback<TResult>();
//
// [SecurityCritical, SecurityTreatAsSafe]
// internal static TResult ExecutePrivileged<TResult>(IStackWalk permission, PrivilegedCallback<TResult> callback)
// {
// permission.Assert();
// try
// {
// return callback();
// }
// finally
// {
// CodeAccessPermission.RevertAssert();
// }
// }
}
}

View File

@@ -23,6 +23,8 @@
using System;
using System.Collections;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using Common.Logging;
@@ -94,7 +96,25 @@ namespace Spring.Web.Support
/// <summary>
/// Holds an instance of the instrinsic System.Web.UI.SimpleHandlerFactory
/// </summary>
private static IHttpHandlerFactory s_simpleHandlerFactory;
private static readonly IHttpHandlerFactory s_simpleHandlerFactory;
static AbstractHandlerFactory()
{
PrivilegedCommand cmd = new PrivilegedCommand();
SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), new SecurityCritical.PrivilegedCallback(cmd.Execute));
s_simpleHandlerFactory = cmd.Result;
}
private class PrivilegedCommand
{
public IHttpHandlerFactory Result = null;
public void Execute()
{
Type simpleHandlerFactoryType = typeof(IHttpHandler).Assembly.GetType("System.Web.UI.SimpleHandlerFactory");
Result = (IHttpHandlerFactory)Activator.CreateInstance(simpleHandlerFactoryType, true);
}
}
/// <summary>
/// Get the global instance of System.Web.UI.SimpleHandlerFactory
@@ -110,8 +130,6 @@ namespace Spring.Web.Support
// instantiate lazy to avoid security exceptions in restricted reflection environments
if (s_simpleHandlerFactory == null)
{
Type simpleHandlerFactoryType = typeof(IHttpHandler).Assembly.GetType("System.Web.UI.SimpleHandlerFactory");
s_simpleHandlerFactory = (IHttpHandlerFactory)Activator.CreateInstance(simpleHandlerFactoryType, true);
}
return s_simpleHandlerFactory;
}
@@ -128,7 +146,7 @@ namespace Spring.Web.Support
/// </summary>
protected AbstractHandlerFactory()
{
this.Log = LogManager.GetLogger( this.GetType() );
this.Log = LogManager.GetLogger(this.GetType());
}
/// <summary>
@@ -149,14 +167,14 @@ namespace Spring.Web.Support
/// A new <see cref="System.Web.IHttpHandler"/> object that processes
/// the request.
/// </returns>
public virtual IHttpHandler GetHandler( HttpContext context, string requestType, string url, string physicalPath )
public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string physicalPath)
{
bool isDebug = Log.IsDebugEnabled;
#region Instrumentation
if (isDebug)
Log.Debug( string.Format( "GetHandler():resolving url '{0}'", url ) );
Log.Debug(string.Format("GetHandler():resolving url '{0}'", url));
#endregion
@@ -172,7 +190,7 @@ namespace Spring.Web.Support
if (isDebug)
{
Log.Debug( string.Format( "GetHandler():resolved url '{0}' from reusable handler cache", url ) );
Log.Debug(string.Format("GetHandler():resolved url '{0}' from reusable handler cache", url));
}
#endregion
@@ -187,7 +205,7 @@ namespace Spring.Web.Support
{
IConfigurableApplicationContext appContext = GetCheckedApplicationContext(url);
handler = CreateHandlerInstance( appContext, context, requestType, url, physicalPath );
handler = CreateHandlerInstance(appContext, context, requestType, url, physicalPath);
ApplyDependencyInjectionInfrastructure(handler, appContext);
@@ -207,7 +225,7 @@ namespace Spring.Web.Support
/// <param name="handler">
/// The <see cref="System.Web.IHttpHandler"/> object to release.
/// </param>
public virtual void ReleaseHandler( IHttpHandler handler )
public virtual void ReleaseHandler(IHttpHandler handler)
{ }
/// <summary>
@@ -219,7 +237,7 @@ namespace Spring.Web.Support
/// <param name="rawUrl">The requested <see cref="HttpRequest.RawUrl"/>.</param>
/// <param name="physicalPath">The physical path of the requested resource.</param>
/// <returns>A handler instance for processing the current request.</returns>
protected abstract IHttpHandler CreateHandlerInstance( IConfigurableApplicationContext appContext, HttpContext context, string requestType, string rawUrl, string physicalPath );
protected abstract IHttpHandler CreateHandlerInstance(IConfigurableApplicationContext appContext, HttpContext context, string requestType, string rawUrl, string physicalPath);
/// <summary>
/// Get the application context instance corresponding to the given absolute url and checks
@@ -236,16 +254,16 @@ namespace Spring.Web.Support
/// <remarks>
/// Calls <see cref="GetContext"/> to obtain a context instance.
/// </remarks>
protected IConfigurableApplicationContext GetCheckedApplicationContext( string url )
protected IConfigurableApplicationContext GetCheckedApplicationContext(string url)
{
IApplicationContext appContext = GetContext( url );
IApplicationContext appContext = GetContext(url);
if (appContext == null)
{
throw new ArgumentException( string.Format( "no application context for virtual path '{0}'", url ) );
throw new ArgumentException(string.Format("no application context for virtual path '{0}'", url));
}
if (!(appContext is IConfigurableApplicationContext))
{
throw new InvalidOperationException( string.Format( "application context '{0}' for virtual path '{1}' must implement IConfigurableApplicationContext", appContext.ToString(), url ) );
throw new InvalidOperationException(string.Format("application context '{0}' for virtual path '{1}' must implement IConfigurableApplicationContext", appContext.ToString(), url));
}
return (IConfigurableApplicationContext)appContext;
}
@@ -259,9 +277,9 @@ namespace Spring.Web.Support
/// Subclasses may override this method to change the context source.
/// By default, <see cref="WebApplicationContext.GetContext"/> is used for obtaining context instances.
/// </remarks>
protected virtual IApplicationContext GetContext( string virtualPath )
protected virtual IApplicationContext GetContext(string virtualPath)
{
return WebApplicationContext.GetContext( virtualPath );
return WebApplicationContext.GetContext(virtualPath);
}
/// <summary>
@@ -276,27 +294,27 @@ namespace Spring.Web.Support
/// <remarks>
/// Resolve an object definition by url.
/// </remarks>
protected internal static NamedObjectDefinition FindWebObjectDefinition( string appRelativeVirtualPath, IConfigurableListableObjectFactory objectFactory )
protected internal static NamedObjectDefinition FindWebObjectDefinition(string appRelativeVirtualPath, IConfigurableListableObjectFactory objectFactory)
{
ILog Log = LogManager.GetLogger( typeof( AbstractHandlerFactory ) );
ILog Log = LogManager.GetLogger(typeof(AbstractHandlerFactory));
bool isDebug = Log.IsDebugEnabled;
// lookup definition using app-relative url
if (isDebug)
Log.Debug( string.Format( "GetHandler():looking up definition for app-relative url '{0}'", appRelativeVirtualPath ) );
Log.Debug(string.Format("GetHandler():looking up definition for app-relative url '{0}'", appRelativeVirtualPath));
string objectDefinitionName = appRelativeVirtualPath;
IObjectDefinition pageDefinition = objectFactory.GetObjectDefinition( appRelativeVirtualPath, true );
IObjectDefinition pageDefinition = objectFactory.GetObjectDefinition(appRelativeVirtualPath, true);
if (pageDefinition == null)
{
// try using pagename+extension and pagename only
string pageExtension = Path.GetExtension( appRelativeVirtualPath );
string pageName = WebUtils.GetPageName( appRelativeVirtualPath );
string pageExtension = Path.GetExtension(appRelativeVirtualPath);
string pageName = WebUtils.GetPageName(appRelativeVirtualPath);
// only looks in the specified object factory -- it will *not* search parent contexts
pageDefinition = objectFactory.GetObjectDefinition( pageName + pageExtension, false );
pageDefinition = objectFactory.GetObjectDefinition(pageName + pageExtension, false);
if (pageDefinition == null)
{
pageDefinition = objectFactory.GetObjectDefinition( pageName, false );
pageDefinition = objectFactory.GetObjectDefinition(pageName, false);
if (pageDefinition != null)
objectDefinitionName = pageName;
}
@@ -308,21 +326,21 @@ namespace Spring.Web.Support
if (pageDefinition != null)
{
if (isDebug)
Log.Debug( string.Format( "GetHandler():found definition for page-name '{0}'", objectDefinitionName ) );
Log.Debug(string.Format("GetHandler():found definition for page-name '{0}'", objectDefinitionName));
}
else
{
if (isDebug)
Log.Debug( string.Format( "GetHandler():no definition found for page-name '{0}'", pageName ) );
Log.Debug(string.Format("GetHandler():no definition found for page-name '{0}'", pageName));
}
}
else
{
if (isDebug)
Log.Debug( string.Format( "GetHandler():found definition for page-url '{0}'", appRelativeVirtualPath ) );
Log.Debug(string.Format("GetHandler():found definition for page-url '{0}'", appRelativeVirtualPath));
}
return (pageDefinition == null) ? (NamedObjectDefinition)null : new NamedObjectDefinition( objectDefinitionName, pageDefinition );
return (pageDefinition == null) ? (NamedObjectDefinition)null : new NamedObjectDefinition(objectDefinitionName, pageDefinition);
}
/// <summary>
@@ -338,8 +356,8 @@ namespace Spring.Web.Support
}
else
{
if ( (handler is ISupportsWebDependencyInjection)
&& (((ISupportsWebDependencyInjection)handler).DefaultApplicationContext == null) )
if ((handler is ISupportsWebDependencyInjection)
&& (((ISupportsWebDependencyInjection)handler).DefaultApplicationContext == null))
{
((ISupportsWebDependencyInjection)handler).DefaultApplicationContext = applicationContext;
}

View File

@@ -22,9 +22,11 @@ using System;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Security;
using System.Security.Permissions;
using System.Web.UI;
using Spring.Reflection.Dynamic;
using Spring.Web.Support;
using Spring.Util;
#endregion
@@ -36,26 +38,20 @@ namespace Spring.Web.Support
/// <author>Erich Eichinger</author>
internal class ControlAccessor
{
private static readonly MethodInfo s_miClear = GetMethod("Clear");
private static MethodInfo GetMethod(string name)
{
return typeof(Control).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
}
private static FieldInfo GetField(string name)
{
return typeof(Control).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
}
private delegate ControlCollection CreateControlCollectionDelegate(Control target);
private delegate void AddedControlDelegate(Control target, Control control, int index);
private delegate void RemovedControlDelegate(Control target, Control control);
private delegate void VoidMethodDelegate(Control target);
private static readonly MethodInfo s_miClear;
private static readonly SafeField ControlsArrayField;
#if NET_2_0
private static readonly CreateControlCollectionDelegate BaseCreateControlCollection = (CreateControlCollectionDelegate) Delegate.CreateDelegate(typeof(CreateControlCollectionDelegate), GetMethod("CreateControlCollection"));
private static readonly AddedControlDelegate BaseAddedControl = (AddedControlDelegate) Delegate.CreateDelegate(typeof (AddedControlDelegate), GetMethod("AddedControl"));
private static readonly RemovedControlDelegate BaseRemovedControl = (RemovedControlDelegate) Delegate.CreateDelegate(typeof (RemovedControlDelegate), GetMethod("RemovedControl"));
private static readonly VoidMethodDelegate BaseClearNamingContainer = (VoidMethodDelegate) Delegate.CreateDelegate(typeof (VoidMethodDelegate), GetMethod("ClearNamingContainer"));
private static readonly CreateControlCollectionDelegate BaseCreateControlCollection;
private static readonly AddedControlDelegate BaseAddedControl;
private static readonly RemovedControlDelegate BaseRemovedControl;
private static readonly VoidMethodDelegate BaseClearNamingContainer;
#else
private class DynamicMethodWrapper
{
@@ -117,6 +113,56 @@ namespace Spring.Web.Support
private static readonly VoidMethodDelegate BaseClearNamingContainer = DynamicMethodWrapper.ClearNamingContainer(GetMethod("ClearNamingContainer"));
#endif
static ControlAccessor()
{
SafeField fldControls = null;
MethodInfo fnClear = null;
#if NET_2_0
SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
{
#endif
fnClear = GetMethod("Clear");
fldControls = new SafeField(typeof(ControlCollection).GetField("_controls", BindingFlags.Instance | BindingFlags.NonPublic));
#if NET_2_0
});
#endif
s_miClear = fnClear;
ControlsArrayField = fldControls;
#if NET_2_0
CreateControlCollectionDelegate fnBaseCreateControlCollection = null;
AddedControlDelegate fnBaseAddedControl = null;
RemovedControlDelegate fnBaseRemovedControl = null;
VoidMethodDelegate fnBaseClearNamingContainer = null;
#if NET_2_0
SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
{
#endif
fnBaseCreateControlCollection = (CreateControlCollectionDelegate)Delegate.CreateDelegate(typeof(CreateControlCollectionDelegate), GetMethod("CreateControlCollection"));
fnBaseAddedControl = (AddedControlDelegate)Delegate.CreateDelegate(typeof(AddedControlDelegate), GetMethod("AddedControl"));
fnBaseRemovedControl = (RemovedControlDelegate)Delegate.CreateDelegate(typeof(RemovedControlDelegate), GetMethod("RemovedControl"));
fnBaseClearNamingContainer = (VoidMethodDelegate)Delegate.CreateDelegate(typeof(VoidMethodDelegate), GetMethod("ClearNamingContainer"));
#if NET_2_0
});
#endif
BaseCreateControlCollection = fnBaseCreateControlCollection;
BaseAddedControl = fnBaseAddedControl;
BaseRemovedControl = fnBaseRemovedControl;
BaseClearNamingContainer = fnBaseClearNamingContainer;
#endif
}
private static MethodInfo GetMethod(string name)
{
return typeof(Control).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
}
private static FieldInfo GetField(string name)
{
return typeof(Control).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
}
private readonly Control _targetControl;
/// <summary>
@@ -187,7 +233,6 @@ namespace Spring.Web.Support
}
}
private static readonly SafeField ControlsArrayField = new SafeField(typeof(ControlCollection).GetField("_controls", BindingFlags.Instance|BindingFlags.NonPublic));
public void SetControlAt(Control control, int index)
{
Control[] controls = (Control[]) ControlsArrayField.GetValue(this.Controls);
@@ -217,24 +262,29 @@ namespace Spring.Web.Support
MethodInfo ensureOccasionalFields = GetMethod("EnsureOccasionalFields");
FieldInfo controls = occasionalFields.FieldType.GetField("Controls");
System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("get_Controls", typeof(ControlCollection), new Type[] { typeof(Control) }, typeof(Control).Module, true);
ILGenerator il = dm.GetILGenerator();
Label occFieldsNull = il.DefineLabel();
Label retControls = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Brfalse_S, occFieldsNull);
il.MarkLabel(retControls);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Ldfld, controls);
il.Emit(OpCodes.Ret);
il.MarkLabel(occFieldsNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, ensureOccasionalFields);
il.Emit(OpCodes.Br, retControls);
GetControlsDelegate handler = null;
return (GetControlsDelegate) dm.CreateDelegate(typeof(GetControlsDelegate));
SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
{
System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("get_Controls", typeof(ControlCollection), new Type[] { typeof(Control) }, typeof(Control).Module, true);
ILGenerator il = dm.GetILGenerator();
Label occFieldsNull = il.DefineLabel();
Label retControls = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Brfalse_S, occFieldsNull);
il.MarkLabel(retControls);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Ldfld, controls);
il.Emit(OpCodes.Ret);
il.MarkLabel(occFieldsNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, ensureOccasionalFields);
il.Emit(OpCodes.Br, retControls);
handler = (GetControlsDelegate) dm.CreateDelegate(typeof(GetControlsDelegate));
});
return handler;
}
private static SetControlsDelegate GetSetControlsDelegate()
@@ -243,53 +293,30 @@ namespace Spring.Web.Support
MethodInfo ensureOccasionalFields = GetMethod("EnsureOccasionalFields");
FieldInfo controls = occasionalFields.FieldType.GetField("Controls");
System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("set_Controls", null, new Type[] { typeof(Control), typeof(ControlCollection) }, typeof(Control).Module, true);
ILGenerator il = dm.GetILGenerator();
Label occFieldsNull = il.DefineLabel();
Label setControls = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Brfalse_S, occFieldsNull);
il.MarkLabel(setControls);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Stfld, controls);
il.Emit(OpCodes.Ret);
il.MarkLabel(occFieldsNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, ensureOccasionalFields);
il.Emit(OpCodes.Br, setControls);
return (SetControlsDelegate) dm.CreateDelegate(typeof(SetControlsDelegate));
SetControlsDelegate handler = null;
SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
{
System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("set_Controls", null, new Type[] { typeof(Control), typeof(ControlCollection) }, typeof(Control).Module, true);
ILGenerator il = dm.GetILGenerator();
Label occFieldsNull = il.DefineLabel();
Label setControls = il.DefineLabel();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Brfalse_S, occFieldsNull);
il.MarkLabel(setControls);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, occasionalFields);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Stfld, controls);
il.Emit(OpCodes.Ret);
il.MarkLabel(occFieldsNull);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, ensureOccasionalFields);
il.Emit(OpCodes.Br, setControls);
handler = (SetControlsDelegate) dm.CreateDelegate(typeof(SetControlsDelegate));
});
return handler;
}
// private static readonly Type s_tOccasionalFields = typeof(Control).GetNestedType("OccasionalFields", BindingFlags.NonPublic);
//
// private static readonly VoidMethodDelegate EnsureOccasionalFields = (VoidMethodDelegate) Delegate.CreateDelegate(typeof (VoidMethodDelegate), GetMethod("EnsureOccasionalFields"));
// private static readonly IDynamicField _occasionalFields = SafeField.CreateFrom(GetField("_occasionalFields"));
// private static readonly IDynamicField _controls = SafeField.CreateFrom(s_tOccasionalFields.GetField("Controls"));
//
// private ControlCollection GetChildControlCollection()
// {
// // we *must not* simply call control.Controls here!
// // Some controls (e.g. Repeater overload this property and call Control.EnsureChildControls()
// // which causes Control.ChildControlsCreated flag to be set and prevents children from being created after loading viewstate!
//
// EnsureOccasionalFields(_targetControl);
//
// object occasionalFields = _occasionalFields.GetValue(_targetControl);
// object childControls = _controls.GetValue(occasionalFields);
// return (ControlCollection) childControls;
// }
//
// private void SetChildControlCollection( ControlCollection controls )
// {
// EnsureOccasionalFields(_targetControl);
//
// object occasionalFields = _occasionalFields.GetValue(_targetControl);
// _controls.SetValue(occasionalFields, controls);
// }
#else
private static readonly IDynamicField fControls = SafeField.CreateFrom(GetField("_controls"));

View File

@@ -20,8 +20,11 @@
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Web.UI;
using Spring.Reflection.Dynamic;
using Spring.Util;
#endregion
@@ -33,12 +36,25 @@ namespace Spring.Web.Support
/// <author>Erich Eichinger</author>
internal class ControlCollectionAccessor
{
#if MONO_2_0
private static readonly IDynamicField _owner = new SafeField(typeof (ControlCollection).GetField("owner", BindingFlags.Instance | BindingFlags.NonPublic));
#else
private static readonly IDynamicField _owner = new SafeField(typeof (ControlCollection).GetField("_owner", BindingFlags.Instance | BindingFlags.NonPublic));
private static readonly IDynamicField _owner;
static ControlCollectionAccessor()
{
IDynamicField owner = null;
#if NET_2_0
SecurityCritical.ExecutePrivileged( new PermissionSet(PermissionState.Unrestricted), delegate
{
#endif
#if MONO_2_0
owner = new SafeField(typeof (ControlCollection).GetField("owner", BindingFlags.Instance | BindingFlags.NonPublic));
#else
owner = new SafeField(typeof (ControlCollection).GetField("_owner", BindingFlags.Instance | BindingFlags.NonPublic));
#endif
#if NET_2_0
});
#endif
_owner = owner;
}
private readonly ControlCollection _controls;
private readonly Type _controlsType;

View File

@@ -133,14 +133,13 @@ namespace Spring.Web.Support
factoryMethod = (CreateControlCollectionDelegate)s_collectionFactoryCache[ownerType];
if (factoryMethod == null)
{
Type interceptedCollectionType =
GetInterceptedCollectionType(collectionType, WebDependencyInjectionUtils.InjectDependenciesRecursive);
Type interceptedCollectionType = GetInterceptedCollectionType(
collectionType
, WebDependencyInjectionUtils.InjectDependenciesRecursive
);
ConstructorInfo ctor =
interceptedCollectionType.GetConstructor(new Type[] { typeof(Control) });
DynamicMethod dm =
new System.Reflection.Emit.DynamicMethod(string.Empty, typeof(ControlCollection),
new Type[] { typeof(Control) });
ConstructorInfo ctor = interceptedCollectionType.GetConstructor(new Type[] { typeof(Control) });
DynamicMethod dm = new DynamicMethod(string.Empty, typeof(ControlCollection), new Type[] { typeof(Control) });
ILGenerator il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, ctor);

View File

@@ -24,6 +24,8 @@ using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Security;
using System.Security.Permissions;
using System.Web;
using System.Web.Compilation;
using System.Web.UI;
@@ -46,17 +48,33 @@ namespace Spring.Web.Support
internal abstract class LocalResourceManager : ResourceManager
{
private delegate IResourceProvider GetResourceProviderDelegate( TemplateControl control );
private static readonly GetResourceProviderDelegate getLocalResourceProvider = (GetResourceProviderDelegate)Delegate.CreateDelegate( typeof( GetResourceProviderDelegate ), typeof( ResourceExpressionBuilder ).GetMethod( "GetLocalResourceProvider", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof( TemplateControl ) }, null ) );
private static readonly Type LocalResXResourceProviderFactoryType = typeof( IResourceProvider ).Assembly.GetType( "System.Web.Compilation.ResXResourceProviderFactory", true );
private static readonly Type LocalResXResourceProviderType = typeof( IResourceProvider ).Assembly.GetType( "System.Web.Compilation.LocalResXResourceProvider", true );
private static readonly ResourceProviderFactory LocalResXResourceProviderFactory = (ResourceProviderFactory)Activator.CreateInstance( LocalResXResourceProviderFactoryType, true );
private static readonly SafeMethod fnGetLocalResourceAssembly = new SafeMethod( LocalResXResourceProviderType.GetMethod( "GetLocalResourceAssembly", BindingFlags.Instance | BindingFlags.NonPublic ) );
private static readonly GetResourceProviderDelegate getLocalResourceProvider;
private static readonly Type LocalResXResourceProviderFactoryType;
private static readonly Type LocalResXResourceProviderType;
private static readonly ResourceProviderFactory LocalResXResourceProviderFactory;
private static readonly SafeMethod fnGetLocalResourceAssembly;
/// <summary>
/// Avoid beforeFieldInit
/// </summary>
static LocalResourceManager()
{ }
{
LocalResXResourceProviderFactoryType = typeof(IResourceProvider).Assembly.GetType("System.Web.Compilation.ResXResourceProviderFactory", true);
LocalResXResourceProviderType = typeof(IResourceProvider).Assembly.GetType("System.Web.Compilation.LocalResXResourceProvider", true);
GetResourceProviderDelegate fnGetResourceProvider = null;
ResourceProviderFactory rpf = null;
SafeMethod glra = null;
SecurityCritical.ExecutePrivileged(new PermissionSet(PermissionState.Unrestricted), delegate
{
fnGetResourceProvider = (GetResourceProviderDelegate)Delegate.CreateDelegate(typeof(GetResourceProviderDelegate), typeof(ResourceExpressionBuilder).GetMethod("GetLocalResourceProvider", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(TemplateControl) }, null));
rpf = (ResourceProviderFactory)Activator.CreateInstance( LocalResXResourceProviderFactoryType, true );
glra = new SafeMethod(LocalResXResourceProviderType.GetMethod("GetLocalResourceAssembly", BindingFlags.Instance | BindingFlags.NonPublic));
});
getLocalResourceProvider = fnGetResourceProvider;
LocalResXResourceProviderFactory = rpf;
fnGetLocalResourceAssembly = glra;
}
internal static ResourceManager GetLocalResourceManager( TemplateControl control )
{

View File

@@ -74,8 +74,6 @@ namespace Spring.Web.Support
/// <returns>Instance of the IHttpHandler object that should be used to process request.</returns>
public override IHttpHandler GetHandler(HttpContext context, string requestType, string url, string physicalPath)
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
return base.GetHandler(context, requestType, url, physicalPath);
}

View File

@@ -19,10 +19,13 @@
#region Imports
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Web.UI;
using Spring.Context;
using Spring.Context.Support;
using Spring.Reflection.Dynamic;
using Spring.Util;
using Spring.Web.Support;
#endregion
@@ -90,7 +93,17 @@ namespace Spring.Web.Support
, INamingContainer
{
#if NET_2_0
private static readonly SafeField refOccasionalFields = new SafeField(typeof(Control).GetField("_occasionalFields", BindingFlags.Instance|BindingFlags.NonPublic));
private static readonly SafeField refOccasionalFields;
static NamingContainerSupportsWebDependencyInjectionOwnerProxy()
{
SafeField fld = null;
SecurityCritical.ExecutePrivileged( new PermissionSet(PermissionState.Unrestricted), delegate
{
fld = new SafeField(typeof(Control).GetField("_occasionalFields", BindingFlags.Instance | BindingFlags.NonPublic));
});
refOccasionalFields = fld;
}
#endif
public NamingContainerSupportsWebDependencyInjectionOwnerProxy(IApplicationContext defaultApplicationContext, Control targetControl) : base(defaultApplicationContext, targetControl)

View File

@@ -174,6 +174,13 @@ namespace Spring.Web.UI.Controls
}
}
/// <summary>
/// Expose the context of this panel for medium trust safe access in e.g. <see cref="VisibleIf"/>.
/// </summary>
public new virtual HttpContext Context
{
get { return base.Context; }
}
#region Dependency Injection Support
private IApplicationContext _defaultApplicationContext;

View File

@@ -740,6 +740,8 @@ namespace Spring.Web.UI
set { this.sharedState = value; }
}
#endregion
#if NET_2_0
/// <summary>
/// Overrides the default PreviousPage property to return an instance of <see cref="Spring.Web.UI.Page"/>,
@@ -750,8 +752,16 @@ namespace Spring.Web.UI
get { return this.Context.PreviousHandler as Page; }
}
#endif
#endregion
///<summary>
/// Publish <see cref="HttpContext"/> associated with this page for convenient usage in Binding Expressions
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new virtual HttpContext Context
{
get {
return base.Context; }
}
#region Master Page support

View File

@@ -1110,6 +1110,19 @@ namespace Spring.Web.UI
get { return (Page)base.Page; }
}
///<summary>
/// Publish <see cref="HttpContext"/> associated with this page for convenient usage in Binding Expressions
///</summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new virtual HttpContext Context
{
get
{
return base.Context;
}
}
#endregion
#region Helper Methods

View File

@@ -3,6 +3,7 @@ using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using NUnit.Framework;
using Spring.Context.Support;
@@ -264,14 +265,26 @@ namespace Spring.Reflection.Dynamic
public class MyStaticClass
{
public const Int64 MyConst = 3456;
public static readonly string myReadonlyField = "hohoho";
public static readonly string myReadonlyField;
private static readonly string myPrivateReadonlyField;
public static string myField;
static MyStaticClass()
{
myReadonlyField = "hohoho";
myPrivateReadonlyField = "hahaha";
}
public static string MyProperty
{
get { return myField; }
set { myField = value; }
}
public static string MyPrivateReadOnylFieldAccessor
{
get { return myPrivateReadonlyField; }
}
}
public struct MyStaticStruct

View File

@@ -23,6 +23,8 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using NUnit.Framework;
using Spring.Context.Support;
@@ -125,10 +127,54 @@ namespace Spring.Reflection.Dynamic
catch (InvalidOperationException) { }
IDynamicField myReadonlyField = Create( typeof( MyStaticClass ).GetField( "myReadonlyField" ) );
Assert.AreEqual( "hohoho", myReadonlyField.GetValue( null ) );
string s2 = (string) myReadonlyField.GetValue(null);
string s1 = MyStaticClass.myReadonlyField;
Assert.AreEqual(s1, s2);
}
#if NET_2_0
[Test]
public void CanReadPrivateReadOnlyField()
{
IDynamicField myPrivateReadonlyField2 = null;
FieldInfo fieldInfo = typeof(MyStaticClass).GetField("myPrivateReadonlyField", BindingFlags.Static | BindingFlags.NonPublic);
myPrivateReadonlyField2 = Create(fieldInfo);
string u2 = (string)myPrivateReadonlyField2.GetValue(null);
string u1 = "hahaha";
Assert.AreEqual(u1, u2);
}
[Test, Ignore("TODO: this works as expected when run using TD.NET & R# (in VS2k8), but fails with nant/NET 2.0 ?!?")]
public void CannotReadPrivateReadOnlyFieldIfNoReflectionPermission()
{
FieldInfo fieldInfo = typeof(MyStaticClass).GetField("myPrivateReadonlyField", BindingFlags.Static | BindingFlags.NonPublic);
try
{
myReadonlyField.SetValue( null, "some other string" );
SecurityTemplate.MediumTrustInvoke( delegate
{
IDynamicField myPrivateReadonlyField2 = Create(fieldInfo);
});
Assert.Fail("private field must not be accessible in medium trust: " + fieldInfo);
}
catch (SecurityException sex)
{
Assert.IsTrue( sex.Message.IndexOf("ReflectionPermission") > -1 );
}
}
#endif
[Test]
public void CannotSetStaticReadOnlyField()
{
IDynamicField myReadonlyField = Create(typeof(MyStaticClass).GetField("myReadonlyField"));
try
{
myReadonlyField.SetValue(null, "some other string");
Assert.Fail();
}
catch (InvalidOperationException) { }
}

View File

@@ -0,0 +1,526 @@
#region License
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
#if NET_2_0
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Drawing.Printing;
using System.IO;
using System.Net;
//using System.Net.Mail;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Configuration;
namespace Spring
{
/// <summary>
/// Allows to invoke parts of your code within the context of a certain PermissionSet.
/// </summary>
/// <remarks>
/// <para>
/// You may also use the static method <see cref="LoadDomainPolicyFromAppConfig"/> and
/// <see cref="LoadDomainPolicyFromUri"/> to load a <see cref="PolicyLevel"/> instance
/// yourself and apply it on your application domain using <see cref="AppDomain.SetAppDomainPolicy"/>. Note,
/// that you must set the policy *before* an assembly gets loaded to apply that policy on that assembly!
/// </para>
/// <para>
/// The policy file format is the one used by <see cref="SecurityManager.LoadPolicyLevelFromString"/>.
/// You get good examples from your %FrameworkDir%/CONFIG/ directory (e.g. 'web_mediumtrust.config').
/// </para>
/// </remarks>
/// <author>Erich Eichinger</author>
public class SecurityTemplate
{
/// <summary>
/// The default full trust permission set name ("FullTrust")
/// </summary>
public static readonly string PERMISSIONSET_FULLTRUST = "FullTrust";
/// <summary>
/// The default no trust permission set name ("Nothing")
/// </summary>
public static readonly string PERMISSIONSET_NOTHING = "Nothing";
/// <summary>
/// The default medium trust permission set name ("MediumTrust")
/// </summary>
public static readonly string PERMISSIONSET_MEDIUMTRUST = "MediumTrust";
/// <summary>
/// The default low trust permission set name ("LowTrust")
/// </summary>
public static readonly string PERMISSIONSET_LOWTRUST = "LowTrust";
/// <summary>
/// The default asp.net permission set name ("ASP.NET")
/// </summary>
public static readonly string PERMISSIONSET_ASPNET = "ASP.Net";
private readonly PolicyLevel _domainPolicy;
// private readonly Dictionary<string, SecurityContext> securityContextCache = new Dictionary<string, SecurityContext>();
private bool throwOnUnknownPermissionSet = true;
/// <summary>
/// Avoid beforeFieldInit
/// </summary>
static SecurityTemplate()
{}
/// <summary>
/// Invoke the specified callback in a medium trusted context
/// </summary>
public static void MediumTrustInvoke( ThreadStart callback )
{
SecurityTemplate template = new SecurityTemplate(false);
template.PartialTrustInvoke(PERMISSIONSET_MEDIUMTRUST, callback);
}
/// <summary>
/// Access the domain <see cref="PolicyLevel"/> of this <see cref="SecurityTemplate"/> instance.
/// </summary>
public PolicyLevel DomainPolicy
{
get { return _domainPolicy; }
}
/// <summary>
/// Whether to throw an <see cref="ArgumentOutOfRangeException"/> in case
/// the permission set name is not found when invoking <see cref="PartialTrustInvoke(string,ThreadStart)"/>.
/// Defaults to <c>true</c>.
/// </summary>
public bool ThrowOnUnknownPermissionSet
{
get { return throwOnUnknownPermissionSet; }
set
{
throwOnUnknownPermissionSet = value;
// securityContextCache.Clear(); // clear cache
}
}
/// <summary>
/// Creates a new instance providing default "FullTrust", "Nothing", "MediumTrust" and "LowTrust" permissionsets
/// </summary>
/// <param name="allowUnmanagedCode">NCover requires unmangaged code permissions, set this flag <c>true</c> in this case.</param>
private SecurityTemplate(bool allowUnmanagedCode)
{
PolicyLevel pLevel = PolicyLevel.CreateAppDomainLevel();
// NOTHING permissionset
if (null == pLevel.GetNamedPermissionSet(PERMISSIONSET_NOTHING))
{
NamedPermissionSet noPermissionSet = new NamedPermissionSet(PERMISSIONSET_NOTHING, PermissionState.None);
noPermissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.NoFlags));
pLevel.AddNamedPermissionSet(noPermissionSet);
}
// FULLTRUST permissionset
if (null == pLevel.GetNamedPermissionSet(PERMISSIONSET_FULLTRUST))
{
NamedPermissionSet fulltrustPermissionSet = new NamedPermissionSet(PERMISSIONSET_FULLTRUST, PermissionState.Unrestricted);
pLevel.AddNamedPermissionSet(fulltrustPermissionSet);
}
// MEDIUMTRUST permissionset (corresponds to ASP.Net permission set in web_mediumtrust.config)
NamedPermissionSet mediumTrustPermissionSet = new NamedPermissionSet(PERMISSIONSET_MEDIUMTRUST, PermissionState.None);
mediumTrustPermissionSet.AddPermission(new AspNetHostingPermission(AspNetHostingPermissionLevel.Medium));
mediumTrustPermissionSet.AddPermission(new DnsPermission(PermissionState.Unrestricted));
mediumTrustPermissionSet.AddPermission(new EnvironmentPermission(EnvironmentPermissionAccess.Read,
"TEMP;TMP;USERNAME;OS;COMPUTERNAME"));
mediumTrustPermissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.AllAccess,
AppDomain.CurrentDomain.BaseDirectory));
IsolatedStorageFilePermission isolatedStorageFilePermission = new IsolatedStorageFilePermission(PermissionState.None);
isolatedStorageFilePermission.UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByUser;
isolatedStorageFilePermission.UserQuota = 9223372036854775807;
mediumTrustPermissionSet.AddPermission(isolatedStorageFilePermission);
mediumTrustPermissionSet.AddPermission(new PrintingPermission(PrintingPermissionLevel.DefaultPrinting));
SecurityPermissionFlag securityPermissionFlag = SecurityPermissionFlag.Assertion | SecurityPermissionFlag.Execution |
SecurityPermissionFlag.ControlThread | SecurityPermissionFlag.ControlPrincipal |
SecurityPermissionFlag.RemotingConfiguration;
if (allowUnmanagedCode)
{
securityPermissionFlag |= SecurityPermissionFlag.UnmanagedCode;
}
mediumTrustPermissionSet.AddPermission(new SecurityPermission(securityPermissionFlag));
#if NET_2_0
mediumTrustPermissionSet.AddPermission(new System.Net.Mail.SmtpPermission(System.Net.Mail.SmtpAccess.Connect));
#endif
mediumTrustPermissionSet.AddPermission(new SqlClientPermission(PermissionState.Unrestricted));
mediumTrustPermissionSet.AddPermission(new WebPermission());
pLevel.AddNamedPermissionSet(mediumTrustPermissionSet);
// LOWTRUST permissionset (corresponds to ASP.Net permission set in web_mediumtrust.config)
NamedPermissionSet lowTrustPermissionSet = new NamedPermissionSet(PERMISSIONSET_LOWTRUST, PermissionState.None);
lowTrustPermissionSet.AddPermission(new AspNetHostingPermission(AspNetHostingPermissionLevel.Low));
lowTrustPermissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery,
AppDomain.CurrentDomain.BaseDirectory));
IsolatedStorageFilePermission isolatedStorageFilePermissionLow = new IsolatedStorageFilePermission(PermissionState.None);
isolatedStorageFilePermissionLow.UsageAllowed = IsolatedStorageContainment.AssemblyIsolationByUser;
isolatedStorageFilePermissionLow.UserQuota = 1048576;
lowTrustPermissionSet.AddPermission(isolatedStorageFilePermissionLow);
SecurityPermissionFlag securityPermissionFlagLow = SecurityPermissionFlag.Execution;
if (allowUnmanagedCode)
{
securityPermissionFlagLow |= SecurityPermissionFlag.UnmanagedCode;
}
lowTrustPermissionSet.AddPermission(new SecurityPermission(securityPermissionFlagLow));
pLevel.AddNamedPermissionSet(lowTrustPermissionSet);
// UnionCodeGroup rootCodeGroup = new UnionCodeGroup(new AllMembershipCondition(), new PolicyStatement(noPermissionSet, PolicyStatementAttribute.Nothing));
// pLevel.RootCodeGroup = rootCodeGroup;
_domainPolicy = pLevel;
}
/// <summary>
/// Loads domain policy from specified file
/// </summary>
/// <param name="securityConfigurationFile"></param>
public SecurityTemplate(FileInfo securityConfigurationFile)
{
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
_domainPolicy = LoadDomainPolicyFromUri(new Uri(securityConfigurationFile.FullName), appDirectory, string.Empty);
}
/// <summary>
/// Create a security tool from the specified domainPolicy
/// </summary>
public SecurityTemplate(PolicyLevel domainPolicy)
{
this._domainPolicy = domainPolicy;
}
/// <summary>
/// Invokes the given callback using the policy's default
/// partial trust permissionset ("ASP.Net" <see cref="PERMISSIONSET_ASPNET"/>).
/// </summary>
public void PartialTrustInvoke(ThreadStart callback)
{
string defaultPermissionSetName = PERMISSIONSET_MEDIUMTRUST;
if (null != GetNamedPermissionSet(PERMISSIONSET_ASPNET))
{
defaultPermissionSetName = PERMISSIONSET_ASPNET;
}
PartialTrustInvoke(defaultPermissionSetName, callback);
}
/// <summary>
/// Invokes the given callback using the specified permissionset.
/// </summary>
// [SecurityTreatAsSafe, SecurityCritical]
public void PartialTrustInvoke(string permissionSetName, ThreadStart callback)
{
PermissionSet ps = null;
ps = GetNamedPermissionSet(permissionSetName);
if (ps == null && throwOnUnknownPermissionSet)
{
throw new ArgumentOutOfRangeException("permissionSetName", permissionSetName,
string.Format("unknown PermissionSet name '{0}'",
permissionSetName));
}
if (!IsFullTrust(ps))
{
ps.PermitOnly();
callback();
CodeAccessPermission.RevertPermitOnly();
}
else
{
callback();
}
}
private PermissionSet GetNamedPermissionSet(string name)
{
if (_domainPolicy != null)
{
return _domainPolicy.GetNamedPermissionSet(name);
}
return null;
}
/// <summary>
/// Loads the policy configuration from app.config configuration section
/// </summary>
/// <example>
/// Configuration is identical to web.config:
/// <code>
/// &lt;configuration&gt;
/// &lt;system.web&gt;
/// &lt;securityPolicy&gt;
/// &lt;trustLevel name=&quot;Full&quot; policyFile=&quot;internal&quot;/&gt;
/// &lt;trustLevel name=&quot;High&quot; policyFile=&quot;web_hightrust.config&quot;/&gt;
/// &lt;trustLevel name=&quot;Medium&quot; policyFile=&quot;web_mediumtrust.config&quot;/&gt;
/// &lt;trustLevel name=&quot;Low&quot; policyFile=&quot;web_lowtrust.config&quot;/&gt;
/// &lt;trustLevel name=&quot;Minimal&quot; policyFile=&quot;web_minimaltrust.config&quot;/&gt;
/// &lt;/securityPolicy&gt;
/// &lt;trust level=&quot;Medium&quot; originUrl=&quot;&quot;/&gt;
/// &lt;/system.web&gt;
/// &lt;/configuration&gt;
/// </code>
/// </example>
/// <param name="throwOnError"></param>
/// <returns></returns>
public static PolicyLevel LoadDomainPolicyFromAppConfig(bool throwOnError)
{
TrustSection trustSection = (TrustSection)ConfigurationManager.GetSection("system.web/trust");
SecurityPolicySection securityPolicySection = (SecurityPolicySection)ConfigurationManager.GetSection("system.web/securityPolicy");
if ((trustSection == null) || string.IsNullOrEmpty(trustSection.Level))
{
if (!throwOnError)
return null;
throw new ConfigurationErrorsException("Configuration section <system.web/trust> not found ");
}
if (trustSection.Level == "Full")
{
return null;
}
if ((securityPolicySection == null) || (securityPolicySection.TrustLevels[trustSection.Level] == null))
{
if (!throwOnError)
return null;
throw new ConfigurationErrorsException(string.Format("configuration <system.web/securityPolicy/trustLevel@name='{0}'> not found", trustSection.Level));
}
string policyFileExpanded = GetPolicyFilenameExpanded(securityPolicySection.TrustLevels[trustSection.Level]);
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
PolicyLevel domainPolicy = LoadDomainPolicyFromUri(new Uri(policyFileExpanded), appDirectory, trustSection.OriginUrl);
return domainPolicy;
}
/// <summary>
/// Loads a policy from a file (<see cref="SecurityManager.LoadPolicyLevelFromFile"/>),
/// replacing placeholders
/// <list>
/// <item>$AppDir$, $AppDirUrl$ => <paramref name="appDirectory"/></item>
/// <item>$CodeGen$ => (TODO)</item>
/// <item>$OriginHost$ => <paramref name="originUrl"/></item>
/// <item>$Gac$ => the current machine's GAC path</item>
/// </list>
/// </summary>
/// <param name="policyFileLocation"></param>
/// <param name="originUrl"></param>
/// <param name="appDirectory"></param>
/// <returns></returns>
public static PolicyLevel LoadDomainPolicyFromUri(Uri policyFileLocation, string appDirectory, string originUrl)
{
bool foundGacToken = false;
PolicyLevel domainPolicy = CreatePolicyLevel(policyFileLocation, appDirectory, appDirectory, originUrl, out foundGacToken);
if (foundGacToken)
{
CodeGroup rootCodeGroup = domainPolicy.RootCodeGroup;
bool hasGacMembershipCondition = false;
foreach (CodeGroup childCodeGroup in rootCodeGroup.Children)
{
if (childCodeGroup.MembershipCondition is GacMembershipCondition)
{
hasGacMembershipCondition = true;
break;
}
}
if (!hasGacMembershipCondition && (rootCodeGroup is FirstMatchCodeGroup))
{
FirstMatchCodeGroup firstMatchCodeGroup = (FirstMatchCodeGroup)rootCodeGroup;
if ((firstMatchCodeGroup.MembershipCondition is AllMembershipCondition) && (firstMatchCodeGroup.PermissionSetName == PERMISSIONSET_NOTHING))
{
PermissionSet unrestrictedPermissionSet = new PermissionSet(PermissionState.Unrestricted);
CodeGroup gacGroup = new UnionCodeGroup(new GacMembershipCondition(), new PolicyStatement(unrestrictedPermissionSet));
CodeGroup rootGroup = new FirstMatchCodeGroup(rootCodeGroup.MembershipCondition, rootCodeGroup.PolicyStatement);
foreach (CodeGroup childGroup in rootCodeGroup.Children)
{
if (((childGroup is UnionCodeGroup) && (childGroup.MembershipCondition is UrlMembershipCondition)) && (childGroup.PolicyStatement.PermissionSet.IsUnrestricted() && (gacGroup != null)))
{
rootGroup.AddChild(gacGroup);
gacGroup = null;
}
rootGroup.AddChild(childGroup);
}
domainPolicy.RootCodeGroup = rootGroup;
}
}
}
return domainPolicy;
}
private static PolicyLevel CreatePolicyLevel(Uri configFile, string appDir, string binDir, string strOriginUrl, out bool foundGacToken)
{
WebClient webClient = new WebClient();
string strXmlPolicy = webClient.DownloadString(configFile);
appDir = FileUtil.RemoveTrailingDirectoryBackSlash(appDir);
binDir = FileUtil.RemoveTrailingDirectoryBackSlash(binDir);
strXmlPolicy = strXmlPolicy.Replace("$AppDir$", appDir).Replace("$AppDirUrl$", MakeFileUrl(appDir)).Replace("$CodeGen$", MakeFileUrl(binDir));
if (strOriginUrl == null)
{
strOriginUrl = string.Empty;
}
strXmlPolicy = strXmlPolicy.Replace("$OriginHost$", strOriginUrl);
if (strXmlPolicy.IndexOf("$Gac$", StringComparison.Ordinal) != -1)
{
string gacLocation = GetGacLocation();
if (gacLocation != null)
{
gacLocation = MakeFileUrl(gacLocation);
}
if (gacLocation == null)
{
gacLocation = string.Empty;
}
strXmlPolicy = strXmlPolicy.Replace("$Gac$", gacLocation);
foundGacToken = true;
}
else
{
foundGacToken = false;
}
return SecurityManager.LoadPolicyLevelFromString(strXmlPolicy, PolicyLevelType.AppDomain);
}
private static string GetPolicyFilenameExpanded(TrustLevel trustLevel)
{
bool isRelative = true;
if (trustLevel.PolicyFile.Length > 1)
{
char ch = trustLevel.PolicyFile[1];
char ch2 = trustLevel.PolicyFile[0];
if (ch == ':')
{
isRelative = false;
}
else if ((ch2 == '\\') && (ch == '\\'))
{
isRelative = false;
}
}
if (isRelative)
{
string configurationElementFileSource = trustLevel.ElementInformation.Properties["policyFile"].Source;
string path = configurationElementFileSource.Substring(0, configurationElementFileSource.LastIndexOf('\\') + 1);
return path + trustLevel.PolicyFile;
}
return trustLevel.PolicyFile;
}
[DllImport("mscorwks.dll", CharSet = CharSet.Unicode)]
private static extern int GetCachePath(int dwCacheFlags, StringBuilder pwzCachePath, ref int pcchPath);
private static string GetGacLocation()
{
int capacity = 0x106;
StringBuilder pwzCachePath = new StringBuilder(capacity);
int pcchPath = capacity - 2;
int hRes = GetCachePath(2, pwzCachePath, ref pcchPath);
if (hRes < 0)
{
throw new HttpException("failed obtaining GAC path", hRes);
}
return pwzCachePath.ToString();
}
private static string MakeFileUrl(string path)
{
Uri uri = new Uri(path);
return uri.ToString();
}
private class FileUtil
{
internal static string RemoveTrailingDirectoryBackSlash(string path)
{
if (path == null)
{
return null;
}
int length = path.Length;
if ((length > 3) && (path[length - 1] == '\\'))
{
path = path.Substring(0, length - 1);
}
return path;
}
}
private static bool IsFullTrust(PermissionSet perms)
{
if (perms != null)
{
return perms.IsUnrestricted();
}
return true;
}
// [SecurityTreatAsSafe, SecurityCritical]
// private bool NeedPartialTrustInvoke(string permissionSetName)
// {
// if (_domainPolicy == null) return false;
//
// SecurityContext securityContext = null;
// if (!securityContextCache.ContainsKey(permissionSetName))
// {
// NamedPermissionSet permissionSet = _domainPolicy.GetNamedPermissionSet(permissionSetName);
// if (permissionSet == null && throwOnUnknownPermissionSet)
// {
// throw new ArgumentOutOfRangeException("permissionSetName", permissionSetName, "Undefined permission set");
// }
// if (!IsFullTrust(permissionSet))
// {
// try
// {
// permissionSet.PermitOnly();
// securityContext = CaptureSecurityContextNoIdentityFlow();
// }
// finally
// {
// CodeAccessPermission.RevertPermitOnly();
// }
// }
// securityContextCache[permissionSetName] = securityContext;
// }
// else
// {
// securityContext = securityContextCache[permissionSetName];
// }
// return (securityContext != null);
// }
// [SecurityCritical]
// private static SecurityContext CaptureSecurityContextNoIdentityFlow()
// {
// if (SecurityContext.IsWindowsIdentityFlowSuppressed())
// {
// return SecurityContext.Capture();
// }
// using (SecurityContext.SuppressFlowWindowsIdentity())
// {
// return SecurityContext.Capture();
// }
// }
}
}
#endif

View File

@@ -656,6 +656,7 @@
<Compile Include="Reflection\Dynamic\DynamicPropertyTests.cs" />
<Compile Include="Reflection\Dynamic\SafeFieldTests.cs" />
<Compile Include="Reflection\Dynamic\SafePropertyTests.cs" />
<Compile Include="SecurityTemplate.cs" />
<Compile Include="StandardsComplianceTest.cs">
<SubType>Code</SubType>
</Compile>

View File

@@ -1,4 +1,8 @@
using System;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Web;
using NUnit.Framework;
namespace Spring.Util
@@ -46,9 +50,50 @@ namespace Spring.Util
ReflectionUtils.MemberwiseCopy(i2, i1);
Assert.AreEqual(i2, i1);
Assert.AreEqual(i1, i2);
}
}
#if NET_2_0
[Test]
public void MediumTrustAllowsCopyingBetweenTypesFromSameModule()
{
SampleBaseClass i1 = new SampleDerivedClass("1st config val");
SampleBaseClass i2 = new SampleFurtherDerivedClass("2nd config val");
SecurityTemplate.MediumTrustInvoke(new ThreadStart(new CopyCommand(i2, i1).Execute));
Assert.AreEqual(i1, i2);
}
[Test]
public void MediumTrustThrowsSecurityExceptionWhenCopyingBetweenTypesFromDifferentModules()
{
Exception e1 = new Exception("my name is e1");
HttpException e2 = new HttpException("my name is e2");
// I know, I am a bit paranoid about that basic assumption
Assert.AreNotEqual( e1.GetType().Assembly, e2.GetType().Assembly );
SecurityTemplate.MediumTrustInvoke(new ThreadStart(new CopyCommand(e2, e1).Execute));
Assert.AreEqual(e1.Message, e2.Message);
}
class CopyCommand
{
private object a;
private object b;
public CopyCommand(object a, object b)
{
this.a = a;
this.b = b;
}
public void Execute()
{
ReflectionUtils.MemberwiseCopy(a, b);
}
}
#endif
}
#region Test Support Classes
@@ -57,7 +102,7 @@ namespace Spring.Util
private const string MyConstant = "SampleBaseClass.MyConstant";
private readonly string _someReadOnlyVal = "SampleBaseClass.SomeReadOnlyVal";
protected readonly string _someProtectedReadOnlyVal = "SampleBaseClass.SomeProtectedReadOnlyVal";
private string _someConfigVal = "SampleBaseClass.SomeConfigVal";
private string _someConfigVal;
public SampleBaseClass(string someConfigVal)
{
@@ -76,9 +121,12 @@ namespace Spring.Util
public override bool Equals(object obj)
{
if (this == obj) return true;
SampleBaseClass sampleBaseClass = obj as SampleBaseClass;
if (sampleBaseClass == null) return false;
if (ReferenceEquals(obj, null) || (!this.GetType().IsAssignableFrom(obj.GetType())))
return false;
if (ReferenceEquals(this , obj))
return true;
SampleBaseClass sampleBaseClass = (SampleBaseClass) obj;
if (!Equals(_someReadOnlyVal, sampleBaseClass._someReadOnlyVal)) return false;
if (!Equals(_someProtectedReadOnlyVal, sampleBaseClass._someProtectedReadOnlyVal)) return false;
if (!Equals(_someConfigVal, sampleBaseClass._someConfigVal)) return false;
@@ -102,11 +150,12 @@ namespace Spring.Util
public override bool Equals(object obj)
{
if (this == obj) return true;
SampleDerivedClass sampleDerivedClass = obj as SampleDerivedClass;
if (sampleDerivedClass == null) return false;
if (!base.Equals(obj)) return false;
if (!Equals(_someConfigVal, sampleDerivedClass._someConfigVal)) return false;
if (!base.Equals(obj))
return false;
SampleDerivedClass sampleDerivedClass = (SampleDerivedClass)obj;
if (!Equals(_someConfigVal, sampleDerivedClass._someConfigVal))
return false;
return true;
}
}