chore(unity): 固定Unity CLI Loop本地包并移除UnitySkills依赖
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Assembly = System.Reflection.Assembly;
|
||||
using Debug = UnityEngine.Debug;
|
||||
|
||||
namespace io.github.hatayama.uLoopMCP
|
||||
{
|
||||
internal static class CompiledAssemblyLoader
|
||||
{
|
||||
public static CompiledAssemblyLoadResult Load(
|
||||
DynamicCodeSecurityLevel securityLevel,
|
||||
byte[] assemblyBytes)
|
||||
{
|
||||
Debug.Assert(assemblyBytes != null, "assemblyBytes must not be null");
|
||||
|
||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||
|
||||
if (securityLevel == DynamicCodeSecurityLevel.Restricted)
|
||||
{
|
||||
SecurityValidationResult preloadValidationResult = ValidateBeforeAssemblyLoad(assemblyBytes);
|
||||
if (!preloadValidationResult.IsValid)
|
||||
{
|
||||
stopwatch.Stop();
|
||||
return new CompiledAssemblyLoadResult(
|
||||
false,
|
||||
null,
|
||||
preloadValidationResult.Violations,
|
||||
stopwatch.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
Assembly compiledAssembly = Assembly.Load(assemblyBytes);
|
||||
if (securityLevel == DynamicCodeSecurityLevel.Restricted)
|
||||
{
|
||||
IlSecurityValidator postLoadValidator = new IlSecurityValidator();
|
||||
SecurityValidationResult postLoadValidationResult = postLoadValidator.Validate(compiledAssembly);
|
||||
if (!postLoadValidationResult.IsValid)
|
||||
{
|
||||
stopwatch.Stop();
|
||||
return new CompiledAssemblyLoadResult(
|
||||
false,
|
||||
null,
|
||||
postLoadValidationResult.Violations,
|
||||
stopwatch.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
return new CompiledAssemblyLoadResult(
|
||||
true,
|
||||
compiledAssembly,
|
||||
new List<SecurityViolation>(),
|
||||
stopwatch.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
|
||||
private static SecurityValidationResult ValidateBeforeAssemblyLoad(byte[] assemblyBytes)
|
||||
{
|
||||
SecurityValidationResult aggregatedResult = new SecurityValidationResult
|
||||
{
|
||||
IsValid = true,
|
||||
Violations = new List<SecurityViolation>(),
|
||||
CompilationErrors = new List<string>()
|
||||
};
|
||||
bool shouldRunMetadataFallback = true;
|
||||
|
||||
IPreloadAssemblySecurityValidator registeredValidator;
|
||||
if (PreloadAssemblySecurityValidatorRegistry.TryGetValidator(out registeredValidator))
|
||||
{
|
||||
MergeValidationResult(aggregatedResult, registeredValidator.Validate(assemblyBytes));
|
||||
shouldRunMetadataFallback = registeredValidator is not IOverrideDefaultPreloadAssemblySecurityValidation;
|
||||
}
|
||||
|
||||
if (shouldRunMetadataFallback)
|
||||
{
|
||||
SystemReflectionMetadataPreloadValidator fallbackValidator = new SystemReflectionMetadataPreloadValidator();
|
||||
MergeValidationResult(aggregatedResult, fallbackValidator.Validate(assemblyBytes));
|
||||
}
|
||||
|
||||
PreloadIlSecurityValidator ilValidator = new PreloadIlSecurityValidator();
|
||||
MergeValidationResult(aggregatedResult, ilValidator.Validate(assemblyBytes));
|
||||
|
||||
aggregatedResult.IsValid = aggregatedResult.Violations.Count == 0 &&
|
||||
aggregatedResult.CompilationErrors.Count == 0;
|
||||
return aggregatedResult;
|
||||
}
|
||||
|
||||
private static void MergeValidationResult(
|
||||
SecurityValidationResult target,
|
||||
SecurityValidationResult source)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HashSet<string> seenViolations = new HashSet<string>(System.StringComparer.Ordinal);
|
||||
foreach (SecurityViolation violation in target.Violations)
|
||||
{
|
||||
seenViolations.Add(CreateViolationKey(violation));
|
||||
}
|
||||
|
||||
if (source.Violations != null)
|
||||
{
|
||||
foreach (SecurityViolation violation in source.Violations)
|
||||
{
|
||||
if (seenViolations.Add(CreateViolationKey(violation)))
|
||||
{
|
||||
target.Violations.Add(violation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (source.CompilationErrors == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string error in source.CompilationErrors)
|
||||
{
|
||||
if (!target.CompilationErrors.Contains(error))
|
||||
{
|
||||
target.CompilationErrors.Add(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string CreateViolationKey(SecurityViolation violation)
|
||||
{
|
||||
return $"{violation.Location}|{violation.ApiName}|{violation.Message}";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user