Skip to content

Commit 116d33f

Browse files
committed
jar: support unconventional jar names
Signed-off-by: RTann <[email protected]> rh-pre-commit.version: 2.3.2 rh-pre-commit.check-secrets: ENABLED
1 parent 3854c85 commit 116d33f

File tree

6 files changed

+83
-34
lines changed

6 files changed

+83
-34
lines changed

java/jar/errors.go

+2-21
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@ type localError struct {
1111
msg string
1212
}
1313

14-
// These are sentinel errors that can be used with errors.Is.
15-
var (
16-
ErrUnidentified = errors.New("unidentified jar")
17-
ErrNotAJar = errors.New("does not seem to be a jar")
18-
)
14+
// ErrNotAJar is a sentinel error that can be used with errors.Is.
15+
var ErrNotAJar = errors.New("does not seem to be a jar")
1916

2017
func (e *localError) Error() string {
2118
switch {
@@ -45,22 +42,6 @@ func archiveErr(m srcPath, err error) *localError {
4542
}
4643
}
4744

48-
type errUnidentified struct {
49-
name string
50-
}
51-
52-
func unidentified(n string) *errUnidentified {
53-
return &errUnidentified{n}
54-
}
55-
56-
func (e *errUnidentified) Is(target error) bool {
57-
return target == ErrUnidentified || target == e
58-
}
59-
60-
func (e *errUnidentified) Error() string {
61-
return fmt.Sprintf("unidentified jar: %s", e.name)
62-
}
63-
6445
type errNotAJar struct {
6546
inner error
6647
name string

java/jar/jar.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func parse(ctx context.Context, name srcPath, z *zip.Reader) ([]Info, error) {
136136
default:
137137
return nil, archiveErr(name, err)
138138
}
139-
// As a last resort, just look at the name of the jar.
139+
// Try to learn something from the name of the jar if that fails.
140140
i, err = checkName(ctx, name.Cur())
141141
switch {
142142
case errors.Is(err, nil):
@@ -148,9 +148,11 @@ func parse(ctx context.Context, name srcPath, z *zip.Reader) ([]Info, error) {
148148
default:
149149
return nil, archiveErr(name, err)
150150
}
151-
// If we haven't jumped past this point, this is almost certainly not a jar,
152-
// so return an error.
153-
return nil, mkErr("", unidentified(base))
151+
152+
// At this point, we have yet to find anything other than the file
153+
// extension which can help confirm this is, in fact, a JAR.
154+
// We accept this, and continue to search through the non-standard JAR
155+
// in case we may find any valid inner JARs.
154156

155157
Finish:
156158
// Now, we need to examine any jars bundled in this jar.
@@ -308,7 +310,6 @@ func extractInner(ctx context.Context, p srcPath, z *zip.Reader) ([]Info, error)
308310
switch {
309311
case errors.Is(err, nil):
310312
case errors.Is(err, ErrNotAJar) ||
311-
errors.Is(err, ErrUnidentified) ||
312313
errors.Is(err, errInsaneManifest):
313314
zlog.Debug(ctx).
314315
Str("member", name).

java/jar/jar_test.go

+51-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121

2222
"github.com/google/go-cmp/cmp"
23+
"github.com/google/go-cmp/cmp/cmpopts"
2324
"github.com/quay/zlog"
2425

2526
"github.com/quay/claircore/test"
@@ -70,8 +71,6 @@ func TestParse(t *testing.T) {
7071
switch {
7172
case errors.Is(err, nil):
7273
t.Log(ps)
73-
case errors.Is(err, ErrUnidentified):
74-
t.Log(err)
7574
case filepath.Base(h.Name) == "javax.inject-1.jar" && errors.Is(err, ErrNotAJar):
7675
// This is an odd one, it has no metadata.
7776
t.Log(err)
@@ -111,8 +110,6 @@ func TestWAR(t *testing.T) {
111110
for _, p := range ps {
112111
t.Log(p.String())
113112
}
114-
case errors.Is(err, ErrUnidentified):
115-
t.Error(err)
116113
default:
117114
t.Errorf("unexpected: %v", err)
118115
}
@@ -475,3 +472,53 @@ func TestManifestSectionReader(t *testing.T) {
475472
})
476473
}
477474
}
475+
476+
func TestInnerJar(t *testing.T) {
477+
name := filepath.Join("testdata", "inner", "inner.jar")
478+
rc, err := zip.OpenReader(name)
479+
if err != nil {
480+
t.Fatal(err)
481+
}
482+
t.Cleanup(func() {
483+
if err := rc.Close(); err != nil {
484+
t.Fatal(err)
485+
}
486+
})
487+
488+
ctx := zlog.Test(context.Background(), t)
489+
got, err := Parse(ctx, name, &rc.Reader)
490+
if err != nil {
491+
t.Fatal(err)
492+
}
493+
494+
if len(got) != 3 {
495+
t.Errorf("got %d entries, expected 3", len(got))
496+
}
497+
498+
// Ignore the SHA.
499+
for i := range got {
500+
got[i].SHA = nil
501+
}
502+
503+
want := []Info{
504+
{
505+
Name: "jackson-annotations",
506+
Version: "2.13.0",
507+
Source: ".",
508+
},
509+
{
510+
Name: "log4j-api",
511+
Version: "2.14",
512+
Source: ".",
513+
},
514+
{
515+
Name: "log4j",
516+
Version: "2.14.0",
517+
Source: ".",
518+
},
519+
}
520+
521+
if !cmp.Equal(got, want, cmpopts.IgnoreFields(Info{}, "SHA")) {
522+
t.Error(cmp.Diff(got, want))
523+
}
524+
}

java/jar/testdata/inner/README.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
inner.jar looks as such:
2+
3+
```
4+
inner.jar
5+
|-- META-INF/
6+
|-- MANIFEST.MF
7+
|-- BOOT-INF/
8+
|-- lib/
9+
|-- jackson-annotations-2.13.0.jar
10+
|-- META-INF/
11+
|-- MANIFEST.MF
12+
|-- log4j-api-2.14.jar
13+
|-- META-INF/
14+
|-- MANIFEST.MF
15+
|-- inner-jar/
16+
|-- META-INF/
17+
|-- MANIFEST.MF
18+
|-- log4j-2.14.0.jar
19+
|-- META-INF/
20+
|-- MANIFEST.MF
21+
```

java/jar/testdata/inner/inner.jar

1.67 KB
Binary file not shown.

java/packagescanner.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ type Scanner struct {
7171
func (*Scanner) Name() string { return "java" }
7272

7373
// Version implements scanner.VersionedScanner.
74-
func (*Scanner) Version() string { return "6" }
74+
func (*Scanner) Version() string { return "7" }
7575

7676
// Kind implements scanner.VersionedScanner.
7777
func (*Scanner) Kind() string { return "package" }
@@ -185,9 +185,8 @@ func (s *Scanner) Scan(ctx context.Context, layer *claircore.Layer) ([]*claircor
185185
infos, err := jar.Parse(ctx, n, z)
186186
switch {
187187
case err == nil:
188-
case errors.Is(err, jar.ErrUnidentified) || errors.Is(err, jar.ErrNotAJar):
189-
// If there's an error that's one of the "known" reasons (e.g. not a
190-
// read error or a malformed file), just log it and continue on.
188+
case errors.Is(err, jar.ErrNotAJar):
189+
// Could not prove this is really a jar. Skip it and move on.
191190
zlog.Info(ctx).
192191
AnErr("reason", err).
193192
Msg("skipping jar")

0 commit comments

Comments
 (0)