package disk
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/projectdiscovery/nuclei/v3/pkg/catalog/config"
fileutil "github.com/projectdiscovery/utils/file"
urlutil "github.com/projectdiscovery/utils/url"
)
func (c *DiskCatalog) ResolvePath(templateName, second string) (string, error) {
if filepath.IsAbs(templateName) {
return templateName, nil
}
if c.templatesFS != nil {
if potentialPath, err := c.tryResolve(templateName); err != errNoValidCombination {
return potentialPath, nil
}
}
if second != "" {
secondBasePath := filepath.Join(filepath.Dir(second), templateName)
if potentialPath, err := c.tryResolve(secondBasePath); err != errNoValidCombination {
return potentialPath, nil
}
}
if c.templatesFS == nil {
curDirectory, err := os.Getwd()
if err != nil {
return "", err
}
templatePath := filepath.Join(curDirectory, templateName)
if potentialPath, err := c.tryResolve(templatePath); err != errNoValidCombination {
return potentialPath, nil
}
}
templatePath := filepath.Join(config.DefaultConfig.GetTemplateDir(), templateName)
if potentialPath, err := c.tryResolve(templatePath); err != errNoValidCombination {
return potentialPath, nil
}
return "", fmt.Errorf("no such path found: %s", templateName)
}
var errNoValidCombination = errors.New("no valid combination found")
func (c *DiskCatalog) tryResolve(fullPath string) (string, error) {
if c.templatesFS == nil {
if fileutil.FileOrFolderExists(fullPath) {
return fullPath, nil
}
} else {
if _, err := fs.Stat(c.templatesFS, fullPath); err == nil {
return fullPath, nil
}
}
return "", errNoValidCombination
}
func BackwardsCompatiblePaths(templateDir string, oldPath string) string {
newPathCallback := func(path string) string {
path = strings.TrimPrefix(path, "/")
if fileutil.FileOrFolderExists(filepath.Join(templateDir, "http", path)) {
return filepath.Join(templateDir, "http", path)
} else if strings.HasPrefix(path, "cves") && fileutil.FileOrFolderExists(filepath.Join(templateDir, "network", "cves", path)) {
return filepath.Join(templateDir, "network", "cves", path)
}
return filepath.Join(templateDir, path)
}
switch {
case fileutil.FileOrFolderExists(oldPath):
return oldPath
case filepath.IsAbs(oldPath):
tmp := strings.TrimPrefix(oldPath, templateDir)
if tmp == oldPath {
return oldPath
}
return newPathCallback(tmp)
case strings.Contains(oldPath, urlutil.SchemeSeparator):
return oldPath
case strings.Contains(oldPath, "*"):
return oldPath
default:
return newPathCallback(oldPath)
}
}