From 82dc14f8ef4929be09009637d2fb1764a506f52e Mon Sep 17 00:00:00 2001 From: Martin Najemi Date: Mon, 16 Feb 2026 14:52:26 +0100 Subject: [PATCH] fix: Fine-grained local CSS/SCSS taint detection Risk: low --- CHANGELOG.md | 6 +++++ VERSION | 2 +- internal/analyzer/analyzer.go | 46 +++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c86488f..d6a9053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.11.2] - 2026-02-14 + +### Fixed +- Fine-grained detection now seeds taint from changed CSS/SCSS files within the project (with CSS module granularity for `*.module.scss`/`*.module.css`) + ## [0.11.1] - 2026-02-14 ### Changed @@ -146,6 +151,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Multi-stage Docker build - Automated vendor upgrade workflow +[0.11.2]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.11.1...v0.11.2 [0.11.1]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.11.0...v0.11.1 [0.11.0]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.10.0...v0.11.0 [0.10.0]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.9.5...v0.10.0 diff --git a/VERSION b/VERSION index af88ba8..bc859cb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.11.1 +0.11.2 diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index b163a29..55feebc 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -1308,6 +1308,52 @@ func FindAffectedFiles(globPattern string, filterPattern string, upstreamTaint m } } + // Seed from changed CSS/SCSS files within the project. + // For CSS module imports (*.module.scss/css) with named bindings, only taint symbols + // that use the imported binding. For all other style imports, taint all symbols. + changedStyleFiles := make(map[string]bool) + for _, f := range changedFiles { + if !strings.HasPrefix(f, projectFolder+"/") { + continue + } + relToProject := strings.TrimPrefix(f, projectFolder+"/") + ext := strings.ToLower(filepath.Ext(relToProject)) + if ext == ".scss" || ext == ".css" { + changedStyleFiles[relToProject] = true + } + } + if len(changedStyleFiles) > 0 { + for stem, analysis := range fileAnalyses { + for _, imp := range analysis.Imports { + if !strings.HasPrefix(imp.Source, ".") { + continue + } + if !isStyleImport(imp.Source) { + continue + } + fileDir := filepath.Dir(stem + ".ts") + resolved := filepath.Join(fileDir, imp.Source) + resolved = filepath.Clean(resolved) + if !changedStyleFiles[resolved] { + continue + } + if tainted[stem] == nil { + tainted[stem] = make(map[string]bool) + } + if isCSSModule(imp.Source) && len(imp.Names) > 0 { + usageTainted := findTaintedSymbolsByUsage(analysis, imp.Names) + for _, s := range usageTainted { + tainted[stem][s] = true + } + } else { + for _, sym := range analysis.Symbols { + tainted[stem][sym.Name] = true + } + } + } + } + } + if len(tainted) == 0 { return nil }