@@ -93,18 +93,18 @@ def test_fortify_many_fdr_findings(self):
9393
9494 with self .subTest (i = 0 ):
9595 finding = findings [0 ]
96- self .assertEqual ("Cross-Site Request Forgery - category.html: 219 (114E5A67-3446-4DD5-B578-D0E6FDBB304E)" , finding .title )
96+ self .assertEqual ("Cross-Site Request Forgery - category.html: 222 (114E5A67-3446-4DD5-B578-D0E6FDBB304E)" , finding .title )
9797 self .assertEqual ("Low" , finding .severity )
9898 self .assertEqual ("1B87289954501EF8FD3861819DD98C27" , finding .unique_id_from_tool )
9999 self .assertEqual ("public/category.html" , finding .file_path )
100- self .assertEqual (219 , finding .line )
100+ self .assertEqual (222 , finding .line )
101101 with self .subTest (i = 1 ):
102102 finding = findings [50 ]
103- self .assertEqual ("Insecure Transport - footer.html: 104 (C72A3E77-8324-4FF9-B958-74FCDDF39D17)" , finding .title )
103+ self .assertEqual ("Insecure Transport - footer.html: 107 (C72A3E77-8324-4FF9-B958-74FCDDF39D17)" , finding .title )
104104 self .assertEqual ("Medium" , finding .severity )
105105 self .assertEqual ("D739B2E51B127BDFA4FE07B5A7662A45" , finding .unique_id_from_tool )
106106 self .assertEqual ("public/footer.html" , finding .file_path )
107- self .assertEqual (104 , finding .line )
107+ self .assertEqual (107 , finding .line )
108108
109109 def test_fortify_hello_world_fpr_findings (self ):
110110 with (get_unit_tests_scans_path ("fortify" ) / "hello_world.fpr" ).open (encoding = "utf-8" ) as testfile :
@@ -117,18 +117,45 @@ def test_fortify_hello_world_fpr_findings(self):
117117
118118 with self .subTest (i = 0 ):
119119 finding = findings [0 ]
120- self .assertEqual ("Password Management - HelloWorld.java: 5 (720E3A66-55AC-4D2D-8DB9-DC30E120A52F)" , finding .title )
120+ self .assertEqual ("Password Management - HelloWorld.java: 8 (720E3A66-55AC-4D2D-8DB9-DC30E120A52F)" , finding .title )
121121 self .assertEqual ("Low" , finding .severity )
122122 self .assertEqual ("A5338E223E737FF81F8A806C50A05969" , finding .unique_id_from_tool )
123123 self .assertEqual ("src/main/java/hello/HelloWorld.java" , finding .file_path )
124- self .assertEqual (5 , finding .line )
124+ self .assertEqual (8 , finding .line )
125125 with self .subTest (i = 1 ):
126126 finding = findings [1 ]
127- self .assertEqual ("Password Management - HelloWorld.java: 13 (9C5BD1B5-C296-48d4-B5F5-5D2958661BC4)" , finding .title )
127+ self .assertEqual ("Password Management - HelloWorld.java: 16 (9C5BD1B5-C296-48d4-B5F5-5D2958661BC4)" , finding .title )
128128 self .assertEqual ("High" , finding .severity )
129129 self .assertEqual ("D3166922519EDD92D132761602EB71B4" , finding .unique_id_from_tool )
130130 self .assertEqual ("src/main/java/hello/HelloWorld.java" , finding .file_path )
131- self .assertEqual (13 , finding .line )
131+ self .assertEqual (16 , finding .line )
132+
133+ # Regression: FPR parser stored the snippet context StartLine (reported line - 3)
134+ # instead of Fortify's reported SourceLocation line, breaking file_path+line dedup.
135+ def test_fortify_fpr_uses_true_source_location_line (self ):
136+ with (get_unit_tests_scans_path ("fortify" ) / "many_findings.fpr" ).open (encoding = "utf-8" ) as testfile :
137+ parser = FortifyParser ()
138+ findings = parser .get_findings (testfile , Test ())
139+ finding = findings [0 ]
140+ # control: the description records Fortify's reported line verbatim
141+ self .assertIn ("**SourceLocationLine:** 222" , finding .description )
142+ # the stored line must match the reported line, not the snippet start (219)
143+ self .assertEqual (
144+ 222 , finding .line ,
145+ msg = f"expected line=222 (SourceLocationLine), stored line={ finding .line } " ,
146+ )
147+ self .assertEqual ("Cross-Site Request Forgery - category.html: 222 (114E5A67-3446-4DD5-B578-D0E6FDBB304E)" , finding .title )
148+ with (get_unit_tests_scans_path ("fortify" ) / "hello_world.fpr" ).open (encoding = "utf-8" ) as testfile :
149+ parser = FortifyParser ()
150+ findings = parser .get_findings (testfile , Test ())
151+ # near the top of a file the snippet start clamps to 1, so the offset
152+ # is not even constant: reported line 3, snippet start 1
153+ finding = findings [2 ]
154+ self .assertIn ("**SourceLocationLine:** 3" , finding .description )
155+ self .assertEqual (
156+ 3 , finding .line ,
157+ msg = f"expected line=3 (SourceLocationLine), stored line={ finding .line } " ,
158+ )
132159
133160 def test_fortify_webinspect_4_2_many_findings (self ):
134161 with (get_unit_tests_scans_path ("fortify" ) / "webinspect_4_2_many_findings.xml" ).open (encoding = "utf-8" ) as testfile :
@@ -152,14 +179,14 @@ def test_fortify_fpr_suppressed_finding(self):
152179
153180 with self .subTest (i = 0 ):
154181 finding = findings [0 ]
155- self .assertEqual ("Password Management - HelloWorld.java: 5 (720E3A66-55AC-4D2D-8DB9-DC30E120A52F)" , finding .title )
182+ self .assertEqual ("Password Management - HelloWorld.java: 8 (720E3A66-55AC-4D2D-8DB9-DC30E120A52F)" , finding .title )
156183 self .assertEqual ("A5338E223E737FF81F8A806C50A05969" , finding .unique_id_from_tool )
157184 self .assertTrue (finding .active )
158185 self .assertFalse (finding .false_p )
159186 self .assertEqual ("" , finding .impact )
160187 with self .subTest (i = 1 ):
161188 finding = findings [2 ]
162- self .assertEqual ("Build Misconfiguration - pom.xml: 1 (FF57412F-DD28-44DE-8F4F-0AD39620768C)" , finding .title )
189+ self .assertEqual ("Build Misconfiguration - pom.xml: 3 (FF57412F-DD28-44DE-8F4F-0AD39620768C)" , finding .title )
163190 self .assertEqual ("87E3EC5CC8154C006783CC461A6DDEEB" , finding .unique_id_from_tool )
164191 self .assertFalse (finding .active )
165192 self .assertTrue (finding .false_p )
@@ -176,16 +203,16 @@ def test_fortify_hello_world_fpr_rule_without_metainfo(self):
176203
177204 with self .subTest (i = 0 ):
178205 finding = findings [0 ]
179- self .assertEqual ("Password Management - HelloWorld.java: 5 (720E3A66-55AC-4D2D-8DB9-DC30E120A52F)" , finding .title )
206+ self .assertEqual ("Password Management - HelloWorld.java: 8 (720E3A66-55AC-4D2D-8DB9-DC30E120A52F)" , finding .title )
180207 # Info as rule has no metainfo/impact
181208 self .assertEqual ("Info" , finding .severity )
182209 self .assertEqual ("A5338E223E737FF81F8A806C50A05969" , finding .unique_id_from_tool )
183210 self .assertEqual ("src/main/java/hello/HelloWorld.java" , finding .file_path )
184- self .assertEqual (5 , finding .line )
211+ self .assertEqual (8 , finding .line )
185212 with self .subTest (i = 1 ):
186213 finding = findings [1 ]
187- self .assertEqual ("Password Management - HelloWorld.java: 13 (9C5BD1B5-C296-48d4-B5F5-5D2958661BC4)" , finding .title )
214+ self .assertEqual ("Password Management - HelloWorld.java: 16 (9C5BD1B5-C296-48d4-B5F5-5D2958661BC4)" , finding .title )
188215 self .assertEqual ("High" , finding .severity )
189216 self .assertEqual ("D3166922519EDD92D132761602EB71B4" , finding .unique_id_from_tool )
190217 self .assertEqual ("src/main/java/hello/HelloWorld.java" , finding .file_path )
191- self .assertEqual (13 , finding .line )
218+ self .assertEqual (16 , finding .line )
0 commit comments