Пример #1
0
        // ------------- 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);
                }
            }
        }
Пример #2
0
        // 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;
        }
Пример #3
0
        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
        }
Пример #4
0
        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);
        }
Пример #5
0
        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;
        }
Пример #6
0
        private void LoadMsUsing(ScriptClass scriptClass)
        {
            _input.GetAttributes(_usingAttributes);

            if (_input.MoveToXsltAttribute(0, "namespace"))
            {
                scriptClass.nsImports.Add(_input.Value);
            }
            CheckNoContent();
        }
Пример #7
0
        // 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();
        }
Пример #8
0
        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();
        }
Пример #9
0
        private void LoadMsUsing(ScriptClass scriptClass) {
            string attNamespace;
            input.GetAttributes(/*required:*/1, input.Atoms.Namespace, out attNamespace);

            if (attNamespace != null) {
                scriptClass.nsImports.Add(attNamespace);
            }
            CheckNoContent();
        }
Пример #10
0
        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);
        }
Пример #11
0
        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));
        }