Skip to content

Commit d862b4d

Browse files
authored
fix: Add intra-file taint propagation after seeding phase
2 parents cf3e363 + 4763eeb commit d862b4d

4 files changed

Lines changed: 70 additions & 4 deletions

File tree

.github/workflows/pull-request-status-check-changelog.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ jobs:
2727
- name: Install changelog validator
2828
run: |
2929
# Install Node.js tool for Keep a Changelog validation
30-
npm install -g keep-a-changelog
30+
npm install -g keep-a-changelog@2.8.0
3131
3232
- name: Validate changelog format
3333
run: |
3434
echo "Validating CHANGELOG.md format according to Keep a Changelog..."
3535
3636
# Use keep-a-changelog to validate the changelog format
37-
if ! npx keep-a-changelog CHANGELOG.md > /dev/null 2>&1; then
37+
if ! npx keep-a-changelog@2.8.0 CHANGELOG.md > /dev/null 2>&1; then
3838
echo "❌ CHANGELOG.md is not valid according to Keep a Changelog format"
3939
echo "Please ensure your changelog follows the format at https://keepachangelog.com"
4040
echo "Validation output:"
41-
npx keep-a-changelog CHANGELOG.md
41+
npx keep-a-changelog@2.8.0 CHANGELOG.md
4242
exit 1
4343
fi
4444

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.15.3] - 2026-02-23
9+
10+
### Fixed
11+
- Add intra-file taint propagation after seeding phase in both `AnalyzeLibraryPackage` and `FindAffectedFiles`, so that symbols referencing other tainted symbols in the same file are also marked as tainted before BFS starts
12+
813
## [0.15.2] - 2026-02-20
914

1015
### Fixed
@@ -192,6 +197,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
192197
- Multi-stage Docker build
193198
- Automated vendor upgrade workflow
194199

200+
[0.15.3]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.15.2...v0.15.3
195201
[0.15.2]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.15.1...v0.15.2
196202
[0.15.1]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.15.0...v0.15.1
197203
[0.15.0]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.14.2...v0.15.0

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.15.2
1+
0.15.3

internal/analyzer/analyzer.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,38 @@ func AnalyzeLibraryPackage(projectFolder string, entrypoints []Entrypoint, merge
714714
return nil, nil
715715
}
716716

717+
// Intra-file propagation for seeded taint.
718+
// When upstream taint or AST diff marks symbol A as tainted, other symbols
719+
// in the same file that reference A should also be tainted.
720+
// Example: if KdaDialogController taints KeyDriverAnalysisComponent, then
721+
// KeyDriverAnalysis = connect(...)(KeyDriverAnalysisComponent) should also be tainted.
722+
for stem, names := range tainted {
723+
analysis := fileAnalyses[stem]
724+
if analysis == nil || analysis.SourceFile == nil {
725+
continue
726+
}
727+
sourceText := analysis.SourceFile.Text()
728+
lineMap := analysis.SourceFile.ECMALineMap()
729+
changed := true
730+
for changed {
731+
changed = false
732+
for _, sym := range analysis.Symbols {
733+
if names[sym.Name] {
734+
continue
735+
}
736+
bodyText := tsparse.ExtractTextForLines(sourceText, lineMap, sym.StartLine, sym.EndLine)
737+
for tName := range names {
738+
if strings.Contains(bodyText, tName) {
739+
names[sym.Name] = true
740+
changed = true
741+
debugf(" %s: %s tainted via intra-file dep on %s (seed propagation)", stem, sym.Name, tName)
742+
break
743+
}
744+
}
745+
}
746+
}
747+
}
748+
717749
// Build reverse import graph
718750
reverseImports := make(map[string][]string)
719751
for stem, edges := range importGraph {
@@ -1500,6 +1532,34 @@ func FindAffectedFiles(globPattern string, filterPattern string, upstreamTaint m
15001532
return nil
15011533
}
15021534

1535+
// Intra-file propagation for seeded taint (same as in AnalyzeLibraryPackage).
1536+
for stem, names := range tainted {
1537+
analysis := fileAnalyses[stem]
1538+
if analysis == nil || analysis.SourceFile == nil {
1539+
continue
1540+
}
1541+
sourceText := analysis.SourceFile.Text()
1542+
lineMap := analysis.SourceFile.ECMALineMap()
1543+
changed := true
1544+
for changed {
1545+
changed = false
1546+
for _, sym := range analysis.Symbols {
1547+
if names[sym.Name] {
1548+
continue
1549+
}
1550+
bodyText := tsparse.ExtractTextForLines(sourceText, lineMap, sym.StartLine, sym.EndLine)
1551+
for tName := range names {
1552+
if strings.Contains(bodyText, tName) {
1553+
names[sym.Name] = true
1554+
changed = true
1555+
debugf(" %s: %s tainted via intra-file dep on %s (seed propagation)", stem, sym.Name, tName)
1556+
break
1557+
}
1558+
}
1559+
}
1560+
}
1561+
}
1562+
15031563
// Symbol-level BFS propagation (same engine as AnalyzeLibraryPackage)
15041564
debugf("=== Starting BFS taint propagation (FindAffectedFiles) ===")
15051565
queue := make([]string, 0, len(tainted))

0 commit comments

Comments
 (0)