Skip to content

Commit 620eea4

Browse files
fix: only parse pragma solidity version (closes #246) (#309)
1 parent 083f2bc commit 620eea4

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

solc.go

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import (
1313
"strings"
1414
)
1515

16-
var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`)
16+
var pragmaRegexp = regexp.MustCompile(`(?m)^\s*pragma\s+solidity\s+([^;]+);`)
17+
1718

1819
// Contract contains information about a compiled contract, alongside its code and runtime code.
1920
type Contract struct {
@@ -88,27 +89,38 @@ func (s *Solidity) makeArgs() ([]string, error) {
8889
return args, nil
8990
}
9091

91-
// SolidityVersion runs solc and parses its version output.
9292
func SolidityVersion(source string) (*Solidity, error) {
93-
var err error
94-
matches := versionRegexp.FindStringSubmatch(source)
95-
if len(matches) != 4 {
96-
return nil, fmt.Errorf("can't parse solc version %q", source)
97-
}
98-
s := &Solidity{Path: "docker"}
99-
if s.Major, err = strconv.Atoi(matches[1]); err != nil {
100-
return nil, err
101-
}
102-
if s.Minor, err = strconv.Atoi(matches[2]); err != nil {
103-
return nil, err
104-
}
105-
if s.Patch, err = strconv.Atoi(matches[3]); err != nil {
106-
return nil, err
107-
}
108-
s.Version = strconv.Itoa(s.Major) + "." + strconv.Itoa(s.Minor) + "." + strconv.Itoa(s.Patch)
109-
return s, nil
93+
var err error
94+
// Extract pragma solidity version from source
95+
matches := pragmaRegexp.FindStringSubmatch(source)
96+
if len(matches) < 2 {
97+
return nil, fmt.Errorf("can't find pragma solidity in %q", source)
98+
}
99+
versionConstraint := strings.TrimSpace(matches[1])
100+
101+
// Grab the first explicit version number like 0.8.0
102+
versionNumber := regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`).FindString(versionConstraint)
103+
if versionNumber == "" {
104+
return nil, fmt.Errorf("invalid pragma solidity version: %q", versionConstraint)
105+
}
106+
107+
parts := strings.Split(versionNumber, ".")
108+
s := &Solidity{Path: "docker"}
109+
110+
if s.Major, err = strconv.Atoi(parts[0]); err != nil {
111+
return nil, err
112+
}
113+
if s.Minor, err = strconv.Atoi(parts[1]); err != nil {
114+
return nil, err
115+
}
116+
if s.Patch, err = strconv.Atoi(parts[2]); err != nil {
117+
return nil, err
118+
}
119+
s.Version = versionNumber
120+
return s, nil
110121
}
111122

123+
112124
// CompileSolidityString builds and returns all the contracts contained within a source string.
113125
func CompileSolidityString(ctx context.Context, source, solcVersion, evmVersion string, optimize bool) (map[string]*Contract, error) {
114126
var s *Solidity

0 commit comments

Comments
 (0)