Compare commits

..

6 Commits

Author SHA1 Message Date
Belac Darkstorm a015b16293 Clean path before checking if valid. 2022-10-24 03:17:55 -05:00
Caleb Gardner 327781d86e Fixed issues with fragments 2022-08-26 12:11:27 -05:00
Caleb Gardner 4efd2ee49d Merge pull request #16 from tri-adam/0.6.0-fixes
v0.6.0 fixes
2022-08-26 11:44:16 -05:00
Caleb Gardner 392193993c Added single file test 2022-08-26 11:43:46 -05:00
Adam Hughes 2230a449ec fix: use fs interfaces in type assertions
Previous code would panic due to invalid type assertions (presumably due
to change of type returned by func Sub). Switching to relevant fs
interface types fixes the issue and should work going forward, even if
the type is changed.

Signed-off-by: Adam Hughes <9903835+tri-adam@users.noreply.github.com>
2022-08-26 15:10:51 +00:00
Adam Hughes 0e50efea64 fix: use correct count when reading fragments
Signed-off-by: Adam Hughes <9903835+tri-adam@users.noreply.github.com>
2022-08-26 15:00:00 +00:00
6 changed files with 107 additions and 57 deletions
+2 -2
View File
@@ -9,7 +9,7 @@ import (
type fileInit struct { type fileInit struct {
BlockStart uint32 BlockStart uint32
FragInd uint32 FragInd uint32
Offset uint32 FragOffset uint32
Size uint32 Size uint32
} }
@@ -24,7 +24,7 @@ type eFileInit struct {
Sparse uint64 Sparse uint64
LinkCount uint32 LinkCount uint32
FragInd uint32 FragInd uint32
Offset uint32 FragOffset uint32
XattrInd uint32 XattrInd uint32
} }
+4 -4
View File
@@ -96,20 +96,20 @@ func NewReader(r io.ReaderAt) (*Reader, error) {
return nil, err return nil, err
} }
} else { } else {
toRead := squash.s.IdCount toRead := squash.s.FragCount
var curRead uint16 var curRead uint32
var tmp []fragEntry var tmp []fragEntry
var rdr *metadata.Reader var rdr *metadata.Reader
var offset int var offset int
for i := range fragOffsets { for i := range fragOffsets {
curRead = uint16(math.Min(512, float64(toRead))) curRead = uint32(math.Min(512, float64(toRead)))
tmp = make([]fragEntry, curRead) tmp = make([]fragEntry, curRead)
rdr = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[i])), squash.d) rdr = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[i])), squash.d)
err = binary.Read(rdr, binary.LittleEndian, &tmp) err = binary.Read(rdr, binary.LittleEndian, &tmp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset = int(squash.s.IdCount - toRead) offset = int(squash.s.FragCount - toRead)
for i := range tmp { for i := range tmp {
squash.fragEntries[offset+i] = tmp[i] squash.fragEntries[offset+i] = tmp[i]
} }
+1 -1
View File
@@ -220,13 +220,13 @@ func (f File) ExtractWithOptions(folder string, op ExtractionOptions) error {
func (f File) realExtract(folder string, op ExtractionOptions) error { func (f File) realExtract(folder string, op ExtractionOptions) error {
err := os.MkdirAll(folder, op.FolderPerm) err := os.MkdirAll(folder, op.FolderPerm)
folder = filepath.Clean(folder)
if err != nil && !os.IsExist(err) { if err != nil && !os.IsExist(err) {
if op.Verbose { if op.Verbose {
log.Println("Error while creating extraction folder") log.Println("Error while creating extraction folder")
} }
return err return err
} }
folder = filepath.Clean(folder)
if f.IsDir() { if f.IsDir() {
filFS, _ := f.FS() filFS, _ := f.FS()
var ents []directory.Entry var ents []directory.Entry
+8 -8
View File
@@ -41,6 +41,7 @@ func (r Reader) newFS(e directory.Entry, parent *FS) (*FS, error) {
// Open opens the file at name. Returns a squashfs.File. // Open opens the file at name. Returns a squashfs.File.
func (f FS) Open(name string) (fs.File, error) { func (f FS) Open(name string) (fs.File, error) {
name = filepath.Clean(name)
if !fs.ValidPath(name) { if !fs.ValidPath(name) {
return nil, &fs.PathError{ return nil, &fs.PathError{
Op: "open", Op: "open",
@@ -48,7 +49,6 @@ func (f FS) Open(name string) (fs.File, error) {
Err: fs.ErrInvalid, Err: fs.ErrInvalid,
} }
} }
name = filepath.Clean(name)
if name == "." || name == "" { if name == "." || name == "" {
return f.File, nil return f.File, nil
} }
@@ -100,6 +100,7 @@ func (f FS) Open(name string) (fs.File, error) {
// All paths are relative to the FS. // All paths are relative to the FS.
// Uses filepath.Match to compare names. // Uses filepath.Match to compare names.
func (f FS) Glob(pattern string) (out []string, err error) { func (f FS) Glob(pattern string) (out []string, err error) {
pattern = filepath.Clean(pattern)
if !fs.ValidPath(pattern) { if !fs.ValidPath(pattern) {
return nil, &fs.PathError{ return nil, &fs.PathError{
Op: "glob", Op: "glob",
@@ -107,7 +108,6 @@ func (f FS) Glob(pattern string) (out []string, err error) {
Err: fs.ErrInvalid, Err: fs.ErrInvalid,
} }
} }
pattern = filepath.Clean(pattern)
split := strings.Split(pattern, "/") split := strings.Split(pattern, "/")
for i := 0; i < len(f.e); i++ { for i := 0; i < len(f.e); i++ {
if match, _ := path.Match(split[0], f.e[i].Name); match { if match, _ := path.Match(split[0], f.e[i].Name); match {
@@ -131,7 +131,7 @@ func (f FS) Glob(pattern string) (out []string, err error) {
Err: err, Err: err,
} }
} }
subGlob, err := sub.(FS).Glob(strings.Join(split[1:], "/")) subGlob, err := sub.(fs.GlobFS).Glob(strings.Join(split[1:], "/"))
if err != nil { if err != nil {
if pathErr, ok := err.(*fs.PathError); ok { if pathErr, ok := err.(*fs.PathError); ok {
if pathErr.Err == fs.ErrNotExist { if pathErr.Err == fs.ErrNotExist {
@@ -159,6 +159,7 @@ func (f FS) Glob(pattern string) (out []string, err error) {
// ReadDir returns all the DirEntry returns all DirEntry's for the directory at name. // ReadDir returns all the DirEntry returns all DirEntry's for the directory at name.
// If name is not a directory, returns an error. // If name is not a directory, returns an error.
func (f FS) ReadDir(name string) ([]fs.DirEntry, error) { func (f FS) ReadDir(name string) ([]fs.DirEntry, error) {
name = filepath.Clean(name)
if !fs.ValidPath(name) { if !fs.ValidPath(name) {
return nil, &fs.PathError{ return nil, &fs.PathError{
Op: "readdir", Op: "readdir",
@@ -166,7 +167,6 @@ func (f FS) ReadDir(name string) ([]fs.DirEntry, error) {
Err: fs.ErrInvalid, Err: fs.ErrInvalid,
} }
} }
name = filepath.Clean(name)
if name == "." || name == "" { if name == "." || name == "" {
return f.File.ReadDir(-1) return f.File.ReadDir(-1)
} }
@@ -208,7 +208,7 @@ func (f FS) ReadDir(name string) ([]fs.DirEntry, error) {
Err: err, Err: err,
} }
} }
redDir, err := sub.(FS).ReadDir(strings.Join(split[1:], "/")) redDir, err := sub.(fs.ReadDirFS).ReadDir(strings.Join(split[1:], "/"))
if err != nil { if err != nil {
if pathErr, ok := err.(*fs.PathError); ok { if pathErr, ok := err.(*fs.PathError); ok {
if pathErr.Err == fs.ErrNotExist { if pathErr.Err == fs.ErrNotExist {
@@ -258,6 +258,7 @@ func (f FS) ReadFile(name string) ([]byte, error) {
// Stat returns the fs.FileInfo for the file at name. // Stat returns the fs.FileInfo for the file at name.
func (f FS) Stat(name string) (fs.FileInfo, error) { func (f FS) Stat(name string) (fs.FileInfo, error) {
name = filepath.Clean(strings.TrimPrefix(name, "/"))
if !fs.ValidPath(name) { if !fs.ValidPath(name) {
return nil, &fs.PathError{ return nil, &fs.PathError{
Op: "stat", Op: "stat",
@@ -265,7 +266,6 @@ func (f FS) Stat(name string) (fs.FileInfo, error) {
Err: fs.ErrInvalid, Err: fs.ErrInvalid,
} }
} }
name = filepath.Clean(strings.TrimPrefix(name, "/"))
if name == "." || name == "" { if name == "." || name == "" {
return f.File.Stat() return f.File.Stat()
} }
@@ -299,7 +299,7 @@ func (f FS) Stat(name string) (fs.FileInfo, error) {
Err: err, Err: err,
} }
} }
stat, err := sub.(FS).Stat(strings.Join(split[1:], "/")) stat, err := sub.(fs.StatFS).Stat(strings.Join(split[1:], "/"))
if err != nil { if err != nil {
if pathErr, ok := err.(*fs.PathError); ok { if pathErr, ok := err.(*fs.PathError); ok {
if pathErr.Err == fs.ErrNotExist { if pathErr.Err == fs.ErrNotExist {
@@ -327,6 +327,7 @@ func (f FS) Stat(name string) (fs.FileInfo, error) {
// Sub returns the FS at dir // Sub returns the FS at dir
func (f FS) Sub(dir string) (fs.FS, error) { func (f FS) Sub(dir string) (fs.FS, error) {
dir = filepath.Clean(dir)
if !fs.ValidPath(dir) { if !fs.ValidPath(dir) {
return nil, &fs.PathError{ return nil, &fs.PathError{
Op: "sub", Op: "sub",
@@ -334,7 +335,6 @@ func (f FS) Sub(dir string) (fs.FS, error) {
Err: fs.ErrInvalid, Err: fs.ErrInvalid,
} }
} }
dir = filepath.Clean(dir)
if dir == "." || dir == "" { if dir == "." || dir == "" {
return f, nil return f, nil
} }
+12 -4
View File
@@ -37,13 +37,13 @@ func (r Reader) getReaders(i inode.Inode) (full *data.FullReader, rdr *data.Read
var fragInd uint32 var fragInd uint32
var fragSize uint32 var fragSize uint32
if i.Type == inode.Fil { if i.Type == inode.Fil {
fragOffset = uint64(i.Data.(inode.File).Offset) fragOffset = uint64(i.Data.(inode.File).FragOffset)
blockOffset = uint64(i.Data.(inode.File).BlockStart) blockOffset = uint64(i.Data.(inode.File).BlockStart)
blockSizes = i.Data.(inode.File).BlockSizes blockSizes = i.Data.(inode.File).BlockSizes
fragInd = i.Data.(inode.File).FragInd fragInd = i.Data.(inode.File).FragInd
fragSize = i.Data.(inode.File).Size % r.s.BlockSize fragSize = i.Data.(inode.File).Size % r.s.BlockSize
} else if i.Type == inode.EFil { } else if i.Type == inode.EFil {
fragOffset = uint64(i.Data.(inode.EFile).Offset) fragOffset = uint64(i.Data.(inode.EFile).FragOffset)
blockOffset = i.Data.(inode.EFile).BlockStart blockOffset = i.Data.(inode.EFile).BlockStart
blockSizes = i.Data.(inode.EFile).BlockSizes blockSizes = i.Data.(inode.EFile).BlockSizes
fragInd = i.Data.(inode.EFile).FragInd fragInd = i.Data.(inode.EFile).FragInd
@@ -60,10 +60,14 @@ func (r Reader) getReaders(i inode.Inode) (full *data.FullReader, rdr *data.Read
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, err = fragRdr.Read(make([]byte, fragOffset)) var n, tmpN int
for n != int(fragOffset) {
tmpN, err = fragRdr.Read(make([]byte, int(fragOffset)-n))
if err != nil { if err != nil {
return nil, err return nil, err
} }
n += tmpN
}
fragRdr = io.LimitReader(fragRdr, int64(fragSize)) fragRdr = io.LimitReader(fragRdr, int64(fragSize))
return fragRdr, nil return fragRdr, nil
}) })
@@ -72,10 +76,14 @@ func (r Reader) getReaders(i inode.Inode) (full *data.FullReader, rdr *data.Read
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
_, err = fragRdr.Read(make([]byte, fragOffset)) var n, tmpN int
for n != int(fragOffset) {
tmpN, err = fragRdr.Read(make([]byte, int(fragOffset)-n))
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
n += tmpN
}
fragRdr = io.LimitReader(fragRdr, int64(fragSize)) fragRdr = io.LimitReader(fragRdr, int64(fragSize))
rdr.AddFragment(fragRdr) rdr.AddFragment(fragRdr)
} }
+42
View File
@@ -20,6 +20,8 @@ import (
const ( const (
squashfsURL = "https://darkstorm.tech/LinuxPATest.sfs" squashfsURL = "https://darkstorm.tech/LinuxPATest.sfs"
squashfsName = "LinuxPATest.sfs" squashfsName = "LinuxPATest.sfs"
filePath = "PortableApps/Notepad++Portable/App/DefaultData/Config/contextMenu.xml"
) )
func preTest(dir string) (fil *os.File, err error) { func preTest(dir string) (fil *os.File, err error) {
@@ -55,6 +57,21 @@ func preTest(dir string) (fil *os.File, err error) {
return return
} }
func TestMisc(t *testing.T) {
tmpDir := "testing"
fil, err := preTest(tmpDir)
if err != nil {
t.Fatal(err)
}
rdr, err := squashfs.NewReader(fil)
if err != nil {
t.Fatal(err)
}
_ = rdr
// Put testing here
t.Fatal("UM")
}
func BenchmarkRace(b *testing.B) { func BenchmarkRace(b *testing.B) {
// tmpDir := b.TempDir() // tmpDir := b.TempDir()
tmpDir := "testing" tmpDir := "testing"
@@ -142,4 +159,29 @@ func TestExtractQuick(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Fatal("end")
}
func TestSingleFile(t *testing.T) {
tmpDir := "testing"
fil, err := preTest(tmpDir)
if err != nil {
t.Fatal(err)
}
os.Remove(filepath.Base(filePath))
rdr, err := squashfs.NewReader(fil)
if err != nil {
t.Fatal(err)
}
f, err := rdr.Open(filePath)
if err != nil {
t.Fatal(err)
}
op := squashfs.DefaultOptions()
op.Verbose = true
err = f.(*squashfs.File).ExtractWithOptions("testing", op)
if err != nil {
t.Fatal(err)
}
t.Fatal("HI")
} }