// ------------- CompileScripts() ----------- public void CompileScripts() { for (int i = 0; i < scriptClasses.Count; i++) { ScriptClass script = scriptClasses[i]; Type clrType = CompileClass(script); if (clrType != null) { nsToType.Add(script.ns, clrType); } } }
// The position of a compile error may be outside of all user code snippets (for example, in case of // unclosed '{'). In that case filename would be the name of the temporary file, and not the name // of the stylesheet file. Exposing the path of the temporary file is considered to be a security issue, // so here we check that filename is amongst user files. private static void FixErrorPosition(CompilerError error, List <ScriptClass> scriptsForLang) { string fileName = error.FileName; string uri; foreach (ScriptClass script in scriptsForLang) { // We assume that CodeDom provider returns absolute paths (VSWhidbey 289665). // Note that casing may be different. if (script.scriptUris.TryGetValue(fileName, out uri)) { // The error position is within one of user stylesheets, its URI may be reported error.FileName = uri; return; } } // Error is outside user code snippeets, we should hide filename for security reasons. // Return filename and position of the end of the last script block for the given class. int idx, scriptNumber; ScriptClass errScript = scriptsForLang[scriptsForLang.Count - 1]; // Normally temporary source files are named according to the scheme "<random name>.<script number>. // <language extension>". Try to extract the middle part to find the relevant script class. In case // of a non-standard CodeDomProvider, use the last script class. fileName = Path.GetFileNameWithoutExtension(fileName); if ((idx = fileName.LastIndexOf('.')) >= 0) { if (int.TryParse(fileName.Substring(idx + 1), NumberStyles.None, NumberFormatInfo.InvariantInfo, out scriptNumber)) { if ((uint)scriptNumber < scriptsForLang.Count) { errScript = scriptsForLang[scriptNumber]; } } } error.FileName = errScript.endUri; error.Line = errScript.endLoc.Line; error.Column = errScript.endLoc.Pos; }
public ScriptClass GetScriptClass(string ns, string language, IErrorHelper errorHelper) { #if CONFIGURATION_DEP CompilerInfo compilerInfo; try { compilerInfo = CodeDomProvider.GetCompilerInfo(language); Debug.Assert(compilerInfo != null); } catch (ConfigurationException) { // There is no CodeDom provider defined for this language errorHelper.ReportError(/*[XT_010]*/ Res.Xslt_ScriptInvalidLanguage, language); return(null); } foreach (ScriptClass scriptClass in scriptClasses) { if (ns == scriptClass.ns) { // Use object comparison because CompilerInfo.Equals may throw if (compilerInfo != scriptClass.compilerInfo) { errorHelper.ReportError(/*[XT_011]*/ Res.Xslt_ScriptMixedLanguages, ns); return(null); } return(scriptClass); } } ScriptClass newScriptClass = new ScriptClass(ns, compilerInfo); newScriptClass.typeDecl.TypeAttributes = TypeAttributes.Public; scriptClasses.Add(newScriptClass); return(newScriptClass); #else return(null); #endif }
private Assembly CompileAssembly(List <ScriptClass> scriptsForLang) { TempFileCollection allTempFiles = compiler.CompilerResults.TempFiles; CompilerErrorCollection allErrors = compiler.CompilerResults.Errors; ScriptClass lastScript = scriptsForLang[scriptsForLang.Count - 1]; CodeDomProvider provider; bool isVB = false; try { provider = lastScript.compilerInfo.CreateProvider(); } catch (ConfigurationException e) { // The CodeDom provider type could not be located, or some error in machine.config allErrors.Add(compiler.CreateError(lastScript.EndLineInfo, /*[XT_041]*/ Res.Xslt_ScriptCompileException, e.Message)); return(null); } #if !FEATURE_PAL // visualbasic isVB = provider is Microsoft.VisualBasic.VBCodeProvider; #endif // !FEATURE_PAL CodeCompileUnit[] codeUnits = new CodeCompileUnit[scriptsForLang.Count]; CompilerParameters compilParams = lastScript.compilerInfo.CreateDefaultCompilerParameters(); // compilParams.ReferencedAssemblies.Add(typeof(System.Xml.Res).Assembly.Location); compilParams.ReferencedAssemblies.Add("System.dll"); if (isVB) { compilParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll"); } bool refAssembliesByHref = false; for (int idx = 0; idx < scriptsForLang.Count; idx++) { ScriptClass script = scriptsForLang[idx]; CodeNamespace scriptNs = new CodeNamespace(ScriptClassesNamespace); // Add imported namespaces foreach (string ns in defaultNamespaces) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } if (isVB) { scriptNs.Imports.Add(new CodeNamespaceImport("Microsoft.VisualBasic")); } foreach (string ns in script.nsImports) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } scriptNs.Types.Add(script.typeDecl); CodeCompileUnit unit = new CodeCompileUnit(); { unit.Namespaces.Add(scriptNs); if (isVB) { // This settings have sense for Visual Basic only. In future releases we may allow to specify // them explicitly in the msxsl:script element. unit.UserData["AllowLateBound"] = true; // Allow variables to be declared untyped unit.UserData["RequireVariableDeclaration"] = false; // Allow variables to be undeclared } // Put SecurityTransparentAttribute and SecurityRulesAttribute on the first CodeCompileUnit only if (idx == 0) { unit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration("System.Security.SecurityTransparentAttribute")); // We want the assemblies generated for scripts to stick to the old security model unit.AssemblyCustomAttributes.Add( new CodeAttributeDeclaration( new CodeTypeReference(typeof(System.Security.SecurityRulesAttribute)), new CodeAttributeArgument( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(System.Security.SecurityRuleSet)), "Level1")))); } } codeUnits[idx] = unit; foreach (string name in script.refAssemblies) { compilParams.ReferencedAssemblies.Add(name); } refAssembliesByHref |= script.refAssembliesByHref; } XsltSettings settings = compiler.Settings; compilParams.WarningLevel = settings.WarningLevel >= 0 ? settings.WarningLevel : compilParams.WarningLevel; compilParams.TreatWarningsAsErrors = settings.TreatWarningsAsErrors; compilParams.IncludeDebugInformation = compiler.IsDebug; string asmPath = compiler.ScriptAssemblyPath; if (asmPath != null && scriptsForLang.Count < scriptClasses.Count) { asmPath = Path.ChangeExtension(asmPath, "." + GetLanguageName(lastScript.compilerInfo) + Path.GetExtension(asmPath)); } compilParams.OutputAssembly = asmPath; string tempDir = (settings.TempFiles != null) ? settings.TempFiles.TempDir : null; compilParams.TempFiles = new TempFileCollection(tempDir); // We need only .dll and .pdb, but there is no way to specify that bool keepFiles = (compiler.IsDebug && asmPath == null); #if DEBUG keepFiles = keepFiles || XmlILTrace.IsEnabled; #endif keepFiles = keepFiles && !settings.CheckOnly; compilParams.TempFiles.KeepFiles = keepFiles; // If GenerateInMemory == true, then CodeDom loads the compiled assembly using Assembly.Load(byte[]) // instead of Assembly.Load(AssemblyName). That means the assembly will be loaded in the anonymous // context (http://blogs.msdn.com/Microsoft/archive/2003/05/29/57143.aspx), and its dependencies can only // be loaded from the Load context or using AssemblyResolve event. However we want to use the LoadFrom // context to preload all dependencies specified by <ms:assembly href="uri-reference"/>, so we turn off // GenerateInMemory here. compilParams.GenerateInMemory = (asmPath == null && !compiler.IsDebug && !refAssembliesByHref) || settings.CheckOnly; CompilerResults results; try { results = provider.CompileAssemblyFromDom(compilParams, codeUnits); } catch (ExternalException e) { // Compiler might have created temporary files results = new CompilerResults(compilParams.TempFiles); results.Errors.Add(compiler.CreateError(lastScript.EndLineInfo, /*[XT_041]*/ Res.Xslt_ScriptCompileException, e.Message)); } if (!settings.CheckOnly) { foreach (string fileName in results.TempFiles) { allTempFiles.AddFile(fileName, allTempFiles.KeepFiles); } } foreach (CompilerError error in results.Errors) { FixErrorPosition(error, scriptsForLang); compiler.AddModule(error.FileName); } allErrors.AddRange(results.Errors); return(results.Errors.HasErrors ? null : results.CompiledAssembly); }
public ScriptClass GetScriptClass(string ns, string language, IErrorHelper errorHelper) { CompilerInfo compilerInfo; try { compilerInfo = CodeDomProvider.GetCompilerInfo(language); Debug.Assert(compilerInfo != null); } catch (ConfigurationException) { // There is no CodeDom provider defined for this language errorHelper.ReportError(/*[XT_010]*/SR.Xslt_ScriptInvalidLanguage, language); return null; } foreach (ScriptClass scriptClass in _scriptClasses) { if (ns == scriptClass.ns) { // Use object comparison because CompilerInfo.Equals may throw if (compilerInfo != scriptClass.compilerInfo) { errorHelper.ReportError(/*[XT_011]*/SR.Xslt_ScriptMixedLanguages, ns); return null; } return scriptClass; } } ScriptClass newScriptClass = new ScriptClass(ns, compilerInfo); newScriptClass.typeDecl.TypeAttributes = TypeAttributes.Public; _scriptClasses.Add(newScriptClass); return newScriptClass; }
private void LoadMsUsing(ScriptClass scriptClass) { _input.GetAttributes(_usingAttributes); if (_input.MoveToXsltAttribute(0, "namespace")) { scriptClass.nsImports.Add(_input.Value); } CheckNoContent(); }
// SxS: This method reads resource names from source document and does not expose any resources to the caller. // It's OK to suppress the SxS warning. private void LoadMsAssembly(ScriptClass scriptClass) { _input.GetAttributes(_assemblyAttributes); string name = ParseStringAttribute(0, "name"); string href = ParseStringAttribute(1, "href"); if ((name != null) == (href != null)) { ReportError(/*[XT_046]*/SR.Xslt_AssemblyNameHref); } else { string asmLocation = null; if (name != null) { try { AssemblyName asmName = new AssemblyName(name); Assembly.Load(asmName); asmLocation = asmName.Name + ".dll"; } catch { AssemblyName asmName = new AssemblyName(name); // If the assembly is simply named, let CodeDomProvider and Fusion resolve it byte[] publicKeyToken = asmName.GetPublicKeyToken(); if ((publicKeyToken == null || publicKeyToken.Length == 0) && asmName.Version == null) { asmLocation = asmName.Name + ".dll"; } else { throw; } } } else { Debug.Assert(href != null); asmLocation = Assembly.LoadFrom(ResolveUri(href, _input.BaseUri).ToString()).Location; scriptClass.refAssembliesByHref = true; } if (asmLocation != null) { scriptClass.refAssemblies.Add(asmLocation); } } CheckNoContent(); }
private void LoadMsAssembly(ScriptClass scriptClass) { string attName, attHref; input.GetAttributes(/*required:*/0, input.Atoms.Name, out attName, input.Atoms.Href, out attHref ); string asmLocation = null; if (attName != null) { if (attHref != null) { ReportError(/*[XT_046]*/Res.Xslt_AssemblyBothNameHrefPresent); } else { try { asmLocation = Assembly.Load(attName).Location; } catch { AssemblyName asmName = new AssemblyName(attName); // If the assembly is simply named, let CodeDomProvider and Fusion resolve it byte[] publicKeyToken = asmName.GetPublicKeyToken(); if ((publicKeyToken == null || publicKeyToken.Length == 0) && asmName.Version == null) { asmLocation = asmName.Name + ".dll"; } else { throw; } } } } else if (attHref != null) { asmLocation = Assembly.LoadFrom(ResolveUri(attHref, input.BaseUri).ToString()).Location; } else { ReportError(/*[XT_045]*/Res.Xslt_AssemblyBothNameHrefAbsent); } if (asmLocation != null) { scriptClass.refAssemblies.Add(asmLocation); } CheckNoContent(); }
private void LoadMsUsing(ScriptClass scriptClass) { string attNamespace; input.GetAttributes(/*required:*/1, input.Atoms.Namespace, out attNamespace); if (attNamespace != null) { scriptClass.nsImports.Add(attNamespace); } CheckNoContent(); }
private Type CompileClass(ScriptClass script) { TempFileCollection allTempFiles = compiler.CompilerResults.TempFiles; CompilerErrorCollection allErrors = compiler.CompilerResults.Errors; CodeDomProvider provider; bool isVB = false; try { provider = script.compilerInfo.CreateProvider(); } catch (ConfigurationException e) { // The CodeDom provider type could not be located, or some error in machine.config allErrors.Add(script.CreateCompileExceptionError(e)); return null; } CodeNamespace scriptNs = new CodeNamespace("System.Xml.Xsl.CompiledQuery"); // Add #using directives foreach (string ns in defaultNamespaces) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } if (isVB) { scriptNs.Imports.Add(new CodeNamespaceImport("Microsoft.VisualBasic")); } foreach (string ns in script.nsImports) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } scriptNs.Types.Add(script.typeDecl); CodeCompileUnit unit = new CodeCompileUnit(); { unit.Namespaces.Add(scriptNs); unit.UserData["AllowLateBound"] = true; // Allow variables to be undeclared unit.UserData["RequireVariableDeclaration"] = false; // Allow variables to be declared untyped unit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration("System.Security.SecurityTransparentAttribute")); } CompilerParameters compilParams = new CompilerParameters(); compilParams.ReferencedAssemblies.Add(typeof(System.Xml.Res).Assembly.Location); compilParams.ReferencedAssemblies.Add("System.dll"); if (isVB) { compilParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll"); } foreach(string name in script.refAssemblies) { compilParams.ReferencedAssemblies.Add(name); } XsltSettings settings = compiler.Settings; compilParams.WarningLevel = settings.WarningLevel >= 0 ? settings.WarningLevel : 4; compilParams.TreatWarningsAsErrors = settings.TreatWarningsAsErrors; compilParams.IncludeDebugInformation = settings.IncludeDebugInformation; compilParams.CompilerOptions = script.compilerInfo.CreateDefaultCompilerParameters().CompilerOptions; bool keepFiles = (settings.IncludeDebugInformation || XmlILTrace.IsEnabled) && !settings.CheckOnly; compilParams.GenerateInMemory = settings.CheckOnly; // We need only .dll and .pdb, but there is no way to specify that compilParams.TempFiles.KeepFiles = keepFiles; CompilerResults results; try { results = provider.CompileAssemblyFromDom(compilParams, unit); } catch (ExternalException e) { // Compiler might have created temporary files results = new CompilerResults(compilParams.TempFiles); results.Errors.Add(script.CreateCompileExceptionError(e)); } if (!settings.CheckOnly) { foreach (string fileName in results.TempFiles) { allTempFiles.AddFile(fileName, allTempFiles.KeepFiles); } } foreach (CompilerError e in results.Errors) { script.FixFileName(e); } allErrors.AddRange(results.Errors); if (results.Errors.HasErrors) { return null; } return results.CompiledAssembly.GetType("System.Xml.Xsl.CompiledQuery." + script.typeDecl.Name); }
private Type CompileClass(ScriptClass script) { TempFileCollection allTempFiles = compiler.CompilerResults.TempFiles; CompilerErrorCollection allErrors = compiler.CompilerResults.Errors; CodeDomProvider provider; bool isVB = false; try { provider = script.compilerInfo.CreateProvider(); } catch (ConfigurationException e) { // The CodeDom provider type could not be located, or some error in machine.config allErrors.Add(script.CreateCompileExceptionError(e)); return(null); } CodeNamespace scriptNs = new CodeNamespace("System.Xml.Xsl.CompiledQuery"); // Add #using directives foreach (string ns in defaultNamespaces) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } if (isVB) { scriptNs.Imports.Add(new CodeNamespaceImport("Microsoft.VisualBasic")); } foreach (string ns in script.nsImports) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } scriptNs.Types.Add(script.typeDecl); CodeCompileUnit unit = new CodeCompileUnit(); { unit.Namespaces.Add(scriptNs); unit.UserData["AllowLateBound"] = true; // Allow variables to be undeclared unit.UserData["RequireVariableDeclaration"] = false; // Allow variables to be declared untyped unit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration("System.Security.SecurityTransparentAttribute")); } CompilerParameters compilParams = new CompilerParameters(); compilParams.ReferencedAssemblies.Add(typeof(System.Xml.Res).Assembly.Location); compilParams.ReferencedAssemblies.Add("System.dll"); if (isVB) { compilParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll"); } foreach (string name in script.refAssemblies) { compilParams.ReferencedAssemblies.Add(name); } XsltSettings settings = compiler.Settings; compilParams.WarningLevel = settings.WarningLevel >= 0 ? settings.WarningLevel : 4; compilParams.TreatWarningsAsErrors = settings.TreatWarningsAsErrors; compilParams.IncludeDebugInformation = settings.IncludeDebugInformation; compilParams.CompilerOptions = script.compilerInfo.CreateDefaultCompilerParameters().CompilerOptions; bool keepFiles = (settings.IncludeDebugInformation || XmlILTrace.IsEnabled) && !settings.CheckOnly; compilParams.GenerateInMemory = settings.CheckOnly; // We need only .dll and .pdb, but there is no way to specify that compilParams.TempFiles.KeepFiles = keepFiles; CompilerResults results; try { results = provider.CompileAssemblyFromDom(compilParams, unit); } catch (ExternalException e) { // Compiler might have created temporary files results = new CompilerResults(compilParams.TempFiles); results.Errors.Add(script.CreateCompileExceptionError(e)); } if (!settings.CheckOnly) { foreach (string fileName in results.TempFiles) { allTempFiles.AddFile(fileName, allTempFiles.KeepFiles); } } foreach (CompilerError e in results.Errors) { script.FixFileName(e); } allErrors.AddRange(results.Errors); if (results.Errors.HasErrors) { return(null); } return(results.CompiledAssembly.GetType("System.Xml.Xsl.CompiledQuery." + script.typeDecl.Name)); }