{"record":{"id":"80e0ff8a15ec6e95","repo":"shadow1ng/fscan","slug":"parser-invalid-ip-end-val","errorCode":null,"errorMessage":"parser_invalid_ip_end_val","messagePattern":"parser_invalid_ip_end_val","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/parsers/host_iterator.go","lineNumber":360,"sourceCode":"}\n\nfunc newRangeHostSource(rangeStr string) (hostSource, error) {\n\tparts := strings.Split(rangeStr, \"-\")\n\tif len(parts) != 2 {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_ip_range_fmt\", rangeStr))\n\t}\n\n\tstartIPStr := strings.TrimSpace(parts[0])\n\tendIPStr := strings.TrimSpace(parts[1])\n\tstartIP := net.ParseIP(startIPStr)\n\tif startIP == nil {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_start_ip\", startIPStr))\n\t}\n\n\tif len(endIPStr) < 4 || !strings.Contains(endIPStr, \".\") {\n\t\tendNum, err := strconv.Atoi(endIPStr)\n\t\tif err != nil || endNum > 255 {\n\t\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_ip_end_val\", endIPStr))\n\t\t}\n\t\tparts := strings.Split(startIPStr, \".\")\n\t\tif len(parts) != 4 {\n\t\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_ip_fmt\", startIPStr))\n\t\t}\n\t\tparts[3] = strconv.Itoa(endNum)\n\t\tendIPStr = strings.Join(parts, \".\")\n\t}\n\n\tstart, ok := ipToUint32(startIP)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.GetText(\"parser_ipv4_only\"))\n\t}\n\tend, ok := ipToUint32(net.ParseIP(endIPStr))\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%s\", i18n.Tr(\"parser_invalid_end_ip\", endIPStr))\n\t}\n\tif start > end {","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/parsers/host_iterator.go#L342-L378","documentation":"The short-tail end of a range (an octet number rather than a full IP, e.g. \"10.0.0.1-50\") must parse as an integer between 0 and 255. When strconv.Atoi fails or the number exceeds 255, newRangeHostSource returns this message naming the invalid end value.","triggerScenarios":"addRange with \"10.0.0.1-300\", \"10.0.0.1-abc\", or \"10.0.0.1-\" where the tail is neither a full dotted IP nor a numeric octet in 0–255.","commonSituations":"Typing 256–999 as the last octet (\"192.168.0.1-999\"); accidentally using a port number as the tail (\"10.0.0.1-8080\"); non-numeric garbage from a malformed config line.","solutions":["Use an end octet in the range 0–255: \"10.0.0.1-254\".","If the end host is above .255, specify a full end IP: \"10.0.0.1-10.0.1.50\".","Pre-validate: if the tail is not dotted, check strconv.Atoi succeeds and value <= 255 before calling addRange."],"exampleFix":"// before\nm.AddRange(\"192.168.0.1-999\") // parser_invalid_ip_end_val\n\n// after\nm.AddRange(\"192.168.0.1-192.168.1.100\") // full end IP for cross-octet ranges","handlingStrategy":"validation","validationCode":"func validEndTail(rng string) bool {\n    parts := strings.SplitN(rng, \"-\", 2)\n    if len(parts) != 2 {\n        return false\n    }\n    tail := strings.TrimSpace(parts[1])\n    if strings.Contains(tail, \".\") {\n        return net.ParseIP(tail) != nil\n    }\n    n, err := strconv.Atoi(tail)\n    return err == nil && n >= 0 && n <= 255\n}","typeGuard":null,"tryCatchPattern":"if err := matcher.AddRange(rng); err != nil {\n    log.Printf(\"bad range tail in %q: %v\", rng, err)\n    return nil\n}","preventionTips":["Remember the short tail is an octet (0–255), not a count or port.","For ranges spanning octets, always use full dotted end IPs."],"tags":["ip-range","parser","go","out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}