From 5ccf827cd8937f22d9a90a36e916a50cd89aac62 Mon Sep 17 00:00:00 2001 From: Kral <118106297+dashitongzhi@users.noreply.github.com> Date: Wed, 20 May 2026 09:12:04 +0800 Subject: [PATCH 1/2] code quality: improve error handling and fix bugs - Fix bug: return err instead of closeErr in DecodeData error path (httpx.go) - Improve error handling for strconv.Atoi calls in multiple locations - Change hammingDistanceThreshold from var to const since it's never modified - Fix redundant return statement in ListFilesWithPattern - Improve port parsing to handle empty port strings explicitly --- common/fileutil/fileutil.go | 2 +- common/hashes/jarm/jarmhash.go | 7 +++++-- common/httpx/httpx.go | 7 ++++--- runner/runner.go | 30 +++++++++++++++++++----------- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/common/fileutil/fileutil.go b/common/fileutil/fileutil.go index 994587a42..24ba53f99 100644 --- a/common/fileutil/fileutil.go +++ b/common/fileutil/fileutil.go @@ -52,7 +52,7 @@ func ListFilesWithPattern(rootpattern string) ([]string, error) { if len(files) == 0 { return nil, errors.New("no files found") } - return files, err + return files, nil } // FileNameIsGlob check if the filanem is a pattern diff --git a/common/hashes/jarm/jarmhash.go b/common/hashes/jarm/jarmhash.go index 5b45656ba..d96f1ad23 100644 --- a/common/hashes/jarm/jarmhash.go +++ b/common/hashes/jarm/jarmhash.go @@ -75,8 +75,11 @@ func Jarm(dialer *fastdialer.Dialer, host string, duration int) string { return "" } t.Host = u.Hostname() - port, _ := strconv.Atoi(u.Port()) - t.Port = port + if portStr := u.Port(); portStr != "" { + if p, err := strconv.Atoi(portStr); err == nil { + t.Port = p + } + } } if t.Port == 0 { t.Port = defaultPort diff --git a/common/httpx/httpx.go b/common/httpx/httpx.go index b38fdf591..15c567f06 100644 --- a/common/httpx/httpx.go +++ b/common/httpx/httpx.go @@ -293,7 +293,7 @@ get_response: respbody, err = DecodeData(respbody, httpresp.Header) if err != nil && !shouldIgnoreBodyErrors { - return nil, closeErr + return nil, err } respbodystr := string(respbody) @@ -307,8 +307,9 @@ get_response: if resp.ContentLength <= 0 { // check if it's in the header and convert to int if contentLength, ok := resp.Headers["Content-Length"]; ok && len(contentLength) > 0 { - contentLengthInt, _ := strconv.Atoi(contentLength[0]) - resp.ContentLength = contentLengthInt + if contentLengthInt, err := strconv.Atoi(contentLength[0]); err == nil { + resp.ContentLength = contentLengthInt + } } // if we have a body, then use the number of bytes in the body if the length is still zero diff --git a/runner/runner.go b/runner/runner.go index af9db5661..d00582f2b 100644 --- a/runner/runner.go +++ b/runner/runner.go @@ -125,7 +125,7 @@ func (r *Runner) IsInterrupted() bool { } // picked based on try-fail but it seems to close to one it's used https://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html#c1992 -var hammingDistanceThreshold int = 22 +const hammingDistanceThreshold = 22 // regex for stripping ANSI codes var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`) @@ -552,9 +552,10 @@ func (r *Runner) prepareInput() { r.hm.Set(target, []byte("1")) //nolint } else if r.options.SkipDedupe && errors.Is(err, duplicateTargetErr) { if v, ok := r.hm.Get(target); ok { - cnt, _ := strconv.Atoi(string(v)) - _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) - numHosts += 1 + if cnt, parseErr := strconv.Atoi(string(v)); parseErr == nil && cnt > 0 { + _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) + numHosts += 1 + } } } } @@ -799,9 +800,10 @@ func (r *Runner) loadAndCloseFile(finput *os.File) (numTargets int, err error) { r.hm.Set(target, []byte("1")) //nolint } else if r.options.SkipDedupe && errors.Is(err, duplicateTargetErr) { if v, ok := r.hm.Get(target); ok { - cnt, _ := strconv.Atoi(string(v)) - _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) - numTargets += 1 + if cnt, parseErr := strconv.Atoi(string(v)); parseErr == nil && cnt > 0 { + _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) + numTargets += 1 + } } } } @@ -824,9 +826,10 @@ func (r *Runner) loadFromFormat(filePath string, format inputformats.Format) (nu r.hm.Set(target, []byte("1")) //nolint } else if r.options.SkipDedupe && errors.Is(countErr, duplicateTargetErr) { if v, ok := r.hm.Get(target); ok { - cnt, _ := strconv.Atoi(string(v)) - _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) - numTargets += 1 + if cnt, parseErr := strconv.Atoi(string(v)); parseErr == nil && cnt > 0 { + _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) + numTargets += 1 + } } } return true @@ -2204,7 +2207,12 @@ retry: pipeline := false if scanopts.Pipeline { - port, _ := strconv.Atoi(URL.Port()) + port := 0 + if portStr := URL.Port(); portStr != "" { + if p, err := strconv.Atoi(portStr); err == nil { + port = p + } + } r.ratelimiter.Take() pipeline = hp.SupportPipeline(protocol, method, URL.Host, port) if pipeline { From 127074e5a04bb391fe85b7a01977d5e45e319488 Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Wed, 20 May 2026 06:11:57 +0200 Subject: [PATCH 2/2] runner: keep input counters incrementing under -skip-dedupe Revert the defensive strconv.Atoi guard around the SkipDedupe branches: values stored in r.hm are always integer strings written by this same code path, so the parseErr/cnt>0 check is unreachable in practice, and when taken literally it skipped the numHosts/numTargets increment for duplicate inputs. --- runner/runner.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/runner/runner.go b/runner/runner.go index d00582f2b..352e4c74c 100644 --- a/runner/runner.go +++ b/runner/runner.go @@ -552,10 +552,9 @@ func (r *Runner) prepareInput() { r.hm.Set(target, []byte("1")) //nolint } else if r.options.SkipDedupe && errors.Is(err, duplicateTargetErr) { if v, ok := r.hm.Get(target); ok { - if cnt, parseErr := strconv.Atoi(string(v)); parseErr == nil && cnt > 0 { - _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) - numHosts += 1 - } + cnt, _ := strconv.Atoi(string(v)) + _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) + numHosts += 1 } } } @@ -800,10 +799,9 @@ func (r *Runner) loadAndCloseFile(finput *os.File) (numTargets int, err error) { r.hm.Set(target, []byte("1")) //nolint } else if r.options.SkipDedupe && errors.Is(err, duplicateTargetErr) { if v, ok := r.hm.Get(target); ok { - if cnt, parseErr := strconv.Atoi(string(v)); parseErr == nil && cnt > 0 { - _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) - numTargets += 1 - } + cnt, _ := strconv.Atoi(string(v)) + _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) + numTargets += 1 } } } @@ -826,10 +824,9 @@ func (r *Runner) loadFromFormat(filePath string, format inputformats.Format) (nu r.hm.Set(target, []byte("1")) //nolint } else if r.options.SkipDedupe && errors.Is(countErr, duplicateTargetErr) { if v, ok := r.hm.Get(target); ok { - if cnt, parseErr := strconv.Atoi(string(v)); parseErr == nil && cnt > 0 { - _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) - numTargets += 1 - } + cnt, _ := strconv.Atoi(string(v)) + _ = r.hm.Set(target, []byte(strconv.Itoa(cnt+1))) + numTargets += 1 } } return true