@@ -1029,6 +1029,212 @@ func compareOrUpdateTestData(t *testing.T, actualReport reporting.IReport, expec
10291029 assert .EqualValues (t , normalizedExpectedReport , normalizedActualReport )
10301030}
10311031
1032+ func TestScan_LimitSettings (t * testing.T ) {
1033+ // Load test data once for all subtests
1034+ githubPatBytes , err := os .ReadFile (githubPatPath )
1035+ assert .NoError (t , err , "failed to read github-pat file" )
1036+ githubPatContent := string (githubPatBytes )
1037+
1038+ jwtBytes , err := os .ReadFile (jwtPath )
1039+ assert .NoError (t , err , "failed to read jwt file" )
1040+ jwtContent := string (jwtBytes )
1041+
1042+ genericKeysBytes , err := os .ReadFile (genericKeysPath )
1043+ assert .NoError (t , err , "failed to read generic-api-keys file" )
1044+ genericKeysContent := string (genericKeysBytes )
1045+
1046+ tests := []struct {
1047+ name string
1048+ filePaths []string
1049+ maxFindings uint64
1050+ maxRuleMatchesPerFragment uint64
1051+ maxSecretSize uint64
1052+ expectedMaxFindings int
1053+ expectedMaxSecretSize int
1054+ }{
1055+ {
1056+ name : "MaxFindings limits total secrets found" ,
1057+ filePaths : []string {githubPatPath , jwtPath , genericKeysPath },
1058+ maxFindings : 2 ,
1059+ maxRuleMatchesPerFragment : 0 ,
1060+ maxSecretSize : 0 ,
1061+ expectedMaxFindings : 2 ,
1062+ expectedMaxSecretSize : 1000 ,
1063+ },
1064+ {
1065+ name : "MaxRuleMatchesPerFragment limits matches per rule per fragment" ,
1066+ filePaths : []string {githubPatPath },
1067+ maxFindings : 0 ,
1068+ maxRuleMatchesPerFragment : 1 ,
1069+ maxSecretSize : 0 ,
1070+ expectedMaxFindings : 2 ,
1071+ expectedMaxSecretSize : 1000 ,
1072+ },
1073+ {
1074+ name : "MaxSecretSize filters out large secrets" ,
1075+ filePaths : []string {jwtPath , githubPatPath },
1076+ maxFindings : 0 ,
1077+ maxRuleMatchesPerFragment : 0 ,
1078+ maxSecretSize : 50 ,
1079+ expectedMaxFindings : 100 ,
1080+ expectedMaxSecretSize : 50 ,
1081+ },
1082+ {
1083+ name : "All limit settings work together" ,
1084+ filePaths : []string {githubPatPath , jwtPath , genericKeysPath },
1085+ maxFindings : 3 ,
1086+ maxRuleMatchesPerFragment : 1 ,
1087+ maxSecretSize : 100 ,
1088+ expectedMaxFindings : 3 ,
1089+ expectedMaxSecretSize : 100 ,
1090+ },
1091+ }
1092+
1093+ // Map file paths to content
1094+ contentMap := map [string ]* string {
1095+ githubPatPath : & githubPatContent ,
1096+ jwtPath : & jwtContent ,
1097+ genericKeysPath : & genericKeysContent ,
1098+ }
1099+
1100+ for _ , tt := range tests {
1101+ t .Run (tt .name , func (t * testing.T ) {
1102+ scanItems := make ([]ScanItem , 0 , len (tt .filePaths ))
1103+ for _ , path := range tt .filePaths {
1104+ scanItems = append (scanItems , ScanItem {
1105+ Content : contentMap [path ],
1106+ ID : fmt .Sprintf ("mock-%s" , path ),
1107+ Source : path ,
1108+ })
1109+ }
1110+
1111+ testScanner := NewScanner ()
1112+ actualReport , err := testScanner .Scan (scanItems , resources.ScanConfig {
1113+ MaxFindings : tt .maxFindings ,
1114+ MaxRuleMatchesPerFragment : tt .maxRuleMatchesPerFragment ,
1115+ MaxSecretSize : tt .maxSecretSize ,
1116+ })
1117+ assert .NoError (t , err , "scanner encountered an error" )
1118+
1119+ totalSecrets := actualReport .GetTotalSecretsFound ()
1120+ assert .LessOrEqual (t , totalSecrets , tt .expectedMaxFindings , "total secrets should respect max findings limit" )
1121+
1122+ results := actualReport .GetResults ()
1123+ for _ , secretsList := range results {
1124+ for _ , secret := range secretsList {
1125+ assert .LessOrEqual (t , len (secret .Value ), tt .expectedMaxSecretSize , "secret value exceeds max size" )
1126+ }
1127+ }
1128+ })
1129+ }
1130+ }
1131+
1132+ func TestScanDynamic_LimitSettings (t * testing.T ) {
1133+ // Load test data once for all subtests
1134+ githubPatBytes , err := os .ReadFile (githubPatPath )
1135+ assert .NoError (t , err , "failed to read github-pat file" )
1136+ githubPatContent := string (githubPatBytes )
1137+
1138+ jwtBytes , err := os .ReadFile (jwtPath )
1139+ assert .NoError (t , err , "failed to read jwt file" )
1140+ jwtContent := string (jwtBytes )
1141+
1142+ genericKeysBytes , err := os .ReadFile (genericKeysPath )
1143+ assert .NoError (t , err , "failed to read generic-api-keys file" )
1144+ genericKeysContent := string (genericKeysBytes )
1145+
1146+ tests := []struct {
1147+ name string
1148+ filePaths []string
1149+ maxFindings uint64
1150+ maxRuleMatchesPerFragment uint64
1151+ maxSecretSize uint64
1152+ expectedMaxFindings int
1153+ expectedMaxSecretSize int
1154+ }{
1155+ {
1156+ name : "MaxFindings limits total secrets found" ,
1157+ filePaths : []string {githubPatPath , jwtPath , genericKeysPath },
1158+ maxFindings : 2 ,
1159+ maxRuleMatchesPerFragment : 0 ,
1160+ maxSecretSize : 0 ,
1161+ expectedMaxFindings : 2 ,
1162+ expectedMaxSecretSize : 1000 ,
1163+ },
1164+ {
1165+ name : "MaxRuleMatchesPerFragment limits matches per rule per fragment" ,
1166+ filePaths : []string {githubPatPath },
1167+ maxFindings : 0 ,
1168+ maxRuleMatchesPerFragment : 1 ,
1169+ maxSecretSize : 0 ,
1170+ expectedMaxFindings : 2 ,
1171+ expectedMaxSecretSize : 1000 ,
1172+ },
1173+ {
1174+ name : "MaxSecretSize filters out large secrets" ,
1175+ filePaths : []string {jwtPath , githubPatPath },
1176+ maxFindings : 0 ,
1177+ maxRuleMatchesPerFragment : 0 ,
1178+ maxSecretSize : 50 ,
1179+ expectedMaxFindings : 100 ,
1180+ expectedMaxSecretSize : 50 ,
1181+ },
1182+ {
1183+ name : "All limit settings work together" ,
1184+ filePaths : []string {githubPatPath , jwtPath , genericKeysPath },
1185+ maxFindings : 3 ,
1186+ maxRuleMatchesPerFragment : 1 ,
1187+ maxSecretSize : 100 ,
1188+ expectedMaxFindings : 3 ,
1189+ expectedMaxSecretSize : 100 ,
1190+ },
1191+ }
1192+
1193+ // Map file paths to content
1194+ contentMap := map [string ]* string {
1195+ githubPatPath : & githubPatContent ,
1196+ jwtPath : & jwtContent ,
1197+ genericKeysPath : & genericKeysContent ,
1198+ }
1199+
1200+ for _ , tt := range tests {
1201+ t .Run (tt .name , func (t * testing.T ) {
1202+ scanItems := make ([]ScanItem , 0 , len (tt .filePaths ))
1203+ for _ , path := range tt .filePaths {
1204+ scanItems = append (scanItems , ScanItem {
1205+ Content : contentMap [path ],
1206+ ID : fmt .Sprintf ("mock-%s" , path ),
1207+ Source : path ,
1208+ })
1209+ }
1210+
1211+ itemsIn := make (chan ScanItem , len (scanItems ))
1212+ for _ , item := range scanItems {
1213+ itemsIn <- item
1214+ }
1215+ close (itemsIn )
1216+
1217+ testScanner := NewScanner ()
1218+ actualReport , err := testScanner .ScanDynamic (itemsIn , resources.ScanConfig {
1219+ MaxFindings : tt .maxFindings ,
1220+ MaxRuleMatchesPerFragment : tt .maxRuleMatchesPerFragment ,
1221+ MaxSecretSize : tt .maxSecretSize ,
1222+ })
1223+ assert .NoError (t , err , "scanner encountered an error" )
1224+
1225+ totalSecrets := actualReport .GetTotalSecretsFound ()
1226+ assert .LessOrEqual (t , totalSecrets , tt .expectedMaxFindings , "total secrets should respect max findings limit" )
1227+
1228+ results := actualReport .GetResults ()
1229+ for _ , secretsList := range results {
1230+ for _ , secret := range secretsList {
1231+ assert .LessOrEqual (t , len (secret .Value ), tt .expectedMaxSecretSize , "secret value exceeds max size" )
1232+ }
1233+ }
1234+ })
1235+ }
1236+ }
1237+
10321238func cloneRules (rulesToClone []* ruledefine.Rule ) []* ruledefine.Rule {
10331239 clonedRules := make ([]* ruledefine.Rule , 0 , len (rulesToClone ))
10341240 for _ , rule := range rulesToClone {
0 commit comments