Skip to content

Commit

Permalink
fixed some issues and improved code - groovy ready except notes
Browse files Browse the repository at this point in the history
  • Loading branch information
eranturgeman committed Sep 12, 2023
1 parent 379a046 commit 9458852
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 28 deletions.
102 changes: 76 additions & 26 deletions packagehandlers/gradlepackagehandler.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package packagehandlers

import (
"errors"
"fmt"
fileutils "github.com/jfrog/build-info-go/utils"
"github.com/jfrog/frogbot/packagehandlers/resources"
"github.com/jfrog/frogbot/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"io/fs"
"math"
"os"
"path/filepath"
Expand All @@ -15,11 +18,11 @@ import (
)

const (
groovyFileType = "groovy"
kotlinFileType = "kotlin"
groovyBuildFile = "build.gradle"
kotlinBuildFile = "build.gradle.kts"
unknownRowType = "unknown"
groovyFileType = "groovy"
kotlinFileType = "kotlin"
groovyBuildFileSuffix = ".gradle"
kotlinBuildFileSuffix = ".gradle.kts"
unknownRowType = "unknown"
)

type GradlePackageHandler struct {
Expand All @@ -28,13 +31,14 @@ type GradlePackageHandler struct {

type buildFileData struct {
fileType string
fileContent []string //needed
filePath string //needed
fileContent []string //needed

Check failure on line 34 in packagehandlers/gradlepackagehandler.go

View workflow job for this annotation

GitHub Actions / Static-Check

commentFormatting: put a space between `//` and comment text (gocritic)
filePath string //needed

Check failure on line 35 in packagehandlers/gradlepackagehandler.go

View workflow job for this annotation

GitHub Actions / Static-Check

commentFormatting: put a space between `//` and comment text (gocritic)
filePerm os.FileMode //needed
}

var buildFileToType = map[string]string{
"build.gradle": groovyFileType,
"build.gradle.kts": kotlinFileType,
".gradle": groovyFileType,
".gradle.kts": kotlinFileType,
}

func (gph *GradlePackageHandler) UpdateDependency(vulnDetails *utils.VulnerabilityDetails) error {
Expand All @@ -50,6 +54,14 @@ func (gph *GradlePackageHandler) UpdateDependency(vulnDetails *utils.Vulnerabili
}

func (gph *GradlePackageHandler) updateDirectDependency(vulnDetails *utils.VulnerabilityDetails) (err error) {
if unsupportedType, isUnsupported := isUnsupportedVulnVersion(vulnDetails.ImpactedDependencyVersion); isUnsupported {
log.Warn("frogbot currently doesn't support fixing %s: %s %s", unsupportedType, vulnDetails.ImpactedDependencyName, vulnDetails.ImpactedDependencyVersion)
return &utils.ErrUnsupportedFix{
PackageName: vulnDetails.ImpactedDependencyName,
FixedVersion: vulnDetails.SuggestedFixedVersion,
ErrorType: utils.UnsupportedGradleDependencyVersion,
}
}
// get all build files
buildFiles, err := readBuildFiles()
if err != nil {
Expand All @@ -73,41 +85,58 @@ func writeUpdatedBuildFile(buildFile buildFileData) (err error) {
bytesSlice = append(bytesSlice, []byte(row+"\n")...)
}
bytesSlice = bytesSlice[:len(bytesSlice)-1]
err = os.WriteFile(buildFile.filePath, bytesSlice, 0644)
err = os.WriteFile(buildFile.filePath, bytesSlice, buildFile.filePerm)
if err != nil {
err = fmt.Errorf("couldn't write fixes to file '%s': %q", buildFile.filePath, err)
}
return
}

func readBuildFiles() (buildFiles []buildFileData, err error) {
dirContent, err := os.ReadDir(".")
if err != nil {
err = fmt.Errorf("couldn't read working directory: %q", err)
return
}
wd, err := os.Getwd()
if err != nil {
return
}
err = filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
err = fmt.Errorf("error has occured when trying to access or traverse the files system")
return err
}

if d.Type().IsRegular() && (filepath.Ext(path) == groovyBuildFileSuffix || filepath.Ext(path) == kotlinBuildFileSuffix) {
fileName := "build" + filepath.Ext(path)

//TODO check if this process is working for multi-dir and can detect build files not in main dir
for _, dirEntry := range dirContent {
fileName := dirEntry.Name()
if fileName == groovyBuildFile || fileName == kotlinBuildFile {
wd, internalErr := os.Getwd()
if internalErr != nil {
return errors.Join(internalErr, err)
}

// Read file's content
var fileContent []string
fileContent, err = fileutils.ReadNLines(fileName, math.MaxInt)
if err != nil {
err = fmt.Errorf("couldn't read %s file: %q", fileName, err)
return
return fmt.Errorf("couldn't read %s file: %q", fileName, err)
}

// Get file permissions
fileInfo, statErr := os.Stat(path)
if statErr != nil {
return fmt.Errorf("couldn't get file info for %s: %q", path, statErr)
}
filePerm := fileInfo.Mode()

buildFiles = append(buildFiles, buildFileData{
fileType: buildFileToType[fileName],
fileContent: fileContent,
filePath: filepath.Join(wd, fileName),
filePerm: filePerm,
})

}
return err
})

if err != nil {
err = fmt.Errorf("failed to read project's directory content: %q", err)
return
}

if len(buildFiles) == 0 {
err = errorutils.CheckErrorf("couldn't detect any build file in the project")
}
Expand Down Expand Up @@ -179,7 +208,7 @@ func isInsideDependenciesScope(rowContent string, insideDependenciesScope *bool,
// detectVulnerableRowType returns the row's type according to predefined patterns defined by RegexpNameToPattern in ./resources/gradlefixhelper.go
// if there is no match for some row with any known type, the row's type will be set to 'unknown'
func detectVulnerableRowType(vulnerableRow string, patternsCompilers map[string][]*regexp.Regexp) string {
rowToCheck := strings.TrimLeft(vulnerableRow, " ")
rowToCheck := strings.TrimSpace(vulnerableRow)
for patternName, regexpCompilers := range patternsCompilers {
for _, compiler := range regexpCompilers {
if compiler.FindString(rowToCheck) != "" {
Expand Down Expand Up @@ -219,3 +248,24 @@ func getPattenCompilersForVulnerability(vulnDetails *utils.VulnerabilityDetails)
}
return
}

func isUnsupportedVulnVersion(impactedVersion string) (string, bool) {
// capture dynamic dep | V
// capture range | V
// capture latest.release | V

// TODO should fix those two or reject?
// capture var version
// capture property version - something that directs to take the value from properties.gradle (starts with $)

if strings.Contains(impactedVersion, "+") {
return "dynamic dependency version", true
}
if strings.Contains(impactedVersion, "latest.release") {
return "latest release version", true
}
if strings.Contains(impactedVersion, "[") || strings.Contains(impactedVersion, "(") {
return "range version", true
}
return "", false
}
6 changes: 4 additions & 2 deletions packagehandlers/resources/gradlefixhelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (

// TODO case: no version at the end
// TODO case: map with newline in the middle
// TODO case: dynamic version

type VulnRowData struct {
Content string
Expand All @@ -24,7 +25,7 @@ type VulnRowData struct {
}

var RegexpNameToPattern = map[string][]string{
"directWithVersion": {directMapWithVersionRegexp, directStringWithVersionRegexp},
"directStaticVersion": {directMapWithVersionRegexp, directStringWithVersionRegexp},
}

type VulnerableRowFixer interface {
Expand All @@ -34,8 +35,9 @@ type VulnerableRowFixer interface {
// GetFixerByRowType returns suitable fixer object for the row according to the row's type.
// The known types can be found in RegexpNameToPattern map
func GetFixerByRowType(rowData VulnRowData, rowNumberInFile int) (VulnerableRowFixer, error) {
// TODO put all in ENUM
switch rowData.RowType {
case "directWithVersion":
case "directStaticVersion":
return &DirectRowFixer{CommonVulnerableRowFixer{
rowData: rowData,
rowNumberInFile: rowNumberInFile,
Expand Down
1 change: 1 addition & 0 deletions utils/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,5 @@ type UnsupportedErrorType string
const (
IndirectDependencyFixNotSupported UnsupportedErrorType = "IndirectDependencyFixNotSupported"
BuildToolsDependencyFixNotSupported UnsupportedErrorType = "BuildToolsDependencyFixNotSupported"
UnsupportedGradleDependencyVersion UnsupportedErrorType = "UnsupportedGradleDependencyVersion"
)

0 comments on commit 9458852

Please sign in to comment.