Beispiel #1
0
        protected virtual CompilerResults FromSourceBatch(CompilerParameters options, string[] sources)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }
            if (sources == null)
            {
                throw new ArgumentNullException("sources");
            }

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

            string[]     filenames   = new string[sources.Length];
            FileStream[] fileStreams = new FileStream[sources.Length];

            CompilerResults results = null;

#if !FEATURE_PAL
            // the extra try-catch is here to mitigate exception filter injection attacks.
            try {
                WindowsImpersonationContext impersonation = Executor.RevertImpersonation();
                try {
#endif // !FEATURE_PAL
            try {
                bool isFileIntegrityEnabled = FileIntegrity.IsEnabled;
                for (int i = 0; i < sources.Length; i++)
                {
                    string     name       = options.TempFiles.AddExtension(i + FileExtension);
                    FileStream fileStream = new FileStream(name, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
                    fileStreams[i] = fileStream;
                    using (StreamWriter sw = new StreamWriter(fileStream, Encoding.UTF8)) {
                        sw.Write(sources[i]);
                        sw.Flush();
                        if (isFileIntegrityEnabled)
                        {
                            FileIntegrity.MarkAsTrusted(fileStream.SafeFileHandle);
                        }
                    }
                    filenames[i] = name;
                }

                results = FromFileBatch(options, filenames);
            }
            finally {
                for (int i = 0; i < fileStreams.Length && fileStreams[i] != null; i++)
                {
                    fileStreams[i].Close();
                }
            }
#if !FEATURE_PAL
        }

        finally {
            Executor.ReImpersonate(impersonation);
        }
    }
    catch {
        throw;
    }
#endif // !FEATURE_PAL

            return(results);
        }
Beispiel #2
0
        protected virtual CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }
            if (fileNames == null)
            {
                throw new ArgumentNullException("fileNames");
            }

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

            string outputFile = null;
            int    retValue   = 0;

            CompilerResults    results = new CompilerResults(options.TempFiles);
            SecurityPermission perm1   = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);

            perm1.Assert();
            try {
#pragma warning disable 618
                results.Evidence = options.Evidence;
#pragma warning restore 618
            }
            finally {
                SecurityPermission.RevertAssert();
            }
            bool createdEmptyAssembly = false;

            if (options.OutputAssembly == null || options.OutputAssembly.Length == 0)
            {
                string extension = (options.GenerateExecutable) ? "exe" : "dll";
                options.OutputAssembly = results.TempFiles.AddExtension(extension, !options.GenerateInMemory);

                // Create an empty assembly.  This is so that the file will have permissions that
                // we can later access with our current credential.  If we don't do this, the compiler
                // could end up creating an assembly that we cannot open
                new FileStream(options.OutputAssembly, FileMode.Create, FileAccess.ReadWrite).Close();
                createdEmptyAssembly = true;
            }

#if FEATURE_PAL
            results.TempFiles.AddExtension("ildb");
#else
            results.TempFiles.AddExtension("pdb");
#endif

            string args = CmdArgsFromParameters(options) + " " + JoinStringArray(fileNames, " ");

            // Use a response file if the compiler supports it
            string responseFileArgs = GetResponseFileCmdArgs(options, args);
            string trueArgs         = null;
            if (responseFileArgs != null)
            {
                trueArgs = args;
                args     = responseFileArgs;
            }

            Compile(options, Executor.GetRuntimeInstallDirectory(), CompilerName, args, ref outputFile, ref retValue, trueArgs);

            results.NativeCompilerReturnValue = retValue;

            // only look for errors/warnings if the compile failed or the caller set the warning level
            if (retValue != 0 || options.WarningLevel > 0)
            {
                FileStream outputStream = new FileStream(outputFile, FileMode.Open,
                                                         FileAccess.Read, FileShare.ReadWrite);
                try {
                    if (outputStream.Length > 0)
                    {
                        // The output of the compiler is in UTF8
                        StreamReader sr = new StreamReader(outputStream, Encoding.UTF8);
                        string       line;
                        do
                        {
                            line = sr.ReadLine();
                            if (line != null)
                            {
                                results.Output.Add(line);

                                ProcessCompilerOutputLine(results, line);
                            }
                        } while (line != null);
                    }
                }
                finally {
                    outputStream.Close();
                }

                // Delete the empty assembly if we created one
                if (retValue != 0 && createdEmptyAssembly)
                {
                    File.Delete(options.OutputAssembly);
                }
            }

            if (!results.Errors.HasErrors && options.GenerateInMemory)
            {
                FileStream fs = new FileStream(options.OutputAssembly, FileMode.Open, FileAccess.Read, FileShare.Read);
                try {
                    int    fileLen = (int)fs.Length;
                    byte[] b       = new byte[fileLen];
                    fs.Read(b, 0, fileLen);
                    SecurityPermission perm = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
                    perm.Assert();
                    try {
                        if (!FileIntegrity.IsEnabled)
                        {
#pragma warning disable 618 // Load with evidence is obsolete - this warning is passed on via the options parameter
                            results.CompiledAssembly = Assembly.Load(b, null, options.Evidence);
#pragma warning restore 618
                        }
                        else
                        {
                            if (!FileIntegrity.IsTrusted(fs.SafeFileHandle))
                            {
                                throw new IOException(SR.GetString(SR.FileIntegrityCheckFailed, options.OutputAssembly));
                            }

                            results.CompiledAssembly = LoadImageSkipIntegrityCheck(b, null, options.Evidence);
                        }
                    }
                    finally {
                        SecurityPermission.RevertAssert();
                    }
                }
                finally {
                    fs.Close();
                }
            }
            else
            {
                results.PathToAssembly = options.OutputAssembly;
            }

            return(results);
        }