{"record":{"id":"117fb821400fa97e","repo":"shadow1ng/fscan","slug":"portfinger-probe-exclude-duplicate","errorCode":null,"errorMessage":"portfinger_probe_exclude_duplicate","messagePattern":"portfinger_probe_exclude_duplicate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/portfinger/probe_parser.go","lineNumber":194,"sourceCode":"\t\tif lineTemp == \"\" || strings.HasPrefix(lineTemp, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tlines = append(lines, lineTemp)\n\t}\n\n\t// 验证文件内容\n\tif len(lines) == 0 {\n\t\treturn fmt.Errorf(\"%s\", i18n.GetText(\"portfinger_probe_file_empty\"))\n\t}\n\n\t// 检查Exclude指令\n\texcludeCount := 0\n\tfor _, line := range lines {\n\t\tif strings.HasPrefix(line, \"Exclude \") {\n\t\t\texcludeCount++\n\t\t}\n\t\tif excludeCount > 1 {\n\t\t\treturn fmt.Errorf(\"%s\", i18n.GetText(\"portfinger_probe_exclude_duplicate\"))\n\t\t}\n\t}\n\n\t// 验证第一行格式\n\tfirstLine := lines[0]\n\tif !strings.HasPrefix(firstLine, \"Exclude \") && !strings.HasPrefix(firstLine, \"Probe \") {\n\t\treturn fmt.Errorf(\"%s\", i18n.GetText(\"portfinger_probe_first_line_invalid\"))\n\t}\n\n\t// 处理Exclude指令\n\tif excludeCount == 1 {\n\t\tv.Exclude = firstLine[len(\"Exclude\")+1:]\n\t\tlines = lines[1:]\n\t}\n\n\t// 合并内容并分割探测器\n\tcontent = \"\\n\" + strings.Join(lines, \"\\n\")\n\tprobeParts := strings.Split(content, \"\\nProbe\")[1:]","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/core/portfinger/probe_parser.go#L176-L212","documentation":"The probe file format allows at most one Exclude directive. parseProbesFromContent counts lines starting with \"Exclude \" and aborts with this error as soon as a second one is seen, because multiple exclusions cannot be represented in the current parser.","triggerScenarios":"Init/parseProbesFromContent is given a probe file containing two or more lines beginning with \"Exclude \".","commonSituations":"Merging probe lists from multiple sources each carrying their own Exclude line, manual edits appending another Exclude, or an upstream database update that added a second Exclude.","solutions":["Merge the exclusion ports into a single \"Exclude \" line (comma-separated) and delete the duplicates.","Keep only one Exclude line at the top of the probe file.","Preprocess the file at load time: collect all Exclude entries and rewrite them as one line.","Report the malformed file to the database maintainer if it came from upstream."],"exampleFix":"// before\nExclude 21,25\nProbe tcp GetHttp ...\nExclude 445,3306\n// after\nExclude 21,25,445,3306\nProbe tcp GetHttp ...","handlingStrategy":"validation","validationCode":"func countExcludes(lines []string) int {\n    n := 0\n    for _, l := range lines { if strings.HasPrefix(l, \"Exclude \") { n++ } }\n    return n\n}\n// reject file if countExcludes(lines) > 1","typeGuard":null,"tryCatchPattern":"if err := pf.Init(path); err != nil && strings.Contains(err.Error(), \"exclude_duplicate\") {\n    return fmt.Errorf(\"merge Exclude lines into one: %w\", err)\n}","preventionTips":["Keep at most one Exclude line, at the top of the file","Merge exclusions from multiple sources into a comma-separated single line","Add a file-format lint step before loading merged probe lists"],"tags":["portfinger","parsing","duplicate","file-format"],"backgroundTag":"invalid-config-value","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}