Skip to content

Commit 9cfaf8e

Browse files
committed
fix: abstract out cpio operations to helper function
This lets us defer the close operation to the end of the helper function and not try to do the closes in all the early exit operations of the loop. v2: drop cyclometric complexity lint silencing comment Signed-off-by: Steve Beattie <steve.beattie@chainguard.dev>
1 parent 42306d1 commit 9cfaf8e

1 file changed

Lines changed: 43 additions & 39 deletions

File tree

pkg/archive/rpm.go

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,48 @@ import (
2121
"github.com/ulikunitz/xz"
2222
)
2323

24+
// extractFileFromCPIO extracts a single file from a CPIO archive.
25+
func extractFileFromCPIO(ctx context.Context, cr *cpio.Reader, target string, buf []byte) error {
26+
if err := os.MkdirAll(filepath.Dir(target), 0o700); err != nil {
27+
return fmt.Errorf("failed to create parent directory: %w", err)
28+
}
29+
30+
out, err := os.OpenFile(target, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600)
31+
if err != nil {
32+
return fmt.Errorf("failed to create file: %w", err)
33+
}
34+
defer out.Close()
35+
36+
var written int64
37+
for {
38+
if written > 0 && written%file.ExtractBuffer == 0 && ctx.Err() != nil {
39+
return ctx.Err()
40+
}
41+
42+
n, err := cr.Read(buf)
43+
if n > 0 {
44+
written += int64(n)
45+
if written > file.MaxBytes {
46+
return fmt.Errorf("file exceeds maximum allowed size (%d bytes): %s", file.MaxBytes, target)
47+
}
48+
if _, writeErr := out.Write(buf[:n]); writeErr != nil {
49+
return fmt.Errorf("failed to write file contents: %w", writeErr)
50+
}
51+
}
52+
53+
if errors.Is(err, io.EOF) {
54+
break
55+
}
56+
57+
if err != nil {
58+
return fmt.Errorf("failed to read file contents: %w", err)
59+
}
60+
}
61+
62+
return nil
63+
}
64+
2465
// extractRPM extracts .rpm packages.
25-
//
26-
//nolint:cyclop // ignore complexity of 40
2766
func ExtractRPM(ctx context.Context, d, f string) error {
2867
if ctx.Err() != nil {
2968
return ctx.Err()
@@ -142,43 +181,8 @@ func ExtractRPM(ctx context.Context, d, f string) error {
142181
continue
143182
}
144183

145-
if err := os.MkdirAll(filepath.Dir(target), 0o700); err != nil {
146-
return fmt.Errorf("failed to create parent directory: %w", err)
147-
}
148-
149-
out, err := os.OpenFile(target, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600)
150-
if err != nil {
151-
return fmt.Errorf("failed to create file: %w", err)
152-
}
153-
154-
var written int64
155-
for {
156-
if written > 0 && written%file.ExtractBuffer == 0 && ctx.Err() != nil {
157-
return ctx.Err()
158-
}
159-
160-
n, err := cr.Read(buf)
161-
if n > 0 {
162-
written += int64(n)
163-
if written > file.MaxBytes {
164-
return fmt.Errorf("file exceeds maximum allowed size (%d bytes): %s", file.MaxBytes, target)
165-
}
166-
if _, writeErr := out.Write(buf[:n]); writeErr != nil {
167-
return fmt.Errorf("failed to write file contents: %w", writeErr)
168-
}
169-
}
170-
171-
if errors.Is(err, io.EOF) {
172-
break
173-
}
174-
175-
if err != nil {
176-
return fmt.Errorf("failed to read file contents: %w", err)
177-
}
178-
}
179-
180-
if err := out.Close(); err != nil {
181-
return fmt.Errorf("failed to close file: %w", err)
184+
if err := extractFileFromCPIO(ctx, cr, target, buf); err != nil {
185+
return err
182186
}
183187
}
184188

0 commit comments

Comments
 (0)