Skip to content
This repository has been archived by the owner on Nov 19, 2024. It is now read-only.

Tar files created inside the directory they are compressing are not walkable #383

Closed
drewstinnett opened this issue Aug 29, 2023 · 5 comments
Labels

Comments

@drewstinnett
Copy link
Contributor

What version of the package or command are you using?

v4.0.0-alpha.8

What are you trying to do?

I am attempting to read the table of contents information out of various compressed archives (similar to using tar -tvf file.tar). This is currently not working, if the tar was created using the current directory as it's first entry. For example:

❯ tar cvf test.tar .
a .
a ./test.tartar: ./test.tar: Can't add archive to itself

a ./1mb
a ./2mb

Even though it was tarred up to the current directory, and barfed out the warning Can't add archive to itself, I can still extract and get content listing using standard tar:

❯ tar tvf test-tar/test.tar
drwxr-xr-x  0 drews  staff       0 Aug 29 13:38 ./
-rw-r--r--  0 drews  staff 1048576 Aug 29 13:37 ./1mb
-rw-r--r--  0 drews  staff 2097152 Aug 29 13:37 ./2mb
❯ tar xvf test-tar/test.tar
x ./
x ./1mb
x ./2mb

However when I use the archiver.FileSystem type, it appears to get recursively hung on that first "./" entry, and it never reaches the next entry.

What steps did you take?

Below is the sample code I am testing:

package main

import (
	"context"
	"fmt"
	"io/fs"
	"log"
	"os"

	"github.com/mholt/archiver/v4"
)

func main() {
	if len(os.Args) != 2 {
		log.Fatal("must give an argument")
	}

	fsys, err := archiver.FileSystem(context.Background(), os.Args[1])
	if err != nil {
		log.Fatal(err)
	}
	err = fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
		fmt.Fprintf(os.Stderr, "Path: %v File: %v Dir: %v\n", path, d.Name(), d.IsDir())
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
}

What did you expect to happen, and what actually happened instead?

I expected an output like this:

❯ go run ./ ~/Desktop/good.tar
Path: . File: good.tar Dir: true
Path: ._test-tar File: ._test-tar Dir: false
Path: test-tar File: test-tar Dir: true
Path: test-tar/._1mb File: ._1mb Dir: false
Path: test-tar/._2mb File: ._2mb Dir: false
Path: test-tar/1mb File: 1mb Dir: false
Path: test-tar/2mb File: 2mb Dir: false

Instead, if the tar has the . as it's first path, it is repeated indefinitely:

❯ go run ./ ~/Desktop/bad.tar
Path: . File: bad.tar Dir: true
Path: . File: . Dir: true
Path: . File: . Dir: true
Path: . File: . Dir: true
...these are repeated forever...

How do you think this should be fixed?

I am unsure where exactly this is in the code, or how it should be fixed...it may be possible to fix this in my code that is using the library as well, however I was unsuccessful at that...any thoughts are appreciated!

Bonus: What do you use archiver for, and do you find it useful?

It's great!

@drewstinnett
Copy link
Contributor Author

I couldn't attach the .tar extension directly to the issues, but you can download both the good and bad tar files here:

https://github.com/drewstinnett/fake-tars/blob/main/bad.tar
https://github.com/drewstinnett/fake-tars/blob/main/good.tar

@drewstinnett
Copy link
Contributor Author

Playing with the code a little bit, found a fix, by adding a new function like this:

func removeSubdirDots(files []File) []File {
	ret := make([]File, 0, len(files))
	for _, item := range files {
		if item.Name() != "." {
			ret = append(ret, item)
		}
	}
	return ret
}

Then calling it in fs.go line 599.

	// always find all implicit directories
	files = fillImplicit(files)
	// Remove bogus "." entries that some tar files generate
	files = removeSubdirDots(files)

Full (but rough) version of this over here

All the tests still pass with this change 🤞

@mholt
Copy link
Owner

mholt commented Aug 30, 2023

Thank you for diving into this bug -- sorry I've been busy this week, but I will circle back around to this soon :)

@mholt mholt added the bug label Aug 30, 2023
@mholt mholt closed this as completed in e2261a1 Aug 31, 2023
@drewstinnett
Copy link
Contributor Author

Appreciate the quick resolution and help, thanks for the awesome project!

@mholt
Copy link
Owner

mholt commented Aug 31, 2023

Yeah for sure, thanks for the patch!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants