Project consumed version evidence through sequence appends
This commit is contained in:
@@ -662,7 +662,7 @@ func projectAcquiredDestinations(composed *composedDocument, scope acquisitionSc
|
||||
}
|
||||
contributionPrefix = appendDestination(container, Path{}.Index(start))
|
||||
contributionInsideItem = true
|
||||
projectSourceVersionEvidence(contribution.processing, contributionPrefix)
|
||||
projectSourceVersionEvidence(contribution.processing, contributionPrefix, nil, sourceIndex)
|
||||
} else if contributionInsideItem {
|
||||
exactDestination := appendDestination(contributionPrefix, contribution.destination)
|
||||
contribution.source.Destination = exactDestination.clone()
|
||||
@@ -672,7 +672,9 @@ func projectAcquiredDestinations(composed *composedDocument, scope acquisitionSc
|
||||
sources[position].Destination = exactDestination
|
||||
sources[position].destinationUnresolved = false
|
||||
}
|
||||
projectSourceVersionEvidence(contribution.processing, exactDestination)
|
||||
projectSourceVersionEvidence(contribution.processing, exactDestination, nil, sourceIndex)
|
||||
} else {
|
||||
projectSourceVersionEvidence(contribution.processing, contribution.destination, currentComposition.sequenceRanges, sourceIndex)
|
||||
}
|
||||
if contribution.nested != nil && contribution.nested.acquisition != nil {
|
||||
for _, nestedScope := range contribution.nested.acquisition {
|
||||
@@ -684,9 +686,28 @@ func projectAcquiredDestinations(composed *composedDocument, scope acquisitionSc
|
||||
projectScope(composed, scope, Path{}, false, "")
|
||||
}
|
||||
|
||||
func projectSourceVersionEvidence(processing *sourceVersionProcessingResult, destination Path) {
|
||||
func projectSourceVersionEvidence(processing *sourceVersionProcessingResult, destination Path, ranges []sequenceRange, sourceIndex int) {
|
||||
if processing != nil && processing.evidence != nil {
|
||||
processing.evidence.destination = destination.clone()
|
||||
evidence := processing.evidence
|
||||
evidence.destination = destination.clone()
|
||||
// Rebuild from source-local paths on each handoff: an input can be
|
||||
// composed first on its own and then at a different offset in its tier.
|
||||
evidence.projectedPaths = nil
|
||||
paths := evidence.sensitivityPaths()
|
||||
for index, path := range paths {
|
||||
for _, assigned := range ranges {
|
||||
if assigned.sourceIndex != sourceIndex || !pathContains(assigned.path, path) || len(path.segments) <= len(assigned.path.segments) {
|
||||
continue
|
||||
}
|
||||
position := len(assigned.path.segments)
|
||||
item, ok := schemaIndex(path.segments[position])
|
||||
if ok && path.segments[position].kind != pathSegmentKey {
|
||||
path.segments[position] = pathSegment{kind: pathSegmentIndex, index: assigned.start + item}
|
||||
}
|
||||
}
|
||||
paths[index] = path
|
||||
}
|
||||
evidence.projectedPaths = paths
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,15 +125,8 @@ func classifySecretPathsWithEvidence(schema *schemaDescriptor, predicate func(Pa
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
candidate := item.resolvedPath
|
||||
if !candidate.valid() {
|
||||
candidate = item.path
|
||||
}
|
||||
resolved := addSecretEvidencePath(paths, item.destination, candidate)
|
||||
addCandidate(resolved)
|
||||
classifyPath(resolved)
|
||||
for _, ancestor := range item.ancestors {
|
||||
resolved := addSecretEvidencePath(paths, item.destination, ancestor.path)
|
||||
for _, resolved := range item.sensitivityPaths() {
|
||||
addSecretPath(paths, resolved.String())
|
||||
addCandidate(resolved)
|
||||
classifyPath(resolved)
|
||||
}
|
||||
|
||||
@@ -30,16 +30,17 @@ type sourceVersionAncestor struct {
|
||||
}
|
||||
|
||||
type sourceVersionEvidence struct {
|
||||
sourceID string
|
||||
path Path
|
||||
resolvedPath Path
|
||||
destination Path
|
||||
version Version
|
||||
location *Location
|
||||
ancestors []sourceVersionAncestor
|
||||
absence sourceVersionPathAbsence
|
||||
checked bool
|
||||
redacted bool
|
||||
sourceID string
|
||||
path Path
|
||||
resolvedPath Path
|
||||
destination Path
|
||||
projectedPaths []Path
|
||||
version Version
|
||||
location *Location
|
||||
ancestors []sourceVersionAncestor
|
||||
absence sourceVersionPathAbsence
|
||||
checked bool
|
||||
redacted bool
|
||||
}
|
||||
|
||||
type sourceVersionState struct {
|
||||
@@ -80,7 +81,7 @@ func sourceVersionCheckForEvidence(evidence *sourceVersionEvidence, sensitivity
|
||||
redacted := evidence.redacted
|
||||
if conservative {
|
||||
redacted = redacted || version.Text != ""
|
||||
} else if sensitivity.isSensitiveAtOrAbove(appendDestination(evidence.destination, path).String()) {
|
||||
} else if sensitivity.isSensitiveAtOrAbove(evidence.sensitivityPaths()[0].String()) {
|
||||
redacted = true
|
||||
}
|
||||
if redacted {
|
||||
@@ -91,6 +92,24 @@ func sourceVersionCheckForEvidence(evidence *sourceVersionEvidence, sensitivity
|
||||
}
|
||||
}
|
||||
|
||||
// sensitivityPaths preserves source-local evidence while describing its assigned
|
||||
// application coordinates. Before assembly, the original mount is the fallback.
|
||||
func (evidence *sourceVersionEvidence) sensitivityPaths() []Path {
|
||||
if evidence.projectedPaths != nil {
|
||||
return evidence.projectedPaths
|
||||
}
|
||||
local := evidence.resolvedPath
|
||||
if !local.valid() {
|
||||
local = evidence.path
|
||||
}
|
||||
paths := make([]Path, 0, len(evidence.ancestors)+1)
|
||||
paths = append(paths, appendDestination(evidence.destination, local))
|
||||
for _, ancestor := range evidence.ancestors {
|
||||
paths = append(paths, appendDestination(evidence.destination, ancestor.path))
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
func (state *sourceVersionState) process(root *document.Node, role sourceVersionRole, destination Path, sourceID string, placement placementMode) (sourceVersionProcessingResult, []Diagnostic) {
|
||||
if state == nil || state.mode == sourceVersionModeDefault {
|
||||
return sourceVersionProcessingResult{}, nil
|
||||
|
||||
Reference in New Issue
Block a user