@@ -51,9 +51,13 @@ type IEngine interface {
5151 GetRuleBaseRiskScore (ruleId string ) float64
5252}
5353
54+ type ctxKey string
55+
5456const (
55- customRegexRuleIdFormat = "custom-regex-%d"
56- CxFileEndMarker = ";cx-file-end"
57+ customRegexRuleIdFormat = "custom-regex-%d"
58+ CxFileEndMarker = ";cx-file-end"
59+ totalLinesKey ctxKey = "totalLines"
60+ linesInChunkKey ctxKey = "linesInChunk"
5761)
5862
5963type EngineConfig struct {
@@ -109,7 +113,7 @@ func (e *Engine) DetectFragment(item plugins.ISourceItem, secretsChannel chan *s
109113 FilePath : item .GetSource (),
110114 }
111115
112- return e .detectSecrets (item , fragment , secretsChannel , pluginName )
116+ return e .detectSecrets (context . Background (), item , fragment , secretsChannel , pluginName )
113117}
114118
115119// DetectFile reads the given file and detects secrets in it
@@ -137,7 +141,7 @@ func (e *Engine) DetectFile(ctx context.Context, item plugins.ISourceItem, secre
137141 }
138142 defer e .semaphore .ReleaseMemoryWeight (weight )
139143
140- return e .detectChunks (item , secretsChannel )
144+ return e .detectChunks (ctx , item , secretsChannel )
141145 }
142146 // fileSize * 2 -> data file bytes and its conversion to string
143147 weight := fileSize * 2
@@ -156,11 +160,11 @@ func (e *Engine) DetectFile(ctx context.Context, item plugins.ISourceItem, secre
156160 FilePath : item .GetSource (),
157161 }
158162
159- return e .detectSecrets (item , fragment , secretsChannel , "filesystem" )
163+ return e .detectSecrets (ctx , item , fragment , secretsChannel , "filesystem" )
160164}
161165
162166// detectChunks reads the given file in chunks and detects secrets in each chunk
163- func (e * Engine ) detectChunks (item plugins.ISourceItem , secretsChannel chan * secrets.Secret ) error {
167+ func (e * Engine ) detectChunks (ctx context. Context , item plugins.ISourceItem , secretsChannel chan * secrets.Secret ) error {
164168 f , err := os .Open (item .GetSource ())
165169 if err != nil {
166170 return fmt .Errorf ("failed to open file %s: %w" , item .GetSource (), err )
@@ -194,20 +198,22 @@ func (e *Engine) detectChunks(item plugins.ISourceItem, secretsChannel chan *sec
194198 Raw : chunkStr ,
195199 FilePath : item .GetSource (),
196200 }
197- if detectErr := e .detectSecrets (item , fragment , secretsChannel , "filesystem" ); detectErr != nil {
201+ ctx = context .WithValue (ctx , totalLinesKey , totalLines )
202+ ctx = context .WithValue (ctx , linesInChunkKey , linesInChunk )
203+ if detectErr := e .detectSecrets (ctx , item , fragment , secretsChannel , "filesystem" ); detectErr != nil {
198204 return fmt .Errorf ("failed to detect secrets: %w" , detectErr )
199205 }
200206 }
201207}
202208
203209// detectSecrets detects secrets and sends them to the secrets channel
204- func (e * Engine ) detectSecrets (item plugins.ISourceItem , fragment detect.Fragment , secrets chan * secrets.Secret ,
210+ func (e * Engine ) detectSecrets (ctx context. Context , item plugins.ISourceItem , fragment detect.Fragment , secrets chan * secrets.Secret ,
205211 pluginName string ) error {
206212 fragment .Raw += CxFileEndMarker + "\n "
207213
208214 values := e .detector .Detect (fragment )
209215 for _ , value := range values {
210- secret , buildErr := buildSecret (item , value , pluginName )
216+ secret , buildErr := buildSecret (ctx , item , value , pluginName )
211217 if buildErr != nil {
212218 return fmt .Errorf ("failed to build secret: %w" , buildErr )
213219 }
@@ -306,10 +312,10 @@ func GetRulesCommand(engineConfig *EngineConfig) *cobra.Command {
306312}
307313
308314// buildSecret creates a secret object from the given source item and finding
309- func buildSecret (item plugins.ISourceItem , value report.Finding , pluginName string ) (* secrets.Secret , error ) {
315+ func buildSecret (ctx context. Context , item plugins.ISourceItem , value report.Finding , pluginName string ) (* secrets.Secret , error ) {
310316 gitInfo := item .GetGitInfo ()
311317 itemId := getFindingId (item , value )
312- startLine , endLine , err := getStartAndEndLines (pluginName , gitInfo , value )
318+ startLine , endLine , err := getStartAndEndLines (ctx , pluginName , gitInfo , value )
313319 if err != nil {
314320 return nil , fmt .Errorf ("failed to get start and end lines for source %s: %w" , item .GetSource (), err )
315321 }
@@ -342,13 +348,21 @@ func getFindingId(item plugins.ISourceItem, finding report.Finding) string {
342348 return fmt .Sprintf ("%x" , sha )
343349}
344350
345- func getStartAndEndLines (pluginName string , gitInfo * plugins.GitInfo , value report.Finding ) (int , int , error ) {
351+ func getStartAndEndLines (ctx context. Context , pluginName string , gitInfo * plugins.GitInfo , value report.Finding ) (int , int , error ) {
346352 var startLine , endLine int
347353 var err error
348354
349355 if pluginName == "filesystem" {
350- startLine = value .StartLine + 1
351- endLine = value .EndLine + 1
356+ totalLines , totalOK := ctx .Value (totalLinesKey ).(int )
357+ chunkLines , chunkOK := ctx .Value (linesInChunkKey ).(int )
358+
359+ offset := 1
360+ if totalOK && chunkOK {
361+ offset = (totalLines - chunkLines ) + 1
362+ }
363+
364+ startLine = value .StartLine + offset
365+ endLine = value .EndLine + offset
352366 } else if pluginName == "git" {
353367 startLine , endLine , err = plugins .GetGitStartAndEndLine (gitInfo , value .StartLine , value .EndLine )
354368 if err != nil {
0 commit comments