Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions internal/runner/lazy.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ func GetAuthTmplStore(opts *types.Options, catalog catalog.Catalog, execOpts *pr
// GetLazyAuthFetchCallback returns a lazy fetch callback for auth secrets
func GetLazyAuthFetchCallback(opts *AuthLazyFetchOptions) authx.LazyFetchSecret {
return func(d *authx.Dynamic) error {
tmpls := opts.TemplateStore.LoadTemplates([]string{d.TemplatePath})
tmpls, err := opts.TemplateStore.LoadTemplates([]string{d.TemplatePath})
if err != nil {
return errkit.Wrap(err, "failed to load template")
}
if len(tmpls) == 0 {
return fmt.Errorf("%w for path: %s", disk.ErrNoTemplatesFound, d.TemplatePath)
}
Expand Down Expand Up @@ -140,7 +143,7 @@ func GetLazyAuthFetchCallback(opts *AuthLazyFetchOptions) authx.LazyFetchSecret
// log result of template in result file/screen
_ = writer.WriteResult(e, opts.ExecOpts.Output, opts.ExecOpts.Progress, opts.ExecOpts.IssuesClient)
}
_, err := tmpl.Executer.ExecuteWithResults(ctx)
_, err = tmpl.Executer.ExecuteWithResults(ctx)
if err != nil {
finalErr = err
}
Expand Down
16 changes: 10 additions & 6 deletions pkg/catalog/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,11 @@ func (store *Store) RegisterPreprocessor(preprocessor templates.Preprocessor) {
// Load loads all the templates from a store, performs filtering and returns
// the complete compiled templates for a nuclei execution configuration.
func (store *Store) Load() {
store.templates = store.LoadTemplates(store.finalTemplates)
templates, err := store.LoadTemplates(store.finalTemplates)
if err != nil {
store.logger.Fatal().Msgf("Could not load templates: %s\n", err)
}
store.templates = templates
store.workflows = store.LoadWorkflows(store.finalWorkflows)
}

Expand Down Expand Up @@ -637,7 +641,7 @@ func isParsingError(store *Store, message string, template string, err error) bo
}

// LoadTemplates takes a list of templates and returns paths for them
func (store *Store) LoadTemplates(templatesList []string) []*templates.Template {
func (store *Store) LoadTemplates(templatesList []string) ([]*templates.Template, error) {
return store.LoadTemplatesWithTags(templatesList, nil)
}
Comment on lines 643 to 646
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update method docs to describe the new error contract.

These APIs now return errors, but the comments still only describe successful behavior. Please document concrete failure modes (e.g., missing dialers / wait-group creation failure) so callers know what to handle.

Also applies to: 673-675

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/catalog/loader/loader.go` around lines 643 - 646, Update the method
comments for Store.LoadTemplates and the related LoadTemplatesWithTags to
document the new error contract: list concrete failure modes callers must handle
(e.g., missing dialers / connection setup failure, wait-group or goroutine setup
errors, template not found or path resolution failures, I/O/read/parsing errors,
and permission/OS errors), and state that the function may return a non-nil
error on these conditions instead of returning only successful results;
reference the function names Store.LoadTemplates and Store.LoadTemplatesWithTags
in the comments so callers can find the documented error cases.


Expand Down Expand Up @@ -668,7 +672,7 @@ func (store *Store) LoadWorkflows(workflowsList []string) []*templates.Template

// LoadTemplatesWithTags takes a list of templates and extra tags
// returning templates that match.
func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templates.Template {
func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) ([]*templates.Template, error) {
defer store.saveMetadataIndexOnce()

indexFilter := store.indexFilter
Expand Down Expand Up @@ -708,7 +712,7 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ

wgLoadTemplates, errWg := syncutil.New(syncutil.WithSize(concurrency))
if errWg != nil {
panic("could not create wait group")
return nil, fmt.Errorf("could not create wait group: %w", errWg)
}

if typesOpts.ExecutionId == "" {
Expand All @@ -717,7 +721,7 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ

dialers := protocolstate.GetDialersWithId(typesOpts.ExecutionId)
if dialers == nil {
panic("dialers with executionId " + typesOpts.ExecutionId + " not found")
return nil, fmt.Errorf("dialers with executionId %s not found", typesOpts.ExecutionId)
}

for _, templatePath := range includedTemplates {
Expand Down Expand Up @@ -852,7 +856,7 @@ func (store *Store) LoadTemplatesWithTags(templatesList, tags []string) []*templ
return loadedTemplates.Slice[i].Path < loadedTemplates.Slice[j].Path
})

return loadedTemplates.Slice
return loadedTemplates.Slice, nil
}

// IsHTTPBasedProtocolUsed returns true if http/headless protocol is being used for
Expand Down
14 changes: 7 additions & 7 deletions pkg/catalog/loader/loader_bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
b.ReportAllocs()

for b.Loop() {
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Don’t drop LoadTemplates errors inside benchmark loops.

At Lines 74/92/110/128/146/164/184, silently discarding errors can benchmark an error path and mask loader regressions.

Suggested pattern (apply to each benchmark loop)
-		for b.Loop() {
-			_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
-		}
+		for b.Loop() {
+			if _, err := store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory}); err != nil {
+				b.Fatalf("could not load templates: %s", err)
+			}
+		}

Also applies to: 92-92, 110-110, 128-128, 146-146, 164-164, 184-184

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/catalog/loader/loader_bench_test.go` at line 74, Benchmarks are currently
discarding errors from store.LoadTemplates, which can hide failures; replace the
blank assignment with error handling inside each benchmark loop by capturing the
returned error from store.LoadTemplates (called on the store variable) and
failing the benchmark on error (e.g., if err != nil { b.Fatalf("LoadTemplates
failed: %v", err) }) or move the call outside the per-iteration loop if it
shouldn’t run every iteration; apply this change for every occurrence of
store.LoadTemplates in loader_bench_test.go so errors aren’t silently ignored.

}
})

Expand All @@ -89,7 +89,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
b.ReportAllocs()

for b.Loop() {
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
}
})

Expand All @@ -107,7 +107,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
b.ReportAllocs()

for b.Loop() {
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
}
})

Expand All @@ -125,7 +125,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
b.ReportAllocs()

for b.Loop() {
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
}
})

Expand All @@ -143,7 +143,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
b.ReportAllocs()

for b.Loop() {
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
}
})

Expand All @@ -161,7 +161,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
b.ReportAllocs()

for b.Loop() {
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
}
})

Expand All @@ -181,7 +181,7 @@ func BenchmarkLoadTemplates(b *testing.B) {
b.ReportAllocs()

for b.Loop() {
_ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
_, _ = store.LoadTemplates([]string{config.DefaultConfig.TemplatesDirectory})
}
})
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/protocols/common/automaticscan/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ func getTemplateDirs(opts Options) ([]string, error) {

// LoadTemplatesWithTags loads and returns templates with given tags
func LoadTemplatesWithTags(opts Options, templateDirs []string, tags []string, logInfo bool) ([]*templates.Template, error) {
finalTemplates := opts.Store.LoadTemplatesWithTags(templateDirs, tags)
finalTemplates, err := opts.Store.LoadTemplatesWithTags(templateDirs, tags)
if err != nil {
return nil, err
}
if len(finalTemplates) == 0 {
return nil, errors.New("could not find any templates with tech tag")
}
Expand Down