Skip to content

Commit

Permalink
Fixes a bug where buildpack_dependency's Update(..) method will upd…
Browse files Browse the repository at this point in the history
…ate the wrong dependencies

Prior to this PR, the version number was not considered when updating the CPEs and PURL. If for example, you have two different major version branches that you are including in buildpack.toml, such as Java 11 and Java 17, prior to this PR trying to update the version of Java 11 could result in the CPE & PURL for both Java 11 and Java 17 being updated.

This PR adds tests to replicate the case where depenencies that don't match the version pattern are having their CPE/PURL updated incorrectly. It also addresses the issue by only modifying the CPE & PURL if the version pattern matches, which is the same criteria applied for updating the URL/SHA/VERSION.

Signed-off-by: Daniel Mikusa <[email protected]>
  • Loading branch information
Daniel Mikusa committed Dec 7, 2021
1 parent 977d0ed commit 113368b
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 27 deletions.
47 changes: 20 additions & 27 deletions carton/buildpack_dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,36 +152,29 @@ func (b BuildpackDependency) Update(options ...Option) {
dep["version"] = b.Version
dep["uri"] = b.URI
dep["sha256"] = b.SHA256
}

purlUnwrapped, found := dep["purl"]
if !found {
continue
}

purl, ok := purlUnwrapped.(string)
if !ok {
continue
}
dep["purl"] = purlExp.ReplaceAllString(purl, b.PURL)

cpesUnwrapped, found := dep["cpes"]
if !found {
continue
}

cpes, ok := cpesUnwrapped.([]interface{})
if !ok {
continue
}

for i := 0; i < len(cpes); i++ {
cpe, ok := cpes[i].(string)
if !ok {
continue
purlUnwrapped, found := dep["purl"]
if found {
purl, ok := purlUnwrapped.(string)
if ok {
dep["purl"] = purlExp.ReplaceAllString(purl, b.PURL)
}
}

cpes[i] = cpeExp.ReplaceAllString(cpe, b.CPE)
cpesUnwrapped, found := dep["cpes"]
if found {
cpes, ok := cpesUnwrapped.([]interface{})
if ok {
for i := 0; i < len(cpes); i++ {
cpe, ok := cpes[i].(string)
if !ok {
continue
}

cpes[i] = cpeExp.ReplaceAllString(cpe, b.CPE)
}
}
}
}
}
}
Expand Down
219 changes: 219 additions & 0 deletions carton/buildpack_dependency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,225 @@ cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-2:patch2:*:*:*:*:*:*
`))
})

it("updates multiple dependencies with different versions", func() {
Expect(ioutil.WriteFile(path, []byte(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-1"
uri = "test-uri-1"
sha256 = "test-sha256-1"
stacks = [ "test-stack" ]
purl = "pkg:generic/test-jre@different-version-1?arch=amd64"
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-1:patch1:*:*:*:*:*:*:*"]
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-2"
uri = "test-uri-2"
sha256 = "test-sha256-2"
stacks = [ "test-stack" ]
purl = "pkg:generic/test-jre@different-version-2?arch=amd64"
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-2:patch2:*:*:*:*:*:*:*"]
`), 0644)).To(Succeed())

d := carton.BuildpackDependency{
BuildpackPath: path,
ID: "test-id",
SHA256: "test-sha256-3",
URI: "test-uri-3",
Version: "test-version-3",
VersionPattern: `test-version-1`,
PURL: "different-version-3",
PURLPattern: `different-version-[\d]`,
CPE: "test-version-3:patch3",
CPEPattern: `test-version-[\d]:patch[\d]`,
}

d.Update(carton.WithExitHandler(exitHandler))

Expect(ioutil.ReadFile(path)).To(internal.MatchTOML(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-3"
uri = "test-uri-3"
sha256 = "test-sha256-3"
stacks = [ "test-stack" ]
purl = "pkg:generic/test-jre@different-version-3?arch=amd64"
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-3:patch3:*:*:*:*:*:*:*"]
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-2"
uri = "test-uri-2"
sha256 = "test-sha256-2"
stacks = [ "test-stack" ]
purl = "pkg:generic/test-jre@different-version-2?arch=amd64"
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-2:patch2:*:*:*:*:*:*:*"]
`))
})

it("updates dependency with missing purl, still updates cpe", func() {
Expect(ioutil.WriteFile(path, []byte(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-1"
uri = "test-uri-1"
sha256 = "test-sha256-1"
stacks = [ "test-stack" ]
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-1:patch1:*:*:*:*:*:*:*"]
`), 0644)).To(Succeed())

d := carton.BuildpackDependency{
BuildpackPath: path,
ID: "test-id",
SHA256: "test-sha256-2",
URI: "test-uri-2",
Version: "test-version-2",
VersionPattern: `test-version-[\d]`,
PURL: "different-version-2",
PURLPattern: `different-version-[\d]`,
CPE: "test-version-2:patch2",
CPEPattern: `test-version-[\d]:patch[\d]`,
}

d.Update(carton.WithExitHandler(exitHandler))

Expect(ioutil.ReadFile(path)).To(internal.MatchTOML(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]id = "test-id"
name = "Test Name"
version = "test-version-2"
uri = "test-uri-2"
sha256 = "test-sha256-2"
stacks = [ "test-stack" ]
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-2:patch2:*:*:*:*:*:*:*"]
`))
})

it("updates dependency with invalid purl, still updates cpe", func() {
Expect(ioutil.WriteFile(path, []byte(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-1"
uri = "test-uri-1"
sha256 = "test-sha256-1"
stacks = [ "test-stack" ]
purl = 1234
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-1:patch1:*:*:*:*:*:*:*"]
`), 0644)).To(Succeed())

d := carton.BuildpackDependency{
BuildpackPath: path,
ID: "test-id",
SHA256: "test-sha256-2",
URI: "test-uri-2",
Version: "test-version-2",
VersionPattern: `test-version-[\d]`,
PURL: "different-version-2",
PURLPattern: `different-version-[\d]`,
CPE: "test-version-2:patch2",
CPEPattern: `test-version-[\d]:patch[\d]`,
}

d.Update(carton.WithExitHandler(exitHandler))

Expect(ioutil.ReadFile(path)).To(internal.MatchTOML(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]id = "test-id"
name = "Test Name"
version = "test-version-2"
uri = "test-uri-2"
sha256 = "test-sha256-2"
stacks = [ "test-stack" ]
purl = 1234
cpes = ["cpe:2.3:a:test-vendor:test-product:test-version-2:patch2:*:*:*:*:*:*:*"]
`))
})

it("updates dependency with invalid cpe, still updates purl", func() {
Expect(ioutil.WriteFile(path, []byte(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]
id = "test-id"
name = "Test Name"
version = "test-version-1"
uri = "test-uri-1"
sha256 = "test-sha256-1"
stacks = [ "test-stack" ]
purl = "pkg:generic/test-jre@different-version-1?arch=amd64"
cpes = 1234
`), 0644)).To(Succeed())

d := carton.BuildpackDependency{
BuildpackPath: path,
ID: "test-id",
SHA256: "test-sha256-2",
URI: "test-uri-2",
Version: "test-version-2",
VersionPattern: `test-version-[\d]`,
PURL: "different-version-2",
PURLPattern: `different-version-[\d]`,
CPE: "test-version-2:patch2",
CPEPattern: `test-version-[\d]:patch[\d]`,
}

d.Update(carton.WithExitHandler(exitHandler))

Expect(ioutil.ReadFile(path)).To(internal.MatchTOML(`api = "0.7"
[buildpack]
id = "some-buildpack"
name = "Some Buildpack"
version = "1.2.3"
[[metadata.dependencies]]id = "test-id"
name = "Test Name"
version = "test-version-2"
uri = "test-uri-2"
sha256 = "test-sha256-2"
stacks = [ "test-stack" ]
purl = "pkg:generic/test-jre@different-version-2?arch=amd64"
cpes = 1234
`))
})

it("updates indented dependency", func() {
Expect(ioutil.WriteFile(path, []byte(`# it should preserve
# these comments
Expand Down

0 comments on commit 113368b

Please sign in to comment.