You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,279 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="Compiler.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Xml.Serialization {
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Principal;
|
||||
using System.Security.Policy;
|
||||
using System.Threading;
|
||||
using System.Xml.Serialization.Configuration;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
internal class Compiler {
|
||||
bool debugEnabled = DiagnosticsSwitches.KeepTempFiles.Enabled;
|
||||
Hashtable imports = new Hashtable();
|
||||
StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
|
||||
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
protected string[] Imports {
|
||||
get {
|
||||
string[] array = new string[imports.Values.Count];
|
||||
imports.Values.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
// SxS: This method does not take any resource name and does not expose any resources to the caller.
|
||||
// It's OK to suppress the SxS warning.
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
internal void AddImport(Type type, Hashtable types) {
|
||||
if (type == null)
|
||||
return;
|
||||
if (TypeScope.IsKnownType(type))
|
||||
return;
|
||||
if (types[type] != null)
|
||||
return;
|
||||
types[type] = type;
|
||||
Type baseType = type.BaseType;
|
||||
if (baseType != null)
|
||||
AddImport(baseType, types);
|
||||
|
||||
Type declaringType = type.DeclaringType;
|
||||
if (declaringType != null)
|
||||
AddImport(declaringType, types);
|
||||
|
||||
foreach (Type intf in type.GetInterfaces())
|
||||
AddImport(intf, types);
|
||||
|
||||
ConstructorInfo[] ctors = type.GetConstructors();
|
||||
for (int i = 0; i < ctors.Length; i++) {
|
||||
ParameterInfo[] parms = ctors[i].GetParameters();
|
||||
for (int j = 0; j < parms.Length; j++) {
|
||||
AddImport(parms[j].ParameterType, types);
|
||||
}
|
||||
}
|
||||
|
||||
if (type.IsGenericType) {
|
||||
Type[] arguments = type.GetGenericArguments();
|
||||
for (int i = 0; i < arguments.Length; i++) {
|
||||
AddImport(arguments[i], types);
|
||||
}
|
||||
}
|
||||
|
||||
TempAssembly.FileIOPermission.Assert();
|
||||
Module module = type.Module;
|
||||
Assembly assembly = module.Assembly;
|
||||
if (DynamicAssemblies.IsTypeDynamic(type)) {
|
||||
DynamicAssemblies.Add(assembly);
|
||||
return;
|
||||
}
|
||||
|
||||
object[] typeForwardedFromAttribute = type.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false);
|
||||
if (typeForwardedFromAttribute.Length > 0)
|
||||
{
|
||||
TypeForwardedFromAttribute originalAssemblyInfo = typeForwardedFromAttribute[0] as TypeForwardedFromAttribute;
|
||||
Assembly originalAssembly = Assembly.Load(originalAssemblyInfo.AssemblyFullName);
|
||||
imports[originalAssembly] = originalAssembly.Location;
|
||||
}
|
||||
|
||||
imports[assembly] = assembly.Location;
|
||||
}
|
||||
|
||||
// SxS: This method does not take any resource name and does not expose any resources to the caller.
|
||||
// It's OK to suppress the SxS warning.
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
internal void AddImport(Assembly assembly) {
|
||||
TempAssembly.FileIOPermission.Assert();
|
||||
imports[assembly] = assembly.Location;
|
||||
}
|
||||
|
||||
internal TextWriter Source {
|
||||
get { return writer; }
|
||||
}
|
||||
|
||||
internal void Close() { }
|
||||
|
||||
[ResourceConsumption(ResourceScope.Machine)]
|
||||
[ResourceExposure(ResourceScope.Machine)]
|
||||
internal static string GetTempAssemblyPath(string baseDir, Assembly assembly, string defaultNamespace) {
|
||||
if (assembly.IsDynamic) {
|
||||
throw new InvalidOperationException(Res.GetString(Res.XmlPregenAssemblyDynamic));
|
||||
}
|
||||
|
||||
PermissionSet perms = new PermissionSet(PermissionState.None);
|
||||
perms.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
|
||||
perms.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted));
|
||||
perms.Assert();
|
||||
|
||||
try {
|
||||
if (baseDir != null && baseDir.Length > 0) {
|
||||
// check that the dirsctory exists
|
||||
if (!Directory.Exists(baseDir)) {
|
||||
throw new UnauthorizedAccessException(Res.GetString(Res.XmlPregenMissingDirectory, baseDir));
|
||||
}
|
||||
}
|
||||
else {
|
||||
baseDir = Path.GetTempPath();
|
||||
// check that the dirsctory exists
|
||||
if (!Directory.Exists(baseDir)) {
|
||||
throw new UnauthorizedAccessException(Res.GetString(Res.XmlPregenMissingTempDirectory));
|
||||
}
|
||||
}
|
||||
|
||||
#if MONO
|
||||
baseDir = Path.Combine (baseDir, GetTempAssemblyName(assembly.GetName(), defaultNamespace));
|
||||
#else
|
||||
if (baseDir.EndsWith("\\", StringComparison.Ordinal))
|
||||
baseDir += GetTempAssemblyName(assembly.GetName(), defaultNamespace);
|
||||
else
|
||||
baseDir += "\\" + GetTempAssemblyName(assembly.GetName(), defaultNamespace);
|
||||
#endif
|
||||
}
|
||||
finally {
|
||||
CodeAccessPermission.RevertAssert();
|
||||
}
|
||||
return baseDir + ".dll";
|
||||
}
|
||||
|
||||
internal static string GetTempAssemblyName(AssemblyName parent, string ns) {
|
||||
return parent.Name + ".XmlSerializers" + (ns == null || ns.Length == 0 ? "" : "." + ns.GetHashCode());
|
||||
}
|
||||
|
||||
// SxS: This method does not take any resource name and does not expose any resources to the caller.
|
||||
// It's OK to suppress the SxS warning.
|
||||
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
internal Assembly Compile(Assembly parent, string ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence) {
|
||||
CodeDomProvider codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
|
||||
CompilerParameters parameters = xmlParameters.CodeDomParameters;
|
||||
parameters.ReferencedAssemblies.AddRange(Imports);
|
||||
|
||||
if (debugEnabled) {
|
||||
parameters.GenerateInMemory = false;
|
||||
parameters.IncludeDebugInformation = true;
|
||||
parameters.TempFiles.KeepFiles = true;
|
||||
}
|
||||
PermissionSet perms = new PermissionSet(PermissionState.None);
|
||||
if (xmlParameters.IsNeedTempDirAccess) {
|
||||
perms.AddPermission(TempAssembly.FileIOPermission);
|
||||
}
|
||||
perms.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted));
|
||||
perms.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));
|
||||
perms.AddPermission(new SecurityPermission(SecurityPermissionFlag.ControlEvidence));
|
||||
perms.Assert();
|
||||
|
||||
if (parent != null && (parameters.OutputAssembly == null || parameters.OutputAssembly.Length ==0)) {
|
||||
string assemblyName = AssemblyNameFromOptions(parameters.CompilerOptions);
|
||||
if (assemblyName == null)
|
||||
assemblyName = GetTempAssemblyPath(parameters.TempFiles.TempDir, parent, ns);
|
||||
//
|
||||
parameters.OutputAssembly = assemblyName;
|
||||
}
|
||||
|
||||
if (parameters.CompilerOptions == null || parameters.CompilerOptions.Length == 0)
|
||||
parameters.CompilerOptions = "/nostdlib";
|
||||
else
|
||||
parameters.CompilerOptions += " /nostdlib";
|
||||
|
||||
parameters.CompilerOptions += " /D:_DYNAMIC_XMLSERIALIZER_COMPILATION";
|
||||
#pragma warning disable 618
|
||||
parameters.Evidence = evidence;
|
||||
#pragma warning restore 618
|
||||
CompilerResults results = null;
|
||||
Assembly assembly = null;
|
||||
try {
|
||||
results = codeProvider.CompileAssemblyFromSource(parameters, writer.ToString());
|
||||
// check the output for errors or a certain level-1 warning (1595)
|
||||
if (results.Errors.Count > 0) {
|
||||
StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
|
||||
stringWriter.WriteLine(Res.GetString(Res.XmlCompilerError, results.NativeCompilerReturnValue.ToString(CultureInfo.InvariantCulture)));
|
||||
bool foundOne = false;
|
||||
foreach (CompilerError e in results.Errors) {
|
||||
// clear filename. This makes ToString() print just error number and message.
|
||||
e.FileName = "";
|
||||
if (!e.IsWarning || e.ErrorNumber == "CS1595") {
|
||||
foundOne = true;
|
||||
stringWriter.WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
if (foundOne) {
|
||||
throw new InvalidOperationException(stringWriter.ToString());
|
||||
}
|
||||
}
|
||||
assembly = results.CompiledAssembly;
|
||||
}
|
||||
catch (UnauthorizedAccessException) {
|
||||
// try to get the user token
|
||||
string user = GetCurrentUser();
|
||||
if (user == null || user.Length == 0) {
|
||||
throw new UnauthorizedAccessException(Res.GetString(Res.XmlSerializerAccessDenied));
|
||||
}
|
||||
else {
|
||||
throw new UnauthorizedAccessException(Res.GetString(Res.XmlIdentityAccessDenied, user));
|
||||
}
|
||||
}
|
||||
catch (FileLoadException fle) {
|
||||
throw new InvalidOperationException(Res.GetString(Res.XmlSerializerCompileFailed), fle);
|
||||
}
|
||||
finally {
|
||||
CodeAccessPermission.RevertAssert();
|
||||
}
|
||||
// somehow we got here without generating an assembly
|
||||
if (assembly == null) throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
||||
static string AssemblyNameFromOptions(string options) {
|
||||
if (options == null || options.Length == 0)
|
||||
return null;
|
||||
|
||||
string outName = null;
|
||||
string[] flags = options.ToLower(CultureInfo.InvariantCulture).Split(null);
|
||||
for (int i = 0; i < flags.Length; i++) {
|
||||
string val = flags[i].Trim();
|
||||
if (val.StartsWith("/out:", StringComparison.Ordinal)) {
|
||||
outName = val.Substring(5);
|
||||
}
|
||||
}
|
||||
return outName;
|
||||
}
|
||||
|
||||
internal static string GetCurrentUser()
|
||||
{
|
||||
#if !FEATURE_PAL
|
||||
try {
|
||||
WindowsIdentity id = WindowsIdentity.GetCurrent();
|
||||
if (id != null && id.Name != null)
|
||||
return id.Name;
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif // !FEATURE_PAL
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user