Started work on proper tests.

STILL HAVING STUPID UNEXPLAINABLE NIL POINTERS.
This commit is contained in:
Caleb Gardner
2022-06-18 01:32:51 -05:00
parent 8613e35221
commit cde6a265a1
6 changed files with 121 additions and 22 deletions
+2
View File
@@ -1,5 +1,7 @@
package squashfs package squashfs
//A place for temporary, expiremental tests. Not meant for actual testing purposes.
import ( import (
"fmt" "fmt"
"io" "io"
+7 -3
View File
@@ -25,8 +25,9 @@ type Reader struct {
} }
var ( var (
ErrorMagic = errors.New("magic incorrect. probably not reading squashfs archive") ErrorMagic = errors.New("magic incorrect. probably not reading squashfs archive")
ErrorLog = errors.New("block log is incorrect. possible corrupted archive") ErrorLog = errors.New("block log is incorrect. possible corrupted archive")
ErrorVersion = errors.New("squashfs version of archive is not 4.0")
) )
const ( const (
@@ -53,12 +54,15 @@ func NewReader(r io.ReaderAt) (*Reader, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !squash.s.hasMagic() { if !squash.s.checkMagic() {
return nil, ErrorMagic return nil, ErrorMagic
} }
if !squash.s.checkBlockLog() { if !squash.s.checkBlockLog() {
return nil, ErrorLog return nil, ErrorLog
} }
if !squash.s.checkVersion() {
return nil, ErrorVersion
}
switch squash.s.CompType { switch squash.s.CompType {
case GZipCompression: case GZipCompression:
squash.d = decompress.GZip{} squash.d = decompress.GZip{}
+3 -6
View File
@@ -101,7 +101,7 @@ func (f *File) ReadDir(n int) (out []fs.DirEntry, err error) {
err = io.EOF err = io.EOF
} }
} }
var fi FileInfo var fi fileInfo
for _, e := range ents[start:end] { for _, e := range ents[start:end] {
fi, err = f.r.newFileInfo(e) fi, err = f.r.newFileInfo(e)
if err != nil { if err != nil {
@@ -190,10 +190,7 @@ type ExtractionOptions struct {
//DefaultOptions is the default ExtractionOptions. //DefaultOptions is the default ExtractionOptions.
func DefaultOptions() ExtractionOptions { func DefaultOptions() ExtractionOptions {
return ExtractionOptions{ return ExtractionOptions{
DereferenceSymlink: false, FolderPerm: 0755,
UnbreakSymlink: false,
Verbose: false,
FolderPerm: fs.ModePerm,
} }
} }
@@ -208,7 +205,7 @@ func (f File) ExtractTo(folder string) error {
func (f File) ExtractSymlink(folder string) error { func (f File) ExtractSymlink(folder string) error {
return f.ExtractWithOptions(folder, ExtractionOptions{ return f.ExtractWithOptions(folder, ExtractionOptions{
DereferenceSymlink: true, DereferenceSymlink: true,
FolderPerm: fs.ModePerm, FolderPerm: 0755,
}) })
} }
+11 -12
View File
@@ -8,29 +8,29 @@ import (
"github.com/CalebQ42/squashfs/internal/inode" "github.com/CalebQ42/squashfs/internal/inode"
) )
type FileInfo struct { type fileInfo struct {
e directory.Entry e directory.Entry
size int64 size int64
perm uint32 perm uint32
modTime uint32 modTime uint32
} }
func (r Reader) newFileInfo(e directory.Entry) (FileInfo, error) { func (r Reader) newFileInfo(e directory.Entry) (fileInfo, error) {
i, err := r.inodeFromDir(e) i, err := r.inodeFromDir(e)
if err != nil { if err != nil {
return FileInfo{}, err return fileInfo{}, err
} }
return newFileInfo(e, i), nil return newFileInfo(e, i), nil
} }
func newFileInfo(e directory.Entry, i inode.Inode) FileInfo { func newFileInfo(e directory.Entry, i inode.Inode) fileInfo {
var size int64 var size int64
if i.Type == inode.Fil { if i.Type == inode.Fil {
size = int64(i.Data.(inode.File).Size) size = int64(i.Data.(inode.File).Size)
} else if i.Type == inode.EFil { } else if i.Type == inode.EFil {
size = int64(i.Data.(inode.EFile).Size) size = int64(i.Data.(inode.EFile).Size)
} }
return FileInfo{ return fileInfo{
e: e, e: e,
size: size, size: size,
perm: uint32(i.Perm), perm: uint32(i.Perm),
@@ -38,30 +38,29 @@ func newFileInfo(e directory.Entry, i inode.Inode) FileInfo {
} }
} }
func (f FileInfo) Name() string { func (f fileInfo) Name() string {
return f.e.Name return f.e.Name
} }
func (f FileInfo) Size() int64 { func (f fileInfo) Size() int64 {
return f.size return f.size
} }
func (f FileInfo) Mode() fs.FileMode { func (f fileInfo) Mode() fs.FileMode {
if f.IsDir() { if f.IsDir() {
return fs.FileMode(f.perm | uint32(fs.ModeDir)) return fs.FileMode(f.perm | uint32(fs.ModeDir))
} }
return fs.FileMode(f.perm) return fs.FileMode(f.perm)
} }
func (f FileInfo) ModTime() time.Time { func (f fileInfo) ModTime() time.Time {
return time.Unix(int64(f.modTime), 0) return time.Unix(int64(f.modTime), 0)
} }
func (f FileInfo) IsDir() bool { func (f fileInfo) IsDir() bool {
return f.e.Type == inode.Dir return f.e.Type == inode.Dir
} }
func (f FileInfo) Sys() any { func (f fileInfo) Sys() any {
//TODO
return nil return nil
} }
+93
View File
@@ -0,0 +1,93 @@
package squashfs_test
import (
"io"
"io/fs"
"net/http"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/CalebQ42/squashfs"
)
const (
squashfsURL = "https://darkstorm.tech/LinuxPATest.sfs"
squashfsName = "LinuxPATest.sfs"
)
func preTest(dir string) (fil *os.File, err error) {
_, err = os.Open(filepath.Join(dir, squashfsName))
if err != nil {
_, err = os.Open(dir)
if os.IsNotExist(err) {
err = os.Mkdir(dir, 0755)
}
if err != nil {
return
}
os.Remove(filepath.Join(dir, squashfsName))
fil, err = os.Create(filepath.Join(dir, squashfsName))
if err != nil {
return
}
var resp *http.Response
resp, err = http.DefaultClient.Get(squashfsURL)
if err != nil {
return
}
_, err = io.Copy(fil, resp.Body)
if err != nil {
return
}
}
_, err = exec.LookPath("unsquashfs")
if err != nil {
return
}
_, err = exec.LookPath("mksquashfs")
return
}
func TestExtractQuick(t *testing.T) {
//First, setup everything and extract the archive using the library and unsquashfs
tmpDir := t.TempDir()
fil, err := preTest(tmpDir)
if err != nil {
t.Fatal(err)
}
libPath := filepath.Join(tmpDir, "ExtractLib")
unsquashPath := filepath.Join(tmpDir, "ExtractSquashfs")
os.Remove(libPath)
os.Remove(unsquashPath)
rdr, err := squashfs.NewReader(fil)
if err != nil {
t.Fatal(err)
}
err = rdr.ExtractTo(libPath)
if err != nil {
t.Fatal(err)
}
cmd := exec.Command("unsquashfs", "-d", unsquashPath, fil.Name())
err = cmd.Run()
if err != nil {
t.Fatal(err)
}
//Then compare the sizes and existance between the two (using unsquashfs as a reference).
//If the file doesn't exist, or the size is different, we exit.
//TODO: Add long test that checks contents.
squashFils := os.DirFS(unsquashPath)
err = fs.WalkDir(squashFils, "", func(path string, d fs.DirEntry, err error) error {
t.Log(path)
return nil
})
if err != nil {
t.Fatal(err)
}
t.Fatal("This is a test")
}
+5 -1
View File
@@ -24,7 +24,7 @@ type superblock struct {
ExportTableStart uint64 ExportTableStart uint64
} }
func (s superblock) hasMagic() bool { func (s superblock) checkMagic() bool {
return s.Magic == 0x73717368 return s.Magic == 0x73717368
} }
@@ -32,6 +32,10 @@ func (s superblock) checkBlockLog() bool {
return s.BlockLog == uint16(math.Log2(float64(s.BlockSize))) return s.BlockLog == uint16(math.Log2(float64(s.BlockSize)))
} }
func (s superblock) checkVersion() bool {
return s.VerMaj == 4 && s.VerMin == 0
}
func (s superblock) uncompressedInodes() bool { func (s superblock) uncompressedInodes() bool {
return s.Flags&0x1 == 0x1 return s.Flags&0x1 == 0x1
} }