Signed-off-by: liang chenye <liangchenye@huawei.com>pull/175/head
parent
f1498b1d17
commit
cb42892716
@ -1,76 +0,0 @@
|
||||
// Copyright 2016 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package nodejs
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type operVersion struct {
|
||||
Oper string
|
||||
Version string
|
||||
}
|
||||
|
||||
type ovState string
|
||||
|
||||
const (
|
||||
ovStateInit ovState = "init"
|
||||
ovStateOper ovState = "operation"
|
||||
ovStateVersion ovState = "version"
|
||||
)
|
||||
|
||||
func isOper(ch rune) bool {
|
||||
return ch == '>' || ch == '<' || ch == '='
|
||||
}
|
||||
|
||||
func getOperVersions(content string) (ovs []operVersion) {
|
||||
state := ovStateInit
|
||||
begin := 0
|
||||
var ov operVersion
|
||||
for i, ch := range content {
|
||||
if unicode.IsSpace(ch) {
|
||||
continue
|
||||
}
|
||||
switch state {
|
||||
case ovStateInit:
|
||||
if isOper(ch) {
|
||||
state = ovStateOper
|
||||
begin = i
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case ovStateOper:
|
||||
if !isOper(ch) {
|
||||
state = ovStateVersion
|
||||
ov.Oper = strings.TrimSpace(content[begin:i])
|
||||
begin = i
|
||||
}
|
||||
case ovStateVersion:
|
||||
if isOper(ch) {
|
||||
state = ovStateOper
|
||||
ov.Version = strings.TrimSpace(content[begin:i])
|
||||
ovs = append(ovs, ov)
|
||||
begin = i
|
||||
}
|
||||
}
|
||||
}
|
||||
if state == ovStateVersion {
|
||||
ov.Version = strings.TrimSpace(content[begin:len(content)])
|
||||
ovs = append(ovs, ov)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
// Copyright 2016 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package nodejs
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNodeVersion(t *testing.T) {
|
||||
invalid_version := "3.1.3 < 4.0.0 || >= "
|
||||
versions := strings.Split(invalid_version, "||")
|
||||
for _, version := range versions {
|
||||
ovs := getOperVersions(version)
|
||||
assert.Len(t, ovs, 0)
|
||||
}
|
||||
|
||||
valid_version := ">=3.1.3 < 4.0.0 || >=4.1.1"
|
||||
versions = strings.Split(valid_version, "||")
|
||||
for _, version := range versions {
|
||||
if strings.Contains(version, "4.1.1") {
|
||||
ovs := getOperVersions(version)
|
||||
assert.Len(t, ovs, 1)
|
||||
assert.Equal(t, ">=", ovs[0].Oper)
|
||||
assert.Equal(t, "4.1.1", ovs[0].Version)
|
||||
} else {
|
||||
ovs := getOperVersions(version)
|
||||
assert.Len(t, ovs, 2)
|
||||
|
||||
for _, ov := range ovs {
|
||||
if ov.Oper == ">=" {
|
||||
assert.Equal(t, "3.1.3", ov.Version)
|
||||
} else if ov.Oper == "<" {
|
||||
assert.Equal(t, "4.0.0", ov.Version)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,237 @@
|
||||
// Copyright 2016 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type Operator string
|
||||
|
||||
const (
|
||||
OpNotEqual Operator = "!="
|
||||
OpLessThan Operator = "<"
|
||||
OpLessEqual Operator = "<="
|
||||
OpEqualTo Operator = "=="
|
||||
OpGreaterEqual Operator = ">="
|
||||
OpGreaterThan Operator = ">"
|
||||
)
|
||||
|
||||
type FixedInVersions struct {
|
||||
fivs [][]operVersion
|
||||
}
|
||||
|
||||
type operVersion struct {
|
||||
oper Operator
|
||||
version Version
|
||||
}
|
||||
|
||||
type ovState string
|
||||
|
||||
const (
|
||||
ovStateInit ovState = "init"
|
||||
ovStateOper ovState = "operation"
|
||||
ovStateVersion ovState = "version"
|
||||
)
|
||||
|
||||
func isOperChar(ch rune) bool {
|
||||
return ch == '>' || ch == '<' || ch == '='
|
||||
}
|
||||
|
||||
func getOperator(str string) (oper Operator, error error) {
|
||||
switch str {
|
||||
case "!=":
|
||||
case "<":
|
||||
case "<=":
|
||||
case "==":
|
||||
case ">=":
|
||||
case ">":
|
||||
default:
|
||||
return oper, fmt.Errorf("Invalid operator: '%s'", str)
|
||||
}
|
||||
|
||||
return Operator(str), nil
|
||||
}
|
||||
|
||||
func getFixedinVersion(content string) (ovs []operVersion, err error) {
|
||||
state := ovStateInit
|
||||
begin := 0
|
||||
var ov operVersion
|
||||
for i, ch := range content {
|
||||
if unicode.IsSpace(ch) {
|
||||
continue
|
||||
}
|
||||
switch state {
|
||||
case ovStateInit:
|
||||
if isOperChar(ch) {
|
||||
state = ovStateOper
|
||||
} else {
|
||||
// Default to '>='
|
||||
ov.oper = OpGreaterEqual
|
||||
state = ovStateVersion
|
||||
}
|
||||
begin = i
|
||||
case ovStateOper:
|
||||
if !isOperChar(ch) {
|
||||
state = ovStateVersion
|
||||
if ov.oper, err = getOperator(strings.TrimSpace(content[begin:i])); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
begin = i
|
||||
}
|
||||
case ovStateVersion:
|
||||
if isOperChar(ch) {
|
||||
state = ovStateOper
|
||||
if ov.version, err = NewVersion(strings.TrimSpace(content[begin:i])); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ovs = append(ovs, ov)
|
||||
begin = i
|
||||
}
|
||||
}
|
||||
}
|
||||
if state == ovStateVersion {
|
||||
if ov.version, err = NewVersion(strings.TrimSpace(content[begin:len(content)])); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ovs = append(ovs, ov)
|
||||
}
|
||||
|
||||
if len(ovs) == 0 {
|
||||
err = fmt.Errorf("Failed to parse '%s'", content)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (ov operVersion) patched(version Version) bool {
|
||||
val := version.Compare(ov.version)
|
||||
switch ov.oper {
|
||||
case OpNotEqual:
|
||||
return val != 0
|
||||
case OpLessThan:
|
||||
return val < 0
|
||||
case OpLessEqual:
|
||||
return val <= 0
|
||||
case OpEqualTo:
|
||||
return val == 0
|
||||
case OpGreaterEqual:
|
||||
return val >= 0
|
||||
case OpGreaterThan:
|
||||
return val > 0
|
||||
}
|
||||
|
||||
//Cannot get here
|
||||
return false
|
||||
}
|
||||
|
||||
// String returns the string representation of a FixedInVersions
|
||||
func (fivs FixedInVersions) String() (s string) {
|
||||
firstFiv := false
|
||||
for _, fiv := range fivs.fivs {
|
||||
if !firstFiv {
|
||||
firstFiv = true
|
||||
} else {
|
||||
s += " || "
|
||||
}
|
||||
|
||||
firstOV := false
|
||||
for _, ov := range fiv {
|
||||
if !firstOV {
|
||||
firstOV = true
|
||||
} else {
|
||||
s += " "
|
||||
}
|
||||
s += string(ov.oper) + ov.version.String()
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (fivs FixedInVersions) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(fivs.String())
|
||||
}
|
||||
|
||||
func (fivs *FixedInVersions) UnmarshalJSON(b []byte) (err error) {
|
||||
var str string
|
||||
json.Unmarshal(b, &str)
|
||||
vp := NewFixedInVersionsUnsafe(str)
|
||||
*fivs = vp
|
||||
return
|
||||
}
|
||||
|
||||
func (fivs *FixedInVersions) Scan(value interface{}) (err error) {
|
||||
val, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New("could not scan a Version from a non-string input")
|
||||
}
|
||||
*fivs, err = NewFixedInVersions(string(val))
|
||||
return
|
||||
}
|
||||
|
||||
func (fivs *FixedInVersions) Value() (driver.Value, error) {
|
||||
return fivs.String(), nil
|
||||
}
|
||||
|
||||
func (fivs FixedInVersions) Affected(version Version) bool {
|
||||
for _, fiv := range fivs.fivs {
|
||||
affected := false
|
||||
for _, ov := range fiv {
|
||||
if !ov.patched(version) {
|
||||
affected = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !affected {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func NewFixedInVersionsFromOV(oper Operator, version Version) FixedInVersions {
|
||||
var fivs FixedInVersions
|
||||
var fiv []operVersion
|
||||
|
||||
fiv = append(fiv, operVersion{oper, version})
|
||||
fivs.fivs = append(fivs.fivs, fiv)
|
||||
|
||||
return fivs
|
||||
}
|
||||
|
||||
func NewFixedInVersions(str string) (FixedInVersions, error) {
|
||||
var fivs FixedInVersions
|
||||
for _, ovsStr := range strings.Split(str, "||") {
|
||||
if fiv, err := getFixedinVersion(ovsStr); err == nil {
|
||||
fivs.fivs = append(fivs.fivs, fiv)
|
||||
} else {
|
||||
return fivs, err
|
||||
}
|
||||
}
|
||||
|
||||
return fivs, nil
|
||||
}
|
||||
|
||||
func NewFixedInVersionsUnsafe(str string) FixedInVersions {
|
||||
fivs, _ := NewFixedInVersions(str)
|
||||
return fivs
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
// Copyright 2016 clair authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFixedInVersions(t *testing.T) {
|
||||
invalid_version := "3.1.3 < 4.0.0 || >= "
|
||||
fivs, err := NewFixedInVersions(invalid_version)
|
||||
assert.Error(t, err, "Failed to parse '%s'", ">=")
|
||||
|
||||
invalid_version = "3.1.3 < ab.0.0 || >= "
|
||||
fivs, err = NewFixedInVersions(invalid_version)
|
||||
assert.Error(t, err, "Failed to parse '%s'", ">=")
|
||||
|
||||
valid_version := "3.1.3"
|
||||
fivs, err = NewFixedInVersions(valid_version)
|
||||
assert.Nil(t, err)
|
||||
|
||||
valid_version = ">=3.1.3 <4.0.0 || >=4.1.1"
|
||||
fivs, err = NewFixedInVersions(valid_version)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, strings.Replace(fivs.String(), " ", "", -1), strings.Replace(valid_version, " ", "", -1))
|
||||
|
||||
for _, fiv := range fivs.fivs {
|
||||
if len(fiv) == 1 {
|
||||
assert.Equal(t, OpGreaterEqual, fiv[0].oper)
|
||||
assert.Equal(t, NewVersionUnsafe("4.1.1"), fiv[0].version)
|
||||
} else {
|
||||
for _, ov := range fiv {
|
||||
if ov.oper == OpGreaterEqual {
|
||||
assert.Equal(t, NewVersionUnsafe("3.1.3"), ov.version)
|
||||
} else if ov.oper == OpLessThan {
|
||||
assert.Equal(t, NewVersionUnsafe("4.0.0"), ov.version)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
version string
|
||||
expected bool
|
||||
}{
|
||||
{"4.2", false},
|
||||
{"4.0.0", true},
|
||||
{"3.1.3", false},
|
||||
{"3.1.2", true},
|
||||
}
|
||||
for _, c := range cases {
|
||||
assert.Equal(t, fivs.Affected(NewVersionUnsafe(c.version)), c.expected)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue