@@ -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
2766func 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