chore: low-severity sweep — import session cap, full compile-error lists, leaf-name-fallback validation warning
#05-T24. Three low-severity cleanups, each TDD'd: - TransportOptions.MaxConcurrentImportSessions (8): BundleSessionStore.Open rejects a new session past the cap (evicting expired entries first), bounding the N×~200 MB decrypted-content footprint. Soft cap (count/add not atomic). - ScriptCompiler.TryCompile now joins ALL forbidden-API violations / compile errors (string.Join instead of [0]) so an operator sees every problem at once; the T15 verdict cache stores the joined string. - SemanticValidator emits an advisory warning when a CallScript target resolves ONLY via the composed leaf-name fallback (dynamic child path, not statically verified) instead of silently accepting it. Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
@@ -42,15 +42,17 @@ public class ScriptCompiler
|
||||
var (ok, error) = ScriptCompileVerdictCache.GetOrAdd(code, () =>
|
||||
{
|
||||
// Authoritative forbidden-API verdict first — a security violation must
|
||||
// gate the script regardless of whether it otherwise compiles.
|
||||
// gate the script regardless of whether it otherwise compiles. Report
|
||||
// ALL violations (#05-T24), not just the first, so an operator fixing
|
||||
// one forbidden API isn't surprised by a second on the next attempt.
|
||||
var violations = ScriptTrustValidator.FindViolations(code);
|
||||
if (violations.Count > 0)
|
||||
return (false, $"uses forbidden API: {violations[0]}");
|
||||
return (false, $"uses forbidden API: {string.Join("; ", violations)}");
|
||||
|
||||
// Real CSharpScript compile against the runtime-mirroring globals surface.
|
||||
var errors = RoslynScriptCompiler.Compile(code, typeof(ScriptCompileSurface));
|
||||
if (errors.Count > 0)
|
||||
return (false, $"failed to compile: {errors[0]}");
|
||||
return (false, $"failed to compile: {string.Join("; ", errors)}");
|
||||
|
||||
return (true, (string?)null);
|
||||
});
|
||||
|
||||
@@ -119,6 +119,18 @@ public class SemanticValidator
|
||||
}
|
||||
else
|
||||
{
|
||||
// #05-T24: if the target resolved ONLY via the composed
|
||||
// leaf-name fallback (not a same-scope sibling), the child
|
||||
// path is dynamic and cannot be statically verified — surface
|
||||
// an advisory warning instead of accepting it silently.
|
||||
if (!scriptNames.Contains(call.TargetName)
|
||||
&& composedLeafNames.Contains(call.TargetName))
|
||||
{
|
||||
warnings.Add(ValidationEntry.Warning(ValidationCategory.CallTargetNotFound,
|
||||
$"Script '{script.CanonicalName}' call target '{call.TargetName}' matched by composed leaf name only — child path not verified.",
|
||||
script.CanonicalName));
|
||||
}
|
||||
|
||||
ValidateCallParameters(script.CanonicalName, call, scriptParamMap, errors);
|
||||
ValidateCallReturnType(script.CanonicalName, call, scriptReturnMap, errors);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user