From 03266d056023d5c28087540eeec835c687cc482c Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Tue, 26 Nov 2024 17:09:39 -0600 Subject: [PATCH 01/32] Fix frag, id, inode table values on block boundries Fixes bug mention in #30 --- low/reader.go | 8 +++++--- low/reader_test.go | 29 +++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/low/reader.go b/low/reader.go index ea71895..4883d94 100644 --- a/low/reader.go +++ b/low/reader.go @@ -3,6 +3,7 @@ package squashfslow import ( "encoding/binary" "errors" + "fmt" "io" "math" @@ -88,7 +89,7 @@ func (r *Reader) Id(i uint16) (uint32, error) { // Populate the id table as needed var blockNum uint32 if i != 0 { // If i == 0, we go negatives causing issues with uint32s - blockNum = uint32(math.Ceil(float64(i)/2048)) - 1 + blockNum = uint32(math.Ceil(float64(i+1)/2048)) - 1 } else { blockNum = 0 } @@ -131,10 +132,11 @@ func (r *Reader) fragEntry(i uint32) (fragEntry, error) { // Populate the fragment table as needed var blockNum uint32 if i != 0 { // If i == 0, we go negatives causing issues with uint32s - blockNum = uint32(math.Ceil(float64(i)/512)) - 1 + blockNum = uint32(math.Ceil(float64(i+1)/512)) - 1 } else { blockNum = 0 } + fmt.Println(blockNum) blocksRead := len(r.fragTable) / 512 blocksToRead := int(blockNum) - blocksRead + 1 @@ -177,7 +179,7 @@ func (r *Reader) inodeRef(i uint32) (uint64, error) { // Populate the export table as needed var blockNum uint32 if i != 0 { // If i == 0, we go negatives causing issues with uint32s - blockNum = uint32(math.Ceil(float64(i)/1024)) - 1 + blockNum = uint32(math.Ceil(float64(i+1)/1024)) - 1 } else { blockNum = 0 } diff --git a/low/reader_test.go b/low/reader_test.go index 6a4a4d0..6a01c09 100644 --- a/low/reader_test.go +++ b/low/reader_test.go @@ -1,4 +1,4 @@ -package squashfslow_test +package squashfslow import ( "fmt" @@ -8,13 +8,11 @@ import ( "os/exec" "path/filepath" "testing" - - squashfslow "github.com/CalebQ42/squashfs/low" ) const ( squashfsURL = "https://darkstorm.tech/files/LinuxPATest.sfs" - squashfsName = "LinuxPATest.sfs" + squashfsName = "airootfs.sfs" ) func preTest(dir string) (fil *os.File, err error) { @@ -50,6 +48,21 @@ func preTest(dir string) (fil *os.File, err error) { return } +func TestMisc(t *testing.T) { + tmpDir := "../testing" + fil, err := preTest(tmpDir) + if err != nil { + t.Fatal(err) + } + defer fil.Close() + rdr, err := NewReader(fil) + if err != nil { + t.Fatal(err) + } + t.Log(rdr.Superblock.FragCount) + t.Fatal(rdr.fragEntry(1233)) +} + func TestReader(t *testing.T) { tmpDir := "../testing" fil, err := preTest(tmpDir) @@ -57,7 +70,7 @@ func TestReader(t *testing.T) { t.Fatal(err) } defer fil.Close() - rdr, err := squashfslow.NewReader(fil) + rdr, err := NewReader(fil) if err != nil { t.Fatal(err) } @@ -77,7 +90,7 @@ func TestSingleFile(t *testing.T) { t.Fatal(err) } defer fil.Close() - rdr, err := squashfslow.NewReader(fil) + rdr, err := NewReader(fil) if err != nil { t.Fatal(err) } @@ -92,7 +105,7 @@ func TestSingleFile(t *testing.T) { t.Fatal(err) } -func extractToDir(rdr *squashfslow.Reader, b *squashfslow.FileBase, folder string) error { +func extractToDir(rdr *Reader, b *FileBase, folder string) error { path := filepath.Join(folder, b.Name) if b.IsDir() { d, err := b.ToDir(rdr) @@ -103,7 +116,7 @@ func extractToDir(rdr *squashfslow.Reader, b *squashfslow.FileBase, folder strin if err != nil { return err } - var nestBast squashfslow.FileBase + var nestBast FileBase for _, e := range d.Entries { nestBast, err = rdr.BaseFromEntry(e) if err != nil { From c80d150fdc8f2f4175fcd2f97359ba5e2c84ad3c Mon Sep 17 00:00:00 2001 From: Will Murphy Date: Tue, 10 Dec 2024 16:52:41 -0500 Subject: [PATCH 02/32] fix: remove stray println --- low/reader.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/low/reader.go b/low/reader.go index 4883d94..31b9b0c 100644 --- a/low/reader.go +++ b/low/reader.go @@ -3,7 +3,6 @@ package squashfslow import ( "encoding/binary" "errors" - "fmt" "io" "math" @@ -136,7 +135,6 @@ func (r *Reader) fragEntry(i uint32) (fragEntry, error) { } else { blockNum = 0 } - fmt.Println(blockNum) blocksRead := len(r.fragTable) / 512 blocksToRead := int(blockNum) - blocksRead + 1 From 87b5ac7f5dc457b62bd37b3d1cc9d93e1bf11ca6 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Thu, 27 Feb 2025 02:46:22 -0600 Subject: [PATCH 03/32] gopls modernize --- file.go | 14 ++++++++------ file_info.go | 5 +++-- fs.go | 4 ++-- go.mod | 6 +++--- go.sum | 4 ++++ internal/metadata/reader.go | 5 +---- low/data/fullreader.go | 5 +---- low/data/reader.go | 5 +---- low/reader.go | 10 ++-------- 9 files changed, 25 insertions(+), 33 deletions(-) diff --git a/file.go b/file.go index 4c4f39a..d52e2b9 100644 --- a/file.go +++ b/file.go @@ -179,9 +179,10 @@ func (f *File) initializeReaders() error { func (f *File) deviceDevices() (maj uint32, min uint32) { var dev uint32 - if f.b.Inode.Type == inode.Char || f.b.Inode.Type == inode.Block { + switch f.b.Inode.Type { + case inode.Char, inode.Block: dev = f.b.Inode.Data.(inode.Device).Dev - } else if f.b.Inode.Type == inode.EChar || f.b.Inode.Type == inode.EBlock { + case inode.EChar, inode.EBlock: dev = f.b.Inode.Data.(inode.EDevice).Dev } return dev >> 8, dev & 0x000FF @@ -266,7 +267,7 @@ func (f *File) ExtractWithOptions(path string, op *ExtractionOptions) error { }(b, path) } var errCache []error - for i := 0; i < len(d.Entries); i++ { + for range d.Entries { err := <-errChan if err != nil { errCache = append(errCache, err) @@ -363,11 +364,12 @@ func (f *File) ExtractWithOptions(path string, op *ExtractionOptions) error { } path = filepath.Join(path, f.b.Name) var typ string - if f.b.Inode.Type == inode.Char || f.b.Inode.Type == inode.EChar { + switch f.b.Inode.Type { + case inode.Char, inode.EChar: typ = "c" - } else if f.b.Inode.Type == inode.Block || f.b.Inode.Type == inode.EBlock { + case inode.Block, inode.EBlock: typ = "b" - } else { //Fifo IPC + default: //Fifo IPC if runtime.GOOS == "darwin" { if op.Verbose { log.Println(f.path(), "ignored. A Fifo file and can't be created on Darwin.") diff --git a/file_info.go b/file_info.go index 28af45a..462e78e 100644 --- a/file_info.go +++ b/file_info.go @@ -26,9 +26,10 @@ func (r Reader) newFileInfo(e directory.Entry) (fileInfo, error) { func newFileInfo(name string, i *inode.Inode) fileInfo { var size int64 - if i.Type == inode.Fil { + switch i.Type { + case inode.Fil: size = int64(i.Data.(inode.File).Size) - } else if i.Type == inode.EFil { + case inode.EFil: size = int64(i.Data.(inode.EFile).Size) } return fileInfo{ diff --git a/fs.go b/fs.go index 0048d0b..e1a282a 100644 --- a/fs.go +++ b/fs.go @@ -42,7 +42,7 @@ func (f *FS) Glob(pattern string) (out []string, err error) { } } split := strings.Split(pattern, "/") - for i := 0; i < len(f.d.Entries); i++ { + for i := range f.d.Entries { if match, _ := path.Match(split[0], f.d.Entries[i].Name); match { if len(split) == 1 { out = append(out, f.d.Entries[i].Name) @@ -80,7 +80,7 @@ func (f *FS) Glob(pattern string) (out []string, err error) { Err: err, } } - for i := 0; i < len(subGlob); i++ { + for i := range subGlob { subGlob[i] = f.d.Name + "/" + subGlob[i] } out = append(out, subGlob...) diff --git a/go.mod b/go.mod index e6c72d8..c1a4306 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,10 @@ module github.com/CalebQ42/squashfs -go 1.22.5 +go 1.24.0 require ( - github.com/klauspost/compress v1.17.9 - github.com/pierrec/lz4/v4 v4.1.21 + github.com/klauspost/compress v1.18.0 + github.com/pierrec/lz4/v4 v4.1.22 github.com/rasky/go-lzo v0.0.0-20200203143853-96a758eda86e github.com/therootcompany/xz v1.0.1 github.com/ulikunitz/xz v0.5.12 diff --git a/go.sum b/go.sum index 164a13f..1c5ef27 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,11 @@ github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/rasky/go-lzo v0.0.0-20200203143853-96a758eda86e h1:dCWirM5F3wMY+cmRda/B1BiPsFtmzXqV9b0hLWtVBMs= github.com/rasky/go-lzo v0.0.0-20200203143853-96a758eda86e/go.mod h1:9leZcVcItj6m9/CfHY5Em/iBrCz7js8LcRQGTKEEv2M= github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= diff --git a/internal/metadata/reader.go b/internal/metadata/reader.go index b20d63c..5a810d1 100644 --- a/internal/metadata/reader.go +++ b/internal/metadata/reader.go @@ -50,10 +50,7 @@ func (r *Reader) Read(b []byte) (int, error) { return curRead, err } } - toRead = len(b) - curRead - if toRead > len(r.dat)-int(r.curOffset) { - toRead = len(r.dat) - int(r.curOffset) - } + toRead = min(len(b)-curRead, len(r.dat)-int(r.curOffset)) copy(b[curRead:], r.dat[r.curOffset:int(r.curOffset)+toRead]) r.curOffset += uint16(toRead) curRead += toRead diff --git a/low/data/fullreader.go b/low/data/fullreader.go index d31853d..c9c694f 100644 --- a/low/data/fullreader.go +++ b/low/data/fullreader.go @@ -88,10 +88,7 @@ func (r *FullReader) WriteTo(w io.Writer) (int64, error) { var errCache []error retChan := make(chan *retValue, r.goroutineLimit) for i := uint64(0); i < uint64(math.Ceil(float64(len(r.sizes))/float64(r.goroutineLimit))); i++ { - toProcess = uint16(len(r.sizes)) - (uint16(i) * r.goroutineLimit) - if toProcess > r.goroutineLimit { - toProcess = r.goroutineLimit - } + toProcess = min(uint16(len(r.sizes))-(uint16(i)*r.goroutineLimit), r.goroutineLimit) // Start all the goroutines for j := uint16(0); j < toProcess; j++ { go r.process((i*uint64(r.goroutineLimit))+uint64(j), curOffset, retChan) diff --git a/low/data/reader.go b/low/data/reader.go index 922263d..df95bed 100644 --- a/low/data/reader.go +++ b/low/data/reader.go @@ -73,10 +73,7 @@ func (r *Reader) Read(b []byte) (int, error) { return curRead, err } } - toRead = len(b) - curRead - if toRead > len(r.dat)-r.curOffset { - toRead = len(r.dat) - r.curOffset - } + toRead = min(len(b)-curRead, len(r.dat)-r.curOffset) toRead = copy(b[curRead:], r.dat[r.curOffset:r.curOffset+toRead]) r.curOffset += toRead curRead += toRead diff --git a/low/reader.go b/low/reader.go index 31b9b0c..614a628 100644 --- a/low/reader.go +++ b/low/reader.go @@ -105,10 +105,7 @@ func (r *Reader) Id(i uint16) (uint32, error) { if err != nil { return 0, err } - idsToRead = r.Superblock.IdCount - uint16(len(r.idTable)) - if idsToRead > 2048 { - idsToRead = 2048 - } + idsToRead = min(r.Superblock.IdCount-uint16(len(r.idTable)), 2048) idsTmp = make([]uint32, idsToRead) rdr = metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d) err = binary.Read(rdr, binary.LittleEndian, &idsTmp) @@ -148,10 +145,7 @@ func (r *Reader) fragEntry(i uint32) (fragEntry, error) { if err != nil { return fragEntry{}, err } - fragsToRead = r.Superblock.FragCount - uint32(len(r.fragTable)) - if fragsToRead > 512 { - fragsToRead = 512 - } + fragsToRead = min(r.Superblock.FragCount-uint32(len(r.fragTable)), 512) fragsTmp = make([]fragEntry, fragsToRead) rdr = metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d) err = binary.Read(rdr, binary.LittleEndian, &fragsTmp) From d890932d5c972ddf48cc826347534f8ad5194f53 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Thu, 27 Feb 2025 07:19:04 -0600 Subject: [PATCH 04/32] Use WriterAt if it's available for FullReader --- low/data/fullreader.go | 99 +++++++++++++++++++++++++++++++++++++----- low/reader.go | 5 +-- squashfs_test.go | 30 +++++++------ 3 files changed, 105 insertions(+), 29 deletions(-) diff --git a/low/data/fullreader.go b/low/data/fullreader.go index c9c694f..d075844 100644 --- a/low/data/fullreader.go +++ b/low/data/fullreader.go @@ -9,6 +9,7 @@ import ( "sync" "github.com/CalebQ42/squashfs/internal/decompress" + "github.com/CalebQ42/squashfs/internal/routinemanager" "github.com/CalebQ42/squashfs/internal/toreader" ) @@ -18,7 +19,6 @@ type FullReader struct { r io.ReaderAt d decompress.Decompressor frag FragReaderConstructor - retPool *sync.Pool sizes []uint32 initialOffset int64 finalBlockSize uint64 @@ -35,11 +35,6 @@ func NewFullReader(r io.ReaderAt, initialOffset int64, d decompress.Decompressor goroutineLimit: uint16(runtime.NumCPU()), finalBlockSize: finalBlockSize, blockSize: blockSize, - retPool: &sync.Pool{ - New: func() any { - return &retValue{} - }, - }, } } @@ -57,8 +52,8 @@ type retValue struct { index uint64 } -func (r *FullReader) process(index uint64, fileOffset uint64, retChan chan *retValue) { - ret := r.retPool.Get().(*retValue) +func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, retChan chan *retValue) { + ret := pool.Get().(*retValue) ret.index = index realSize := r.sizes[index] &^ (1 << 24) if realSize == 0 { @@ -79,7 +74,10 @@ func (r *FullReader) process(index uint64, fileOffset uint64, retChan chan *retV retChan <- ret } -func (r *FullReader) WriteTo(w io.Writer) (int64, error) { +func (r FullReader) WriteTo(w io.Writer) (int64, error) { + if wa, is := w.(io.WriterAt); is { + return r.writeToWriteAt(wa) + } var curIndex uint64 var curOffset uint64 var toProcess uint16 @@ -87,11 +85,16 @@ func (r *FullReader) WriteTo(w io.Writer) (int64, error) { cache := make(map[uint64]*retValue) var errCache []error retChan := make(chan *retValue, r.goroutineLimit) + pool := &sync.Pool{ + New: func() any { + return &retValue{} + }, + } for i := uint64(0); i < uint64(math.Ceil(float64(len(r.sizes))/float64(r.goroutineLimit))); i++ { toProcess = min(uint16(len(r.sizes))-(uint16(i)*r.goroutineLimit), r.goroutineLimit) // Start all the goroutines for j := uint16(0); j < toProcess; j++ { - go r.process((i*uint64(r.goroutineLimit))+uint64(j), curOffset, retChan) + go r.process((i*uint64(r.goroutineLimit))+uint64(j), curOffset, pool, retChan) curOffset += uint64(r.sizes[(i*uint64(r.goroutineLimit))+uint64(j)]) &^ (1 << 24) } // Then consume the results on retChan @@ -125,7 +128,7 @@ func (r *FullReader) WriteTo(w io.Writer) (int64, error) { } continue } - r.retPool.Put(res) + pool.Put(res) curIndex++ // Now we recursively try to clear the cache for len(cache) > 0 { @@ -143,7 +146,7 @@ func (r *FullReader) WriteTo(w io.Writer) (int64, error) { break } delete(cache, curIndex) - r.retPool.Put(res) + pool.Put(res) curIndex++ } } @@ -169,3 +172,75 @@ func (r *FullReader) WriteTo(w io.Writer) (int64, error) { } return wrote, nil } + +func (r FullReader) writeToWriteAt(w io.WriterAt) (out int64, outErr error) { + wait := sync.WaitGroup{} + wait.Add(len(r.sizes)) + mgr := routinemanager.NewManager(r.goroutineLimit) + curOffset := r.initialOffset + for i := uint64(0); i < uint64(len(r.sizes)); i++ { + go func(index uint64, fileOffset int64) { + lckNum := mgr.Lock() + defer mgr.Unlock(lckNum) + defer wait.Done() + realSize := r.sizes[index] &^ (1 << 24) + if realSize == 0 { + if index == uint64(len(r.sizes))-1 && r.frag == nil { + _, err := w.WriteAt([]byte{0}, int64((uint64(r.blockSize)*index)+r.finalBlockSize)-1) + if err != nil { + outErr = errors.Join(outErr, err) + return + } + out = max(out, int64((uint64(r.blockSize)*index)+r.finalBlockSize)) + } + return + } + data := make([]byte, realSize) + err := binary.Read(toreader.NewReader(r.r, int64(r.initialOffset)+int64(fileOffset)), binary.LittleEndian, &data) + if err != nil { + outErr = errors.Join(outErr, err) + return + } + if r.sizes[index] == realSize { + data, err = r.d.Decompress(data) + } + if err != nil { + outErr = errors.Join(outErr, err) + return + } + _, err = w.WriteAt(data, int64(uint64(r.blockSize)*index)) + if err != nil { + outErr = errors.Join(outErr, err) + return + } + out = max(out, int64(uint64(r.blockSize)*(index+1))) + }(i, curOffset) + curOffset += int64(r.sizes[i]) &^ (1 << 24) + } + if r.frag != nil { + wait.Add(1) + go func() { + lckNum := mgr.Lock() + defer mgr.Unlock(lckNum) + defer wait.Done() + rdr, err := r.frag() + if err != nil { + outErr = errors.Join(outErr, err) + return + } + dat, err := io.ReadAll(rdr) + if err != nil { + outErr = errors.Join(outErr, err) + return + } + _, err = w.WriteAt(dat, int64(int(r.blockSize)*len(r.sizes))) + if err != nil { + outErr = errors.Join(outErr, err) + return + } + out = int64(int(r.blockSize)*len(r.sizes)) + int64(r.finalBlockSize) + }() + } + wait.Wait() + return +} diff --git a/low/reader.go b/low/reader.go index 614a628..1535dde 100644 --- a/low/reader.go +++ b/low/reader.go @@ -188,10 +188,7 @@ func (r *Reader) inodeRef(i uint32) (uint64, error) { if err != nil { return 0, err } - refsToRead = r.Superblock.InodeCount - uint32(len(r.exportTable)) - if refsToRead > 1024 { - refsToRead = 1024 - } + refsToRead = min(r.Superblock.InodeCount-uint32(len(r.exportTable)), 1024) refsTmp = make([]uint64, refsToRead) rdr = metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d) err = binary.Read(rdr, binary.LittleEndian, &refsTmp) diff --git a/squashfs_test.go b/squashfs_test.go index 1479774..ed74d3f 100644 --- a/squashfs_test.go +++ b/squashfs_test.go @@ -1,4 +1,4 @@ -package squashfs_test +package squashfs //Actually proper tests go here. @@ -13,13 +13,11 @@ import ( "strconv" "testing" "time" - - "github.com/CalebQ42/squashfs" ) const ( squashfsURL = "https://darkstorm.tech/files/LinuxPATest.sfs" - squashfsName = "airootfs.sfs" + squashfsName = "LinuxPATest.sfs" ) func preTest(dir string) (fil *os.File, err error) { @@ -61,7 +59,7 @@ func TestMisc(t *testing.T) { if err != nil { t.Fatal(err) } - rdr, err := squashfs.NewReader(fil) + rdr, err := NewReader(fil) if err != nil { t.Fatal(err) } @@ -81,10 +79,10 @@ func BenchmarkRace(b *testing.B) { os.RemoveAll(libPath) os.RemoveAll(unsquashPath) var libTime, unsquashTime time.Duration - op := squashfs.FastOptions() + op := FastOptions() op.IgnorePerm = true start := time.Now() - rdr, err := squashfs.NewReader(fil) + rdr, err := NewReader(fil) if err != nil { b.Fatal(err) } @@ -104,13 +102,13 @@ func BenchmarkRace(b *testing.B) { unsquashTime = time.Since(start) // b.Log("Library took:", libTime.Round(time.Millisecond)) // b.Log("unsquashfs took:", unsquashTime.Round(time.Millisecond)) - b.Fatal("unsquashfs is", strconv.FormatFloat(float64(libTime.Milliseconds())/float64(unsquashTime.Milliseconds()), 'f', 2, 64), "times faster") + b.Log("unsquashfs is", strconv.FormatFloat(float64(libTime.Milliseconds())/float64(unsquashTime.Milliseconds()), 'f', 2, 64), "times faster") } func TestExtractQuick(t *testing.T) { //First, setup everything and extract the archive using the library and unsquashfs - // tmpDir := b.TempDir() + // tmpDir := bTempDir() tmpDir := "testing" fil, err := preTest(tmpDir) if err != nil { @@ -120,13 +118,13 @@ func TestExtractQuick(t *testing.T) { unsquashPath := filepath.Join(tmpDir, "ExtractSquashfs") os.RemoveAll(libPath) os.RemoveAll(unsquashPath) - rdr, err := squashfs.NewReader(fil) + rdr, err := NewReader(fil) if err != nil { t.Fatal(err) } os.RemoveAll(filepath.Join(tmpDir, "testLog.txt")) logFil, _ := os.Create(filepath.Join(tmpDir, "testLog.txt")) - op := squashfs.DefaultOptions() + op := DefaultOptions() op.Verbose = true op.IgnorePerm = true op.LogOutput = logFil @@ -178,7 +176,7 @@ func TestSingleFile(t *testing.T) { t.Fatal(err) } os.Remove(filepath.Join(tmpDir, filePath)) - rdr, err := squashfs.NewReader(fil) + rdr, err := NewReader(fil) if err != nil { t.Fatal(err) } @@ -186,9 +184,15 @@ func TestSingleFile(t *testing.T) { if err != nil { t.Fatal(err) } - err = f.(*squashfs.File).ExtractWithOptions("testing", &squashfs.ExtractionOptions{Verbose: true}) + err = f.(*File).ExtractWithOptions("testing", &ExtractionOptions{Verbose: true}) if err != nil { t.Fatal(err) } t.Fatal("HI") } + +func TestStuff(t *testing.T) { + fil, _ := os.Create("testing/stuff.txt") + _, err := fil.WriteAt([]byte("Yo"), 1024) + t.Fatal(err) +} From d6c8efcfe67bf308063bc236fdb74ffb14e216b0 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Tue, 4 Mar 2025 04:08:13 -0600 Subject: [PATCH 05/32] Removed writeToWriteAt Didn't seem to have any performance advantage --- low/data/fullreader.go | 152 +++++++++++++++++++++-------------------- squashfs_test.go | 18 ++--- 2 files changed, 84 insertions(+), 86 deletions(-) diff --git a/low/data/fullreader.go b/low/data/fullreader.go index d075844..1e41eba 100644 --- a/low/data/fullreader.go +++ b/low/data/fullreader.go @@ -9,7 +9,6 @@ import ( "sync" "github.com/CalebQ42/squashfs/internal/decompress" - "github.com/CalebQ42/squashfs/internal/routinemanager" "github.com/CalebQ42/squashfs/internal/toreader" ) @@ -43,6 +42,9 @@ func (r *FullReader) AddFrag(frag FragReaderConstructor) { } func (r *FullReader) SetGoroutineLimit(limit uint16) { + if limit <= 0 { + r.goroutineLimit = 1 + } r.goroutineLimit = limit } @@ -75,9 +77,9 @@ func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, re } func (r FullReader) WriteTo(w io.Writer) (int64, error) { - if wa, is := w.(io.WriterAt); is { - return r.writeToWriteAt(wa) - } + // if wa, is := w.(io.WriterAt); is { + // return r.writeToWriteAt(wa) + // } var curIndex uint64 var curOffset uint64 var toProcess uint16 @@ -173,74 +175,74 @@ func (r FullReader) WriteTo(w io.Writer) (int64, error) { return wrote, nil } -func (r FullReader) writeToWriteAt(w io.WriterAt) (out int64, outErr error) { - wait := sync.WaitGroup{} - wait.Add(len(r.sizes)) - mgr := routinemanager.NewManager(r.goroutineLimit) - curOffset := r.initialOffset - for i := uint64(0); i < uint64(len(r.sizes)); i++ { - go func(index uint64, fileOffset int64) { - lckNum := mgr.Lock() - defer mgr.Unlock(lckNum) - defer wait.Done() - realSize := r.sizes[index] &^ (1 << 24) - if realSize == 0 { - if index == uint64(len(r.sizes))-1 && r.frag == nil { - _, err := w.WriteAt([]byte{0}, int64((uint64(r.blockSize)*index)+r.finalBlockSize)-1) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - out = max(out, int64((uint64(r.blockSize)*index)+r.finalBlockSize)) - } - return - } - data := make([]byte, realSize) - err := binary.Read(toreader.NewReader(r.r, int64(r.initialOffset)+int64(fileOffset)), binary.LittleEndian, &data) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - if r.sizes[index] == realSize { - data, err = r.d.Decompress(data) - } - if err != nil { - outErr = errors.Join(outErr, err) - return - } - _, err = w.WriteAt(data, int64(uint64(r.blockSize)*index)) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - out = max(out, int64(uint64(r.blockSize)*(index+1))) - }(i, curOffset) - curOffset += int64(r.sizes[i]) &^ (1 << 24) - } - if r.frag != nil { - wait.Add(1) - go func() { - lckNum := mgr.Lock() - defer mgr.Unlock(lckNum) - defer wait.Done() - rdr, err := r.frag() - if err != nil { - outErr = errors.Join(outErr, err) - return - } - dat, err := io.ReadAll(rdr) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - _, err = w.WriteAt(dat, int64(int(r.blockSize)*len(r.sizes))) - if err != nil { - outErr = errors.Join(outErr, err) - return - } - out = int64(int(r.blockSize)*len(r.sizes)) + int64(r.finalBlockSize) - }() - } - wait.Wait() - return -} +// func (r FullReader) writeToWriteAt(w io.WriterAt) (out int64, outErr error) { +// wait := &sync.WaitGroup{} +// wait.Add(len(r.sizes)) +// mgr := routinemanager.NewManager(r.goroutineLimit) +// curOffset := r.initialOffset +// for i := uint64(0); i < uint64(len(r.sizes)); i++ { +// go func(index uint64, fileOffset int64) { +// lckNum := mgr.Lock() +// defer mgr.Unlock(lckNum) +// defer wait.Done() +// realSize := r.sizes[index] &^ (1 << 24) +// if realSize == 0 { +// if index == uint64(len(r.sizes))-1 && r.frag == nil { +// _, err := w.WriteAt([]byte{0}, int64((uint64(r.blockSize)*index)+r.finalBlockSize)-1) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// out = max(out, int64((uint64(r.blockSize)*index)+r.finalBlockSize)) +// } +// return +// } +// data := make([]byte, realSize) +// err := binary.Read(toreader.NewReader(r.r, int64(fileOffset)), binary.LittleEndian, &data) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// if r.sizes[index] == realSize { +// data, err = r.d.Decompress(data) +// } +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// _, err = w.WriteAt(data, int64(uint64(r.blockSize)*index)) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// out = max(out, int64(uint64(r.blockSize)*(index+1))) +// }(i, curOffset) +// curOffset += int64(r.sizes[i]) &^ (1 << 24) +// } +// if r.frag != nil { +// wait.Add(1) +// go func() { +// lckNum := mgr.Lock() +// defer mgr.Unlock(lckNum) +// defer wait.Done() +// rdr, err := r.frag() +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// dat, err := io.ReadAll(rdr) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// _, err = w.WriteAt(dat, int64(int(r.blockSize)*len(r.sizes))) +// if err != nil { +// outErr = errors.Join(outErr, err) +// return +// } +// out = int64(int(r.blockSize)*len(r.sizes)) + int64(r.finalBlockSize) +// }() +// } +// wait.Wait() +// return +// } diff --git a/squashfs_test.go b/squashfs_test.go index ed74d3f..1e0873d 100644 --- a/squashfs_test.go +++ b/squashfs_test.go @@ -100,8 +100,8 @@ func BenchmarkRace(b *testing.B) { b.Log("Unsquashfs error:", err) } unsquashTime = time.Since(start) - // b.Log("Library took:", libTime.Round(time.Millisecond)) - // b.Log("unsquashfs took:", unsquashTime.Round(time.Millisecond)) + b.Log("Library took:", libTime.Round(time.Millisecond)) + b.Log("unsquashfs took:", unsquashTime.Round(time.Millisecond)) b.Log("unsquashfs is", strconv.FormatFloat(float64(libTime.Milliseconds())/float64(unsquashTime.Milliseconds()), 'f', 2, 64), "times faster") } @@ -124,7 +124,7 @@ func TestExtractQuick(t *testing.T) { } os.RemoveAll(filepath.Join(tmpDir, "testLog.txt")) logFil, _ := os.Create(filepath.Join(tmpDir, "testLog.txt")) - op := DefaultOptions() + op := FastOptions() op.Verbose = true op.IgnorePerm = true op.LogOutput = logFil @@ -167,7 +167,7 @@ func TestExtractQuick(t *testing.T) { } } -var filePath = "bin" +var filePath = "Start.exe" func TestSingleFile(t *testing.T) { tmpDir := "testing" @@ -184,15 +184,11 @@ func TestSingleFile(t *testing.T) { if err != nil { t.Fatal(err) } - err = f.(*File).ExtractWithOptions("testing", &ExtractionOptions{Verbose: true}) + op := DefaultOptions() + op.Verbose = true + err = f.(*File).ExtractWithOptions("testing", op) if err != nil { t.Fatal(err) } t.Fatal("HI") } - -func TestStuff(t *testing.T) { - fil, _ := os.Create("testing/stuff.txt") - _, err := fil.WriteAt([]byte("Yo"), 1024) - t.Fatal(err) -} From 446f29df70f72b3eec735db64634c0b34c017e85 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Tue, 4 Mar 2025 04:33:47 -0600 Subject: [PATCH 06/32] Empty io.Reader buffer on EOF --- low/data/reader.go | 1 + 1 file changed, 1 insertion(+) diff --git a/low/data/reader.go b/low/data/reader.go index df95bed..e556369 100644 --- a/low/data/reader.go +++ b/low/data/reader.go @@ -41,6 +41,7 @@ func (r *Reader) advance() error { r.dat, err = io.ReadAll(r.frag) return err } else if r.curIndex >= uint64(len(r.sizes)) { + r.dat = []byte{} return io.EOF } realSize := r.sizes[r.curIndex] &^ (1 << 24) From 06d2ef30560cdad6de220bfa05dfa9720474caec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Tue, 11 Mar 2025 18:44:30 +0100 Subject: [PATCH 07/32] Properly show symlinks in Mode Previously they were extracted OK (as symlinks), but shown as regular files with length 0 when getting the file info. --- file_info.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/file_info.go b/file_info.go index 462e78e..c6e7b8d 100644 --- a/file_info.go +++ b/file_info.go @@ -53,6 +53,9 @@ func (f fileInfo) Mode() fs.FileMode { if f.IsDir() { return fs.FileMode(f.perm | uint32(fs.ModeDir)) } + if f.IsSymlink() { + return fs.FileMode(f.perm | uint32(fs.ModeSymlink)) + } return fs.FileMode(f.perm) } @@ -64,6 +67,10 @@ func (f fileInfo) IsDir() bool { return f.fileType == inode.Dir || f.fileType == inode.EDir } +func (f fileInfo) IsSymlink() bool { + return f.fileType == inode.Sym || f.fileType == inode.ESym +} + func (f fileInfo) Sys() any { return nil } From 619bb023b1af39c877e5cf5c69bb66a1156ca709 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Wed, 12 Mar 2025 00:03:58 -0500 Subject: [PATCH 08/32] Fix missing fileInfo.Mode() types --- file_info.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/file_info.go b/file_info.go index c6e7b8d..74ecdbc 100644 --- a/file_info.go +++ b/file_info.go @@ -50,11 +50,17 @@ func (f fileInfo) Size() int64 { } func (f fileInfo) Mode() fs.FileMode { - if f.IsDir() { + switch f.fileType { + case inode.Dir, inode.EDir: return fs.FileMode(f.perm | uint32(fs.ModeDir)) - } - if f.IsSymlink() { + case inode.Sym, inode.ESym: return fs.FileMode(f.perm | uint32(fs.ModeSymlink)) + case inode.Char, inode.EChar, inode.Block, inode.EBlock: + return fs.FileMode(f.perm | uint32(fs.ModeDevice)) + case inode.Fifo, inode.EFifo: + return fs.FileMode(f.perm | uint32(fs.ModeNamedPipe)) + case inode.Sock, inode.ESock: + return fs.FileMode(f.perm | uint32(fs.ModeSocket)) } return fs.FileMode(f.perm) } @@ -71,6 +77,19 @@ func (f fileInfo) IsSymlink() bool { return f.fileType == inode.Sym || f.fileType == inode.ESym } +func (f fileInfo) IsDevice() bool { + return f.fileType == inode.Block || f.fileType == inode.EBlock || + f.fileType == inode.Char || f.fileType == inode.EChar +} + +func (f fileInfo) IsFifo() bool { + return f.fileType == inode.Fifo || f.fileType == inode.EFifo +} + +func (f fileInfo) IsSocket() bool { + return f.fileType == inode.Sock || f.fileType == inode.ESock +} + func (f fileInfo) Sys() any { return nil } From f11416493eb8b6880a116e583791694d20c90ab0 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Wed, 12 Mar 2025 00:09:02 -0500 Subject: [PATCH 09/32] Apply FileMode fixes to Inode.Mode() --- low/inode/inode.go | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/low/inode/inode.go b/low/inode/inode.go index 11976f5..db9f238 100644 --- a/low/inode/inode.go +++ b/low/inode/inode.go @@ -81,23 +81,17 @@ func Read(r io.Reader, blockSize uint32) (i Inode, err error) { func (i Inode) Mode() (out fs.FileMode) { out = fs.FileMode(i.Perm) - switch i.Data.(type) { - case Directory: + switch i.Type { + case Dir, EDir: out |= fs.ModeDir - case EDirectory: - out |= fs.ModeDir - case Symlink: + case Sym, ESym: out |= fs.ModeSymlink - case ESymlink: - out |= fs.ModeSymlink - case Device: + case Char, EChar, Block, EBlock: out |= fs.ModeDevice - case EDevice: - out |= fs.ModeDevice - case IPC: - out |= fs.ModeNamedPipe - case EIPC: + case Fifo, EFifo: out |= fs.ModeNamedPipe + case Sock, ESock: + out |= fs.ModeSocket } return } From 3a48a0bcdc24591113c225c3c14fc810de34c64d Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Wed, 12 Mar 2025 00:11:29 -0500 Subject: [PATCH 10/32] Remove t.Fatal at end of single file test --- squashfs_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/squashfs_test.go b/squashfs_test.go index 1e0873d..ff3f074 100644 --- a/squashfs_test.go +++ b/squashfs_test.go @@ -190,5 +190,4 @@ func TestSingleFile(t *testing.T) { if err != nil { t.Fatal(err) } - t.Fatal("HI") } From 8b475b6cc4965126ba4721a617813577eee6ca9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 15 Mar 2025 17:26:46 +0100 Subject: [PATCH 11/32] Allow mounting with an offset When mounting squashfs images embedded in apptainer image, using offset means we don't need to use a temporary copy. --- cmd/go-unsquashfs/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/go-unsquashfs/main.go b/cmd/go-unsquashfs/main.go index 75be53f..0781bcc 100644 --- a/cmd/go-unsquashfs/main.go +++ b/cmd/go-unsquashfs/main.go @@ -11,6 +11,7 @@ import ( func main() { verbose := flag.Bool("v", false, "Verbose") + offset := flag.Int64("o", 0, "Offset") ignore := flag.Bool("ip", false, "Ignore Permissions and extract all files/folders with 0755") flag.Parse() if len(flag.Args()) < 2 { @@ -21,7 +22,7 @@ func main() { if err != nil { panic(err) } - r, err := squashfs.NewReader(f) + r, err := squashfs.NewReaderAtOffset(f, *offset) if err != nil { panic(err) } From e0c1309ed4bde952271f59be1760c13ac100502d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 15 Mar 2025 17:32:27 +0100 Subject: [PATCH 12/32] Add list option to unsquashfs --- cmd/go-unsquashfs/main.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmd/go-unsquashfs/main.go b/cmd/go-unsquashfs/main.go index 75be53f..9915b0a 100644 --- a/cmd/go-unsquashfs/main.go +++ b/cmd/go-unsquashfs/main.go @@ -3,7 +3,9 @@ package main import ( "flag" "fmt" + "io/fs" "os" + "path/filepath" "time" "github.com/CalebQ42/squashfs" @@ -11,6 +13,7 @@ import ( func main() { verbose := flag.Bool("v", false, "Verbose") + list := flag.Bool("l", false, "List") ignore := flag.Bool("ip", false, "Ignore Permissions and extract all files/folders with 0755") flag.Parse() if len(flag.Args()) < 2 { @@ -25,6 +28,17 @@ func main() { if err != nil { panic(err) } + if *list { + root := flag.Arg(1) + fs.WalkDir(r, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + panic(err) + } + fmt.Println(filepath.Join(root, path)) + return nil + }) + return + } op := squashfs.DefaultOptions() op.Verbose = *verbose op.IgnorePerm = *ignore From 24a9457c6bcd3332d2ac0ab02c4cc99bb13488fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 15 Mar 2025 17:35:40 +0100 Subject: [PATCH 13/32] Refactor: export FileInfo --- file.go | 2 +- file_info.go | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/file.go b/file.go index d52e2b9..1024fa1 100644 --- a/file.go +++ b/file.go @@ -127,7 +127,7 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) { } } var out []fs.DirEntry - var fi fileInfo + var fi FileInfo for _, e := range d.Entries[start:end] { fi, err = f.r.newFileInfo(e) if err != nil { diff --git a/file_info.go b/file_info.go index 74ecdbc..06f90c7 100644 --- a/file_info.go +++ b/file_info.go @@ -8,7 +8,7 @@ import ( "github.com/CalebQ42/squashfs/low/inode" ) -type fileInfo struct { +type FileInfo struct { name string size int64 perm uint32 @@ -16,15 +16,15 @@ type fileInfo struct { fileType uint16 } -func (r Reader) newFileInfo(e directory.Entry) (fileInfo, error) { +func (r Reader) newFileInfo(e directory.Entry) (FileInfo, error) { i, err := r.Low.InodeFromEntry(e) if err != nil { - return fileInfo{}, err + return FileInfo{}, err } return newFileInfo(e.Name, &i), nil } -func newFileInfo(name string, i *inode.Inode) fileInfo { +func newFileInfo(name string, i *inode.Inode) FileInfo { var size int64 switch i.Type { case inode.Fil: @@ -32,7 +32,7 @@ func newFileInfo(name string, i *inode.Inode) fileInfo { case inode.EFil: size = int64(i.Data.(inode.EFile).Size) } - return fileInfo{ + return FileInfo{ name: name, size: size, perm: uint32(i.Perm), @@ -41,15 +41,15 @@ func newFileInfo(name string, i *inode.Inode) fileInfo { } } -func (f fileInfo) Name() string { +func (f FileInfo) Name() string { return f.name } -func (f fileInfo) Size() int64 { +func (f FileInfo) Size() int64 { return f.size } -func (f fileInfo) Mode() fs.FileMode { +func (f FileInfo) Mode() fs.FileMode { switch f.fileType { case inode.Dir, inode.EDir: return fs.FileMode(f.perm | uint32(fs.ModeDir)) @@ -65,31 +65,31 @@ func (f fileInfo) Mode() fs.FileMode { return fs.FileMode(f.perm) } -func (f fileInfo) ModTime() time.Time { +func (f FileInfo) ModTime() time.Time { return time.Unix(int64(f.modTime), 0) } -func (f fileInfo) IsDir() bool { +func (f FileInfo) IsDir() bool { return f.fileType == inode.Dir || f.fileType == inode.EDir } -func (f fileInfo) IsSymlink() bool { +func (f FileInfo) IsSymlink() bool { return f.fileType == inode.Sym || f.fileType == inode.ESym } -func (f fileInfo) IsDevice() bool { +func (f FileInfo) IsDevice() bool { return f.fileType == inode.Block || f.fileType == inode.EBlock || f.fileType == inode.Char || f.fileType == inode.EChar } -func (f fileInfo) IsFifo() bool { +func (f FileInfo) IsFifo() bool { return f.fileType == inode.Fifo || f.fileType == inode.EFifo } -func (f fileInfo) IsSocket() bool { +func (f FileInfo) IsSocket() bool { return f.fileType == inode.Sock || f.fileType == inode.ESock } -func (f fileInfo) Sys() any { +func (f FileInfo) Sys() any { return nil } From cef9090210413bf7b9a716f512bf8fa4970f4340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 15 Mar 2025 17:43:55 +0100 Subject: [PATCH 14/32] Add support for symlinks --- cmd/go-unsquashfs/main.go | 27 +++++++++++++++++++++++++-- file_info.go | 11 +++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/cmd/go-unsquashfs/main.go b/cmd/go-unsquashfs/main.go index 9915b0a..fe4ce13 100644 --- a/cmd/go-unsquashfs/main.go +++ b/cmd/go-unsquashfs/main.go @@ -6,14 +6,33 @@ import ( "io/fs" "os" "path/filepath" + "strings" "time" "github.com/CalebQ42/squashfs" ) +func printEntry(root, path string, d fs.DirEntry) { + fi, _ := d.Info() + sfi := fi.(squashfs.FileInfo) + owner := fmt.Sprintf("%d/%d", + sfi.Uid(), + sfi.Gid()) + link := "" + if sfi.IsSymlink() { + link = " -> " + sfi.SymlinkPath() + } + fmt.Printf("%s %s %*d %s %s%s\n", + strings.ToLower(fi.Mode().String()), + owner, 26-len(owner), fi.Size(), + fi.ModTime().Format("2006-01-02 15:04"), + filepath.Join(root, path), link) +} + func main() { verbose := flag.Bool("v", false, "Verbose") list := flag.Bool("l", false, "List") + long := flag.Bool("ll", false, "List with attributes") ignore := flag.Bool("ip", false, "Ignore Permissions and extract all files/folders with 0755") flag.Parse() if len(flag.Args()) < 2 { @@ -28,13 +47,17 @@ func main() { if err != nil { panic(err) } - if *list { + if *list || *long { root := flag.Arg(1) fs.WalkDir(r, ".", func(path string, d fs.DirEntry, err error) error { if err != nil { panic(err) } - fmt.Println(filepath.Join(root, path)) + if *long { + printEntry(root, path, d) + } else { + fmt.Println(filepath.Join(root, path)) + } return nil }) return diff --git a/file_info.go b/file_info.go index 06f90c7..6c00017 100644 --- a/file_info.go +++ b/file_info.go @@ -11,6 +11,7 @@ import ( type FileInfo struct { name string size int64 + target string perm uint32 modTime uint32 fileType uint16 @@ -26,15 +27,21 @@ func (r Reader) newFileInfo(e directory.Entry) (FileInfo, error) { func newFileInfo(name string, i *inode.Inode) FileInfo { var size int64 + var target string switch i.Type { case inode.Fil: size = int64(i.Data.(inode.File).Size) case inode.EFil: size = int64(i.Data.(inode.EFile).Size) + case inode.Sym: + target = string(i.Data.(inode.Symlink).Target) + case inode.ESym: + target = string(i.Data.(inode.ESymlink).Target) } return FileInfo{ name: name, size: size, + target: target, perm: uint32(i.Perm), modTime: i.ModTime, fileType: i.Type, @@ -49,6 +56,10 @@ func (f FileInfo) Size() int64 { return f.size } +func (f FileInfo) SymlinkPath() string { + return f.target +} + func (f FileInfo) Mode() fs.FileMode { switch f.fileType { case inode.Dir, inode.EDir: From e6b0b83dcb76e2242ba5e9739c01a1bde129b692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 15 Mar 2025 17:49:27 +0100 Subject: [PATCH 15/32] Add support for uid/gid --- cmd/go-unsquashfs/main.go | 39 ++++++++++++++++++++++++++++++++------- file.go | 10 +++++++++- file_info.go | 26 +++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/cmd/go-unsquashfs/main.go b/cmd/go-unsquashfs/main.go index fe4ce13..1b6a530 100644 --- a/cmd/go-unsquashfs/main.go +++ b/cmd/go-unsquashfs/main.go @@ -5,19 +5,43 @@ import ( "fmt" "io/fs" "os" + "os/user" "path/filepath" + "strconv" "strings" "time" "github.com/CalebQ42/squashfs" ) -func printEntry(root, path string, d fs.DirEntry) { +func userName(uid int, numeric bool) string { + us := strconv.Itoa(uid) + if numeric { + return us + } + if u, err := user.LookupId(us); err == nil { + return u.Username + } + return us +} + +func groupName(gid int, numeric bool) string { + gs := strconv.Itoa(gid) + if numeric { + return gs + } + if g, err := user.LookupGroupId(gs); err == nil { + return g.Name + } + return gs +} + +func printEntry(root, path string, d fs.DirEntry, numeric bool) { fi, _ := d.Info() sfi := fi.(squashfs.FileInfo) - owner := fmt.Sprintf("%d/%d", - sfi.Uid(), - sfi.Gid()) + owner := fmt.Sprintf("%s/%s", + userName(sfi.Uid(), numeric), + groupName(sfi.Gid(), numeric)) link := "" if sfi.IsSymlink() { link = " -> " + sfi.SymlinkPath() @@ -33,6 +57,7 @@ func main() { verbose := flag.Bool("v", false, "Verbose") list := flag.Bool("l", false, "List") long := flag.Bool("ll", false, "List with attributes") + numeric := flag.Bool("lln", false, "List with attributes and numeric ids") ignore := flag.Bool("ip", false, "Ignore Permissions and extract all files/folders with 0755") flag.Parse() if len(flag.Args()) < 2 { @@ -47,14 +72,14 @@ func main() { if err != nil { panic(err) } - if *list || *long { + if *list || *long || *numeric { root := flag.Arg(1) fs.WalkDir(r, ".", func(path string, d fs.DirEntry, err error) error { if err != nil { panic(err) } - if *long { - printEntry(root, path, d) + if *long || *numeric { + printEntry(root, path, d, *numeric) } else { fmt.Println(filepath.Join(root, path)) } diff --git a/file.go b/file.go index 1024fa1..c3ebf6f 100644 --- a/file.go +++ b/file.go @@ -142,7 +142,15 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) { // Returns the file's fs.FileInfo func (f *File) Stat() (fs.FileInfo, error) { - return newFileInfo(f.b.Name, &f.b.Inode), nil + uid, err := f.b.Uid(&f.r.Low) + if err != nil { + return nil, err + } + gid, err := f.b.Gid(&f.r.Low) + if err != nil { + return nil, err + } + return newFileInfo(f.b.Name, uid, gid, &f.b.Inode), nil } // SymlinkPath returns the symlink's target path. Is the File isn't a symlink, returns an empty string. diff --git a/file_info.go b/file_info.go index 6c00017..20ddfc7 100644 --- a/file_info.go +++ b/file_info.go @@ -10,6 +10,8 @@ import ( type FileInfo struct { name string + uid uint32 + gid uint32 size int64 target string perm uint32 @@ -18,14 +20,22 @@ type FileInfo struct { } func (r Reader) newFileInfo(e directory.Entry) (FileInfo, error) { - i, err := r.Low.InodeFromEntry(e) + b, err := r.Low.BaseFromEntry(e) if err != nil { return FileInfo{}, err } - return newFileInfo(e.Name, &i), nil + uid, err := b.Uid(&r.Low) + if err != nil { + return FileInfo{}, err + } + gid, err := b.Gid(&r.Low) + if err != nil { + return FileInfo{}, err + } + return newFileInfo(e.Name, uid, gid, &b.Inode), nil } -func newFileInfo(name string, i *inode.Inode) FileInfo { +func newFileInfo(name string, uid, gid uint32, i *inode.Inode) FileInfo { var size int64 var target string switch i.Type { @@ -40,6 +50,8 @@ func newFileInfo(name string, i *inode.Inode) FileInfo { } return FileInfo{ name: name, + uid: uid, + gid: gid, size: size, target: target, perm: uint32(i.Perm), @@ -52,6 +64,14 @@ func (f FileInfo) Name() string { return f.name } +func (f FileInfo) Uid() int { + return int(f.uid) +} + +func (f FileInfo) Gid() int { + return int(f.gid) +} + func (f FileInfo) Size() int64 { return f.size } From 04d914d403c6471fc78791fdc82035b53a5db513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sun, 16 Mar 2025 13:53:42 +0100 Subject: [PATCH 16/32] Allow disabling lzo and lzma By setting the buildtags "no_lzo" and/or "no_lzma", one can drop the library dependency on lzo and lzma. The same could be done for xz as well, but there are still lots of archives using xz compression out there. --- internal/decompress/lzma.go | 1 + internal/decompress/lzma_none.go | 12 ++++++++++++ internal/decompress/lzo.go | 1 + internal/decompress/lzo_none.go | 12 ++++++++++++ 4 files changed, 26 insertions(+) create mode 100644 internal/decompress/lzma_none.go create mode 100644 internal/decompress/lzo_none.go diff --git a/internal/decompress/lzma.go b/internal/decompress/lzma.go index e79d0db..f204b2a 100644 --- a/internal/decompress/lzma.go +++ b/internal/decompress/lzma.go @@ -1,3 +1,4 @@ +//go:build !no_lzma package decompress import ( diff --git a/internal/decompress/lzma_none.go b/internal/decompress/lzma_none.go new file mode 100644 index 0000000..718127b --- /dev/null +++ b/internal/decompress/lzma_none.go @@ -0,0 +1,12 @@ +//go:build no_lzma +package decompress + +import ( + "fmt" +) + +type Lzma struct{} + +func (l Lzma) Decompress(_ []byte) ([]byte, error) { + return nil, fmt.Errorf("lzma is not supported") +} diff --git a/internal/decompress/lzo.go b/internal/decompress/lzo.go index f5783b4..74ab7b4 100644 --- a/internal/decompress/lzo.go +++ b/internal/decompress/lzo.go @@ -1,3 +1,4 @@ +//go:build !no_lzo package decompress import ( diff --git a/internal/decompress/lzo_none.go b/internal/decompress/lzo_none.go new file mode 100644 index 0000000..0901043 --- /dev/null +++ b/internal/decompress/lzo_none.go @@ -0,0 +1,12 @@ +//go:build no_lzo +package decompress + +import ( + "fmt" +) + +type Lzo struct{} + +func (l Lzo) Decompress(_ []byte) ([]byte, error) { + return nil, fmt.Errorf("lzo is not supported") +} From ad24995b7bb27dfbd7d2e9fa49a20fe769e8ac08 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Mon, 17 Mar 2025 06:16:25 -0500 Subject: [PATCH 17/32] Change no_lzma and no_lzo to no_obsolete and no_gpl Added build tags section to README --- README.md | 4 +++ internal/decompress/get_decomp.go | 32 +++++++++++++++++ internal/decompress/get_decomp_no_gpl.go | 34 +++++++++++++++++++ .../decompress/get_decomp_no_gpl_obsolete.go | 34 +++++++++++++++++++ internal/decompress/get_decomp_no_obsolete.go | 34 +++++++++++++++++++ internal/decompress/lzma.go | 1 + internal/decompress/lzma_none.go | 12 ------- internal/decompress/lzo.go | 1 + internal/decompress/lzo_none.go | 12 ------- low/reader.go | 18 ++-------- 10 files changed, 143 insertions(+), 39 deletions(-) create mode 100644 internal/decompress/get_decomp.go create mode 100644 internal/decompress/get_decomp_no_gpl.go create mode 100644 internal/decompress/get_decomp_no_gpl_obsolete.go create mode 100644 internal/decompress/get_decomp_no_obsolete.go delete mode 100644 internal/decompress/lzma_none.go delete mode 100644 internal/decompress/lzo_none.go diff --git a/README.md b/README.md index 73e7767..3874485 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,10 @@ Currently has support for reading squashfs files and extracting files and folder Special thanks to for some VERY important information in an easy to understand format. Thanks also to [distri's squashfs library](https://github.com/distr1/distri/tree/master/internal/squashfs) as I referenced it to figure some things out (and double check others). +## Build tags + +This library has two optional build tags. `no_gpl` disables the ability to read archives with lzo compression due to the library's gpl license. `no_obsolete` removes "obsolete" compression types for a reduced size; currently this only disable lzma compression. + ## FUSE As of `v1.0`, FUSE capabilities has been moved to [a separate library](https://github.com/CalebQ42/squashfuse). diff --git a/internal/decompress/get_decomp.go b/internal/decompress/get_decomp.go new file mode 100644 index 0000000..45c902c --- /dev/null +++ b/internal/decompress/get_decomp.go @@ -0,0 +1,32 @@ +package decompress + +import "errors" + +// The types of compression supported by squashfs +const ( + ZlibCompression = uint16(iota + 1) + LZMACompression + LZOCompression + XZCompression + LZ4Compression + ZSTDCompression +) + +func GetDecompressor(compType uint16) (Decompressor, error) { + switch compType { + case ZlibCompression: + return Zlib{}, nil + case LZMACompression: + return Lzma{}, nil + case LZOCompression: + return Lzo{}, nil + case XZCompression: + return Xz{}, nil + case LZ4Compression: + return Lz4{}, nil + case ZSTDCompression: + return &Zstd{}, nil + default: + return nil, errors.New("invalid compression type. possible corrupted archive") + } +} diff --git a/internal/decompress/get_decomp_no_gpl.go b/internal/decompress/get_decomp_no_gpl.go new file mode 100644 index 0000000..c6ab40f --- /dev/null +++ b/internal/decompress/get_decomp_no_gpl.go @@ -0,0 +1,34 @@ +//go:build no_gpl + +package decompress + +import "errors" + +// The types of compression supported by squashfs +const ( + ZlibCompression = uint16(iota + 1) + LZMACompression + LZOCompression + XZCompression + LZ4Compression + ZSTDCompression +) + +func GetDecompressor(compType uint16) (Decompressor, error) { + switch compType { + case ZlibCompression: + return Zlib{}, nil + case LZMACompression: + return Lzma{}, nil + case LZOCompression: + return nil, errors.New("lzo compression is disable in this build with no_gpl") + case XZCompression: + return Xz{}, nil + case LZ4Compression: + return Lz4{}, nil + case ZSTDCompression: + return &Zstd{}, nil + default: + return nil, errors.New("invalid compression type. possible corrupted archive") + } +} diff --git a/internal/decompress/get_decomp_no_gpl_obsolete.go b/internal/decompress/get_decomp_no_gpl_obsolete.go new file mode 100644 index 0000000..cb17867 --- /dev/null +++ b/internal/decompress/get_decomp_no_gpl_obsolete.go @@ -0,0 +1,34 @@ +//go:build no_obsolete + +package decompress + +import "errors" + +// The types of compression supported by squashfs +const ( + ZlibCompression = uint16(iota + 1) + LZMACompression + LZOCompression + XZCompression + LZ4Compression + ZSTDCompression +) + +func GetDecompressor(compType uint16) (Decompressor, error) { + switch compType { + case ZlibCompression: + return Zlib{}, nil + case LZMACompression: + return nil, errors.New("lzma compression is disable in this build with no_obsolete") + case LZOCompression: + return Lzo{}, nil + case XZCompression: + return Xz{}, nil + case LZ4Compression: + return Lz4{}, nil + case ZSTDCompression: + return &Zstd{}, nil + default: + return nil, errors.New("invalid compression type. possible corrupted archive") + } +} diff --git a/internal/decompress/get_decomp_no_obsolete.go b/internal/decompress/get_decomp_no_obsolete.go new file mode 100644 index 0000000..0a85d11 --- /dev/null +++ b/internal/decompress/get_decomp_no_obsolete.go @@ -0,0 +1,34 @@ +//go:build no_gpl && no_obsolete + +package decompress + +import "errors" + +// The types of compression supported by squashfs +const ( + ZlibCompression = uint16(iota + 1) + LZMACompression + LZOCompression + XZCompression + LZ4Compression + ZSTDCompression +) + +func GetDecompressor(compType uint16) (Decompressor, error) { + switch compType { + case ZlibCompression: + return Zlib{}, nil + case LZMACompression: + return nil, errors.New("lzma compression is disable in this build with no_obsolete") + case LZOCompression: + return nil, errors.New("lzo compression is disable in this build with no_gpl") + case XZCompression: + return Xz{}, nil + case LZ4Compression: + return Lz4{}, nil + case ZSTDCompression: + return &Zstd{}, nil + default: + return nil, errors.New("invalid compression type. possible corrupted archive") + } +} diff --git a/internal/decompress/lzma.go b/internal/decompress/lzma.go index f204b2a..74603f9 100644 --- a/internal/decompress/lzma.go +++ b/internal/decompress/lzma.go @@ -1,4 +1,5 @@ //go:build !no_lzma + package decompress import ( diff --git a/internal/decompress/lzma_none.go b/internal/decompress/lzma_none.go deleted file mode 100644 index 718127b..0000000 --- a/internal/decompress/lzma_none.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build no_lzma -package decompress - -import ( - "fmt" -) - -type Lzma struct{} - -func (l Lzma) Decompress(_ []byte) ([]byte, error) { - return nil, fmt.Errorf("lzma is not supported") -} diff --git a/internal/decompress/lzo.go b/internal/decompress/lzo.go index 74ab7b4..fd8d650 100644 --- a/internal/decompress/lzo.go +++ b/internal/decompress/lzo.go @@ -1,4 +1,5 @@ //go:build !no_lzo + package decompress import ( diff --git a/internal/decompress/lzo_none.go b/internal/decompress/lzo_none.go deleted file mode 100644 index 0901043..0000000 --- a/internal/decompress/lzo_none.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build no_lzo -package decompress - -import ( - "fmt" -) - -type Lzo struct{} - -func (l Lzo) Decompress(_ []byte) ([]byte, error) { - return nil, fmt.Errorf("lzo is not supported") -} diff --git a/low/reader.go b/low/reader.go index 1535dde..85e45d8 100644 --- a/low/reader.go +++ b/low/reader.go @@ -55,21 +55,9 @@ func NewReader(r io.ReaderAt) (rdr *Reader, err error) { if !rdr.Superblock.ValidVersion() { return nil, ErrorVersion } - switch rdr.Superblock.CompType { - case ZlibCompression: - rdr.d = decompress.Zlib{} - case LZMACompression: - rdr.d = decompress.Lzma{} - case LZOCompression: - rdr.d = decompress.Lzo{} - case XZCompression: - rdr.d = decompress.Xz{} - case LZ4Compression: - rdr.d = decompress.Lz4{} - case ZSTDCompression: - rdr.d = &decompress.Zstd{} - default: - return nil, errors.New("invalid compression type. possible corrupted archive") + rdr.d, err = decompress.GetDecompressor(rdr.Superblock.CompType) + if err != nil { + return nil, err } rdr.Root, err = rdr.directoryFromRef(rdr.Superblock.RootInodeRef, "") if err != nil { From d3f84344d19010de47b289e1d972c914a9c42f91 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Mon, 17 Mar 2025 06:19:45 -0500 Subject: [PATCH 18/32] Fix build flags in lzma.go & xz.go --- README.md | 2 +- internal/decompress/lzma.go | 2 +- internal/decompress/lzo.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3874485..c4060fc 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Thanks also to [distri's squashfs library](https://github.com/distr1/distri/tree ## Build tags -This library has two optional build tags. `no_gpl` disables the ability to read archives with lzo compression due to the library's gpl license. `no_obsolete` removes "obsolete" compression types for a reduced size; currently this only disable lzma compression. +This library has two optional build tags. `no_gpl` disables the ability to read archives with lzo compression due to the library's gpl license. `no_obsolete` removes "obsolete" compression types for a reduced compilation size; currently this only disable lzma compression since it's superseded by xz. ## FUSE diff --git a/internal/decompress/lzma.go b/internal/decompress/lzma.go index 74603f9..8fa1e3c 100644 --- a/internal/decompress/lzma.go +++ b/internal/decompress/lzma.go @@ -1,4 +1,4 @@ -//go:build !no_lzma +//go:build !no_obsolete package decompress diff --git a/internal/decompress/lzo.go b/internal/decompress/lzo.go index fd8d650..b708f50 100644 --- a/internal/decompress/lzo.go +++ b/internal/decompress/lzo.go @@ -1,4 +1,4 @@ -//go:build !no_lzo +//go:build !no_gpl package decompress From 863b03fb19e9282287e53f2e1bc2f624fe79b147 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Mon, 17 Mar 2025 06:21:19 -0500 Subject: [PATCH 19/32] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4060fc..a633f95 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Thanks also to [distri's squashfs library](https://github.com/distr1/distri/tree ## Build tags -This library has two optional build tags. `no_gpl` disables the ability to read archives with lzo compression due to the library's gpl license. `no_obsolete` removes "obsolete" compression types for a reduced compilation size; currently this only disable lzma compression since it's superseded by xz. +As of `v1.1.0` this library has two optional build tags: `no_gpl` and `no_obsolete`. `no_gpl` disables the ability to read archives with lzo compression due to the library's gpl license. `no_obsolete` removes "obsolete" compression types for a reduced compilation size; currently this only disable lzma compression since it's superseded by xz. ## FUSE From 1e2a8f4b7519f4c35e7de79cdb9d0cf3cd9b8cb4 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Mon, 17 Mar 2025 06:22:24 -0500 Subject: [PATCH 20/32] go mod tidy --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index 1c5ef27..1e69fc0 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= -github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/rasky/go-lzo v0.0.0-20200203143853-96a758eda86e h1:dCWirM5F3wMY+cmRda/B1BiPsFtmzXqV9b0hLWtVBMs= From 88315ee384c5ff84b7d5bbee5fc547eb9b295089 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Mon, 17 Mar 2025 06:28:31 -0500 Subject: [PATCH 21/32] Fix build flags --- internal/decompress/get_decomp.go | 2 ++ internal/decompress/get_decomp_no_gpl.go | 2 +- internal/decompress/get_decomp_no_gpl_obsolete.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/decompress/get_decomp.go b/internal/decompress/get_decomp.go index 45c902c..ee438e1 100644 --- a/internal/decompress/get_decomp.go +++ b/internal/decompress/get_decomp.go @@ -1,3 +1,5 @@ +//go:build !no_gpl && !no_obsolete + package decompress import "errors" diff --git a/internal/decompress/get_decomp_no_gpl.go b/internal/decompress/get_decomp_no_gpl.go index c6ab40f..43875c5 100644 --- a/internal/decompress/get_decomp_no_gpl.go +++ b/internal/decompress/get_decomp_no_gpl.go @@ -1,4 +1,4 @@ -//go:build no_gpl +//go:build no_gpl && !no_obsolete package decompress diff --git a/internal/decompress/get_decomp_no_gpl_obsolete.go b/internal/decompress/get_decomp_no_gpl_obsolete.go index cb17867..2c2d3fb 100644 --- a/internal/decompress/get_decomp_no_gpl_obsolete.go +++ b/internal/decompress/get_decomp_no_gpl_obsolete.go @@ -1,4 +1,4 @@ -//go:build no_obsolete +//go:build no_obsolete && !no_gpl package decompress From f242de2710d0f810a9f0f0d9ab3b7510851003d2 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Mon, 17 Mar 2025 06:53:29 -0500 Subject: [PATCH 22/32] Better disabling of compression types --- internal/decompress/get_decomp.go | 34 ------------------- internal/decompress/get_decomp_no_gpl.go | 34 ------------------- .../decompress/get_decomp_no_gpl_obsolete.go | 34 ------------------- internal/decompress/get_decomp_no_obsolete.go | 34 ------------------- internal/decompress/lzma.go | 4 +++ internal/decompress/lzma_disabled.go | 17 ++++++++++ internal/decompress/lzo.go | 4 +++ internal/decompress/lzo_disabled.go | 15 ++++++++ low/reader.go | 24 +++++++++++-- 9 files changed, 61 insertions(+), 139 deletions(-) delete mode 100644 internal/decompress/get_decomp.go delete mode 100644 internal/decompress/get_decomp_no_gpl.go delete mode 100644 internal/decompress/get_decomp_no_gpl_obsolete.go delete mode 100644 internal/decompress/get_decomp_no_obsolete.go create mode 100644 internal/decompress/lzma_disabled.go create mode 100644 internal/decompress/lzo_disabled.go diff --git a/internal/decompress/get_decomp.go b/internal/decompress/get_decomp.go deleted file mode 100644 index ee438e1..0000000 --- a/internal/decompress/get_decomp.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build !no_gpl && !no_obsolete - -package decompress - -import "errors" - -// The types of compression supported by squashfs -const ( - ZlibCompression = uint16(iota + 1) - LZMACompression - LZOCompression - XZCompression - LZ4Compression - ZSTDCompression -) - -func GetDecompressor(compType uint16) (Decompressor, error) { - switch compType { - case ZlibCompression: - return Zlib{}, nil - case LZMACompression: - return Lzma{}, nil - case LZOCompression: - return Lzo{}, nil - case XZCompression: - return Xz{}, nil - case LZ4Compression: - return Lz4{}, nil - case ZSTDCompression: - return &Zstd{}, nil - default: - return nil, errors.New("invalid compression type. possible corrupted archive") - } -} diff --git a/internal/decompress/get_decomp_no_gpl.go b/internal/decompress/get_decomp_no_gpl.go deleted file mode 100644 index 43875c5..0000000 --- a/internal/decompress/get_decomp_no_gpl.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build no_gpl && !no_obsolete - -package decompress - -import "errors" - -// The types of compression supported by squashfs -const ( - ZlibCompression = uint16(iota + 1) - LZMACompression - LZOCompression - XZCompression - LZ4Compression - ZSTDCompression -) - -func GetDecompressor(compType uint16) (Decompressor, error) { - switch compType { - case ZlibCompression: - return Zlib{}, nil - case LZMACompression: - return Lzma{}, nil - case LZOCompression: - return nil, errors.New("lzo compression is disable in this build with no_gpl") - case XZCompression: - return Xz{}, nil - case LZ4Compression: - return Lz4{}, nil - case ZSTDCompression: - return &Zstd{}, nil - default: - return nil, errors.New("invalid compression type. possible corrupted archive") - } -} diff --git a/internal/decompress/get_decomp_no_gpl_obsolete.go b/internal/decompress/get_decomp_no_gpl_obsolete.go deleted file mode 100644 index 2c2d3fb..0000000 --- a/internal/decompress/get_decomp_no_gpl_obsolete.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build no_obsolete && !no_gpl - -package decompress - -import "errors" - -// The types of compression supported by squashfs -const ( - ZlibCompression = uint16(iota + 1) - LZMACompression - LZOCompression - XZCompression - LZ4Compression - ZSTDCompression -) - -func GetDecompressor(compType uint16) (Decompressor, error) { - switch compType { - case ZlibCompression: - return Zlib{}, nil - case LZMACompression: - return nil, errors.New("lzma compression is disable in this build with no_obsolete") - case LZOCompression: - return Lzo{}, nil - case XZCompression: - return Xz{}, nil - case LZ4Compression: - return Lz4{}, nil - case ZSTDCompression: - return &Zstd{}, nil - default: - return nil, errors.New("invalid compression type. possible corrupted archive") - } -} diff --git a/internal/decompress/get_decomp_no_obsolete.go b/internal/decompress/get_decomp_no_obsolete.go deleted file mode 100644 index 0a85d11..0000000 --- a/internal/decompress/get_decomp_no_obsolete.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build no_gpl && no_obsolete - -package decompress - -import "errors" - -// The types of compression supported by squashfs -const ( - ZlibCompression = uint16(iota + 1) - LZMACompression - LZOCompression - XZCompression - LZ4Compression - ZSTDCompression -) - -func GetDecompressor(compType uint16) (Decompressor, error) { - switch compType { - case ZlibCompression: - return Zlib{}, nil - case LZMACompression: - return nil, errors.New("lzma compression is disable in this build with no_obsolete") - case LZOCompression: - return nil, errors.New("lzo compression is disable in this build with no_gpl") - case XZCompression: - return Xz{}, nil - case LZ4Compression: - return Lz4{}, nil - case ZSTDCompression: - return &Zstd{}, nil - default: - return nil, errors.New("invalid compression type. possible corrupted archive") - } -} diff --git a/internal/decompress/lzma.go b/internal/decompress/lzma.go index 8fa1e3c..1403b07 100644 --- a/internal/decompress/lzma.go +++ b/internal/decompress/lzma.go @@ -11,6 +11,10 @@ import ( type Lzma struct{} +func NewLzma() (Lzma, error) { + return Lzma{}, nil +} + func (l Lzma) Decompress(data []byte) ([]byte, error) { rdr, err := lzma.NewReader(bytes.NewReader(data)) if err != nil { diff --git a/internal/decompress/lzma_disabled.go b/internal/decompress/lzma_disabled.go new file mode 100644 index 0000000..d93eb8f --- /dev/null +++ b/internal/decompress/lzma_disabled.go @@ -0,0 +1,17 @@ +//go:build no_obsolete + +package decompress + +import ( + "errors" +) + +type Lzma struct{} + +func NewLzma() (Lzma, error) { + return Lzma{}, errors.New("lzma compression is disable in this build with no_obsolete") +} + +func (l Lzma) Decompress(data []byte) ([]byte, error) { + return nil, errors.New("lzma compression is disable in this build with no_obsolete") +} diff --git a/internal/decompress/lzo.go b/internal/decompress/lzo.go index b708f50..9f54e9e 100644 --- a/internal/decompress/lzo.go +++ b/internal/decompress/lzo.go @@ -10,6 +10,10 @@ import ( type Lzo struct{} +func NewLzo() (Lzo, error) { + return Lzo{}, nil +} + func (l Lzo) Decompress(data []byte) ([]byte, error) { return lzo.Decompress1X(bytes.NewReader(data), len(data), 0) } diff --git a/internal/decompress/lzo_disabled.go b/internal/decompress/lzo_disabled.go new file mode 100644 index 0000000..181b5cb --- /dev/null +++ b/internal/decompress/lzo_disabled.go @@ -0,0 +1,15 @@ +//go:build no_gpl + +package decompress + +import "errors" + +type Lzo struct{} + +func NewLzo() (Lzo, error) { + return Lzo{}, errors.New("lzo compression is disable in this build with no_gpl") +} + +func (l Lzo) Decompress(data []byte) ([]byte, error) { + return nil, errors.New("lzo compression is disable in this build with no_gpl") +} diff --git a/low/reader.go b/low/reader.go index 85e45d8..1f415ea 100644 --- a/low/reader.go +++ b/low/reader.go @@ -55,9 +55,27 @@ func NewReader(r io.ReaderAt) (rdr *Reader, err error) { if !rdr.Superblock.ValidVersion() { return nil, ErrorVersion } - rdr.d, err = decompress.GetDecompressor(rdr.Superblock.CompType) - if err != nil { - return nil, err + switch rdr.Superblock.CompType { + case ZlibCompression: + rdr.d = decompress.Zlib{} + case LZMACompression: + rdr.d, err = decompress.NewLzma() + if err != nil { + return nil, err + } + case LZOCompression: + rdr.d, err = decompress.NewLzo() + if err != nil { + return nil, err + } + case XZCompression: + rdr.d = decompress.Xz{} + case LZ4Compression: + rdr.d = decompress.Lz4{} + case ZSTDCompression: + rdr.d = decompress.Zstd{} + default: + return nil, errors.New("invalid compression type. possible corrupted archive") } rdr.Root, err = rdr.directoryFromRef(rdr.Superblock.RootInodeRef, "") if err != nil { From 4490fc3873f1fe71c94fda5eea783a654bce66c5 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Thu, 10 Apr 2025 02:15:24 -0500 Subject: [PATCH 23/32] Removed all the pointers --- file.go | 68 ++++++++++++++++++++++-------------------- fs.go | 38 +++++++++++++---------- low/data/fullreader.go | 18 +++++++++-- low/data/reader.go | 14 +++++++-- low/directory.go | 4 +-- low/file_base.go | 40 ++++++++++++------------- low/inode.go | 4 +-- low/reader.go | 21 +++++++------ low/reader_test.go | 8 ++--- reader.go | 16 +++++----- 10 files changed, 132 insertions(+), 99 deletions(-) diff --git a/file.go b/file.go index c3ebf6f..8c99b27 100644 --- a/file.go +++ b/file.go @@ -19,49 +19,47 @@ import ( // File represents a file inside a squashfs archive. type File struct { - full *data.FullReader - rdr *data.Reader - parent *FS + full data.FullReader + rdr data.Reader + rdrInit bool + parent FS r *Reader b squashfslow.FileBase dirsRead int } // Creates a new *File from the given *squashfs.Base -func (r *Reader) FileFromBase(b squashfslow.FileBase, parent *FS) *File { - return &File{ +func (r *Reader) FileFromBase(b squashfslow.FileBase, parent FS) File { + return File{ b: b, parent: parent, r: r, } } -func (f *File) FS() (*FS, error) { +func (f File) FS() (FS, error) { if !f.IsDir() { - return nil, errors.New("not a directory") + return FS{}, errors.New("not a directory") } - d, err := f.b.ToDir(&f.r.Low) + d, err := f.b.ToDir(f.r.Low) if err != nil { - return nil, err + return FS{}, err } - return &FS{d: d, parent: f.parent, r: f.r}, nil + return FS{d: d, parent: &f.parent, r: f.r}, nil } // Closes the underlying readers. // Further calls to Read and WriteTo will re-create the readers. // Never returns an error. func (f *File) Close() error { - if f.rdr != nil { - return f.rdr.Close() - } - f.rdr = nil - f.full = nil + f.rdr.Close() + f.full.Close() return nil } // Returns the file the symlink points to. // If the file isn't a symlink, or points to a file outside the archive, returns nil. -func (f *File) GetSymlinkFile() fs.File { +func (f File) GetSymlinkFile() fs.File { if !f.IsSymlink() { return nil } @@ -76,21 +74,21 @@ func (f *File) GetSymlinkFile() fs.File { } // Returns whether the file is a directory. -func (f *File) IsDir() bool { +func (f File) IsDir() bool { return f.b.IsDir() } // Returns whether the file is a regular file. -func (f *File) IsRegular() bool { +func (f File) IsRegular() bool { return f.b.IsRegular() } // Returns whether the file is a symlink. -func (f *File) IsSymlink() bool { +func (f File) IsSymlink() bool { return f.b.Inode.Type == inode.Sym || f.b.Inode.Type == inode.ESym } -func (f *File) Mode() fs.FileMode { +func (f File) Mode() fs.FileMode { return f.b.Inode.Mode() } @@ -99,7 +97,7 @@ func (f *File) Read(b []byte) (int, error) { if !f.IsRegular() { return 0, errors.New("file is not a regular file") } - if f.rdr == nil { + if !f.rdrInit { err := f.initializeReaders() if err != nil { return 0, err @@ -114,7 +112,7 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) { if !f.IsDir() { return nil, errors.New("file is not a directory") } - d, err := f.b.ToDir(&f.r.Low) + d, err := f.b.ToDir(f.r.Low) if err != nil { return nil, err } @@ -141,7 +139,7 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) { } // Returns the file's fs.FileInfo -func (f *File) Stat() (fs.FileInfo, error) { +func (f File) Stat() (fs.FileInfo, error) { uid, err := f.b.Uid(&f.r.Low) if err != nil { return nil, err @@ -154,7 +152,7 @@ func (f *File) Stat() (fs.FileInfo, error) { } // SymlinkPath returns the symlink's target path. Is the File isn't a symlink, returns an empty string. -func (f *File) SymlinkPath() string { +func (f File) SymlinkPath() string { switch f.b.Inode.Type { case inode.Sym: return string(f.b.Inode.Data.(inode.Symlink).Target) @@ -170,7 +168,7 @@ func (f *File) WriteTo(w io.Writer) (int64, error) { if !f.IsRegular() { return 0, errors.New("file is not a regular file") } - if f.full == nil { + if !f.rdrInit { err := f.initializeReaders() if err != nil { return 0, err @@ -181,11 +179,17 @@ func (f *File) WriteTo(w io.Writer) (int64, error) { func (f *File) initializeReaders() error { var err error - f.rdr, f.full, err = f.b.GetRegFileReaders(&f.r.Low) + f.rdr, f.full, err = f.b.GetRegFileReaders(f.r.Low) + if err == nil { + f.rdrInit = true + } else { + f.rdr.Close() + f.full.Close() + } return err } -func (f *File) deviceDevices() (maj uint32, min uint32) { +func (f File) deviceDevices() (maj uint32, min uint32) { var dev uint32 switch f.b.Inode.Type { case inode.Char, inode.Block: @@ -196,8 +200,8 @@ func (f *File) deviceDevices() (maj uint32, min uint32) { return dev >> 8, dev & 0x000FF } -func (f *File) path() string { - if f.parent == nil { +func (f File) path() string { + if f.parent.d.Name == "" { return f.b.Name } return filepath.Join(f.parent.path(), f.b.Name) @@ -205,13 +209,13 @@ func (f *File) path() string { // Extract the file to the given folder. If the file is a folder, the folder's contents will be extracted to the folder. // Uses default extraction options. -func (f *File) Extract(folder string) error { +func (f File) Extract(folder string) error { return f.ExtractWithOptions(folder, DefaultOptions()) } // Extract the file to the given folder. If the file is a folder, the folder's contents will be extracted to the folder. // Allows setting various extraction options via ExtractionOptions. -func (f *File) ExtractWithOptions(path string, op *ExtractionOptions) error { +func (f File) ExtractWithOptions(path string, op *ExtractionOptions) error { if op.manager == nil { op.manager = routinemanager.NewManager(op.SimultaneousFiles) if op.LogOutput != nil { @@ -227,7 +231,7 @@ func (f *File) ExtractWithOptions(path string, op *ExtractionOptions) error { } switch f.b.Inode.Type { case inode.Dir, inode.EDir: - d, err := f.b.ToDir(&f.r.Low) + d, err := f.b.ToDir(f.r.Low) if err != nil { if op.Verbose { log.Println("Failed to create squashfs.Directory for", path) diff --git a/fs.go b/fs.go index e1a282a..5971916 100644 --- a/fs.go +++ b/fs.go @@ -21,11 +21,11 @@ type FS struct { } // Creates a new *FS from the given squashfs.directory -func (r *Reader) FSFromDirectory(d squashfslow.Directory, parent *FS) *FS { - return &FS{ +func (r *Reader) FSFromDirectory(d squashfslow.Directory, parent FS) FS { + return FS{ d: d, r: r, - parent: parent, + parent: &parent, } } @@ -90,7 +90,7 @@ func (f *FS) Glob(pattern string) (out []string, err error) { } // Opens the file at name. Returns a *File as an fs.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) { return nil, &fs.PathError{ @@ -142,7 +142,7 @@ func (f *FS) Open(name string) (fs.File, error) { Err: fs.ErrNotExist, } } - d, err := b.ToDir(&f.r.Low) + d, err := b.ToDir(f.r.Low) if err != nil { return nil, err } @@ -151,7 +151,7 @@ func (f *FS) Open(name string) (fs.File, error) { // Returns all DirEntry's for the directory at name. // 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) { return nil, &fs.PathError{ @@ -171,7 +171,7 @@ func (f *FS) ReadDir(name string) ([]fs.DirEntry, error) { } // Returns the contents of the file at name. -func (f *FS) ReadFile(name string) (out []byte, err error) { +func (f FS) ReadFile(name string) (out []byte, err error) { name = filepath.Clean(name) if !fs.ValidPath(name) { return nil, &fs.PathError{ @@ -194,7 +194,7 @@ func (f *FS) ReadFile(name string) (out []byte, err error) { } // 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(name) if !fs.ValidPath(name) { return nil, &fs.PathError{ @@ -214,7 +214,7 @@ func (f *FS) Stat(name string) (fs.FileInfo, error) { } // 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) { return nil, &fs.PathError{ @@ -242,26 +242,32 @@ func (f *FS) Sub(dir string) (fs.FS, error) { // Extract the FS to the given folder. If the file is a folder, the folder's contents will be extracted to the folder. // Uses default extraction options. -func (f *FS) Extract(folder string) error { +func (f FS) Extract(folder string) error { return f.File().Extract(folder) } // Extract the FS to the given folder. If the file is a folder, the folder's contents will be extracted to the folder. // Allows setting various extraction options via ExtractionOptions. -func (f *FS) ExtractWithOptions(folder string, op *ExtractionOptions) error { +func (f FS) ExtractWithOptions(folder string, op *ExtractionOptions) error { return f.File().ExtractWithOptions(folder, op) } // Returns the FS as a *File -func (f *FS) File() *File { +func (f FS) File() *File { + if f.parent != nil { + return &File{ + b: f.d.FileBase, + parent: *f.parent, + r: f.r, + } + } return &File{ - b: f.d.FileBase, - parent: f.parent, - r: f.r, + b: f.d.FileBase, + r: f.r, } } -func (f *FS) path() string { +func (f FS) path() string { if f.parent == nil { return f.d.Name } diff --git a/low/data/fullreader.go b/low/data/fullreader.go index 1e41eba..f016a57 100644 --- a/low/data/fullreader.go +++ b/low/data/fullreader.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "errors" "io" + "io/fs" "math" "runtime" "sync" @@ -23,10 +24,11 @@ type FullReader struct { finalBlockSize uint64 blockSize uint32 goroutineLimit uint16 + closed bool } -func NewFullReader(r io.ReaderAt, initialOffset int64, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) *FullReader { - return &FullReader{ +func NewFullReader(r io.ReaderAt, initialOffset int64, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) FullReader { + return FullReader{ r: r, d: d, sizes: sizes, @@ -37,6 +39,15 @@ func NewFullReader(r io.ReaderAt, initialOffset int64, d decompress.Decompressor } } +func (r *FullReader) Close() error { + r.closed = true + r.r = nil + r.d = nil + r.frag = nil + r.sizes = nil + return nil +} + func (r *FullReader) AddFrag(frag FragReaderConstructor) { r.frag = frag } @@ -77,6 +88,9 @@ func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, re } func (r FullReader) WriteTo(w io.Writer) (int64, error) { + if r.closed { + return 0, fs.ErrClosed + } // if wa, is := w.(io.WriterAt); is { // return r.writeToWriteAt(wa) // } diff --git a/low/data/reader.go b/low/data/reader.go index e556369..ba593ac 100644 --- a/low/data/reader.go +++ b/low/data/reader.go @@ -3,6 +3,7 @@ package data import ( "encoding/binary" "io" + "io/fs" "github.com/CalebQ42/squashfs/internal/decompress" ) @@ -17,10 +18,11 @@ type Reader struct { curIndex uint64 finalBlockSize uint64 blockSize uint32 + closed bool } -func NewReader(r io.Reader, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) *Reader { - return &Reader{ +func NewReader(r io.Reader, d decompress.Decompressor, sizes []uint32, finalBlockSize uint64, blockSize uint32) Reader { + return Reader{ r: r, d: d, sizes: sizes, @@ -66,6 +68,9 @@ func (r *Reader) advance() error { } func (r *Reader) Read(b []byte) (int, error) { + if r.closed { + return 0, fs.ErrClosed + } curRead := 0 var toRead int for curRead < len(b) { @@ -83,6 +88,9 @@ func (r *Reader) Read(b []byte) (int, error) { } func (r *Reader) Close() error { + r.closed = true + r.r = nil + r.d = nil if r.frag != nil { if l, ok := r.frag.(*io.LimitedReader); ok { if cl, ok := l.R.(io.Closer); ok { @@ -90,6 +98,8 @@ func (r *Reader) Close() error { } } } + r.frag = nil + r.sizes = nil r.dat = nil return nil } diff --git a/low/directory.go b/low/directory.go index 097078b..07f0c80 100644 --- a/low/directory.go +++ b/low/directory.go @@ -18,7 +18,7 @@ type Directory struct { Entries []directory.Entry } -func (r *Reader) directoryFromRef(ref uint64, name string) (Directory, error) { +func (r Reader) directoryFromRef(ref uint64, name string) (Directory, error) { i, err := r.InodeFromRef(ref) if err != nil { return Directory{}, err @@ -54,7 +54,7 @@ func (r *Reader) directoryFromRef(ref uint64, name string) (Directory, error) { }, nil } -func (d *Directory) Open(r *Reader, path string) (FileBase, error) { +func (d Directory) Open(r Reader, path string) (FileBase, error) { path = filepath.Clean(path) if path == "." || path == "" { return d.FileBase, nil diff --git a/low/file_base.go b/low/file_base.go index a095276..90c9de3 100644 --- a/low/file_base.go +++ b/low/file_base.go @@ -16,11 +16,11 @@ type FileBase struct { Name string } -func (r *Reader) BaseFromInode(i inode.Inode, name string) FileBase { +func (r Reader) BaseFromInode(i inode.Inode, name string) FileBase { return FileBase{Inode: i, Name: name} } -func (r *Reader) BaseFromEntry(e directory.Entry) (FileBase, error) { +func (r Reader) BaseFromEntry(e directory.Entry) (FileBase, error) { in, err := r.InodeFromEntry(e) if err != nil { return FileBase{}, err @@ -28,7 +28,7 @@ func (r *Reader) BaseFromEntry(e directory.Entry) (FileBase, error) { return FileBase{Inode: in, Name: e.Name}, nil } -func (r *Reader) BaseFromRef(ref uint64, name string) (FileBase, error) { +func (r Reader) BaseFromRef(ref uint64, name string) (FileBase, error) { in, err := r.InodeFromRef(ref) if err != nil { return FileBase{}, err @@ -36,19 +36,19 @@ func (r *Reader) BaseFromRef(ref uint64, name string) (FileBase, error) { return FileBase{Inode: in, Name: name}, nil } -func (b *FileBase) Uid(r *Reader) (uint32, error) { +func (b FileBase) Uid(r *Reader) (uint32, error) { return r.Id(b.Inode.UidInd) } -func (b *FileBase) Gid(r *Reader) (uint32, error) { +func (b FileBase) Gid(r *Reader) (uint32, error) { return r.Id(b.Inode.GidInd) } -func (b *FileBase) IsDir() bool { +func (b FileBase) IsDir() bool { return b.Inode.Type == inode.Dir || b.Inode.Type == inode.EDir } -func (b *FileBase) ToDir(r *Reader) (Directory, error) { +func (b FileBase) ToDir(r Reader) (Directory, error) { var blockStart uint32 var size uint32 var offset uint16 @@ -75,18 +75,18 @@ func (b *FileBase) ToDir(r *Reader) (Directory, error) { return Directory{}, err } return Directory{ - FileBase: *b, + FileBase: b, Entries: entries, }, nil } -func (b *FileBase) IsRegular() bool { +func (b FileBase) IsRegular() bool { return b.Inode.Type == inode.Fil || b.Inode.Type == inode.EFil } -func (b *FileBase) GetRegFileReaders(r *Reader) (*data.Reader, *data.FullReader, error) { +func (b FileBase) GetRegFileReaders(r Reader) (data.Reader, data.FullReader, error) { if !b.IsRegular() { - return nil, nil, errors.New("not a regular file") + return data.Reader{}, data.FullReader{}, errors.New("not a regular file") } var blockStart uint64 var fragIndex uint32 @@ -113,13 +113,13 @@ func (b *FileBase) GetRegFileReaders(r *Reader) (*data.Reader, *data.FullReader, } frag := data.NewReader(toreader.NewReader(r.r, int64(ent.Start)), r.d, []uint32{ent.Size}, uint64(r.Superblock.BlockSize), r.Superblock.BlockSize) frag.Read(make([]byte, fragOffset)) - return io.LimitReader(frag, int64(fragSize)), nil + return io.LimitReader(&frag, int64(fragSize)), nil } outRdr := data.NewReader(toreader.NewReader(r.r, int64(blockStart)), r.d, sizes, fragSize, r.Superblock.BlockSize) if fragIndex != 0xffffffff { f, err := frag() if err != nil { - return nil, nil, err + return data.Reader{}, data.FullReader{}, err } outRdr.AddFrag(f) } @@ -130,9 +130,9 @@ func (b *FileBase) GetRegFileReaders(r *Reader) (*data.Reader, *data.FullReader, return outRdr, outFull, nil } -func (b *FileBase) GetFullReader(r *Reader) (*data.FullReader, error) { +func (b *FileBase) GetFullReader(r *Reader) (data.FullReader, error) { if !b.IsRegular() { - return nil, errors.New("not a regular file") + return data.FullReader{}, errors.New("not a regular file") } var blockStart uint64 var fragIndex uint32 @@ -161,15 +161,15 @@ func (b *FileBase) GetFullReader(r *Reader) (*data.FullReader, error) { } frag := data.NewReader(toreader.NewReader(r.r, int64(ent.Start)), r.d, []uint32{ent.Size}, uint64(r.Superblock.BlockSize), r.Superblock.BlockSize) frag.Read(make([]byte, fragOffset)) - return io.LimitReader(frag, int64(fragSize)), nil + return io.LimitReader(&frag, int64(fragSize)), nil }) } return outFull, nil } -func (b *FileBase) GetReader(r *Reader) (*data.Reader, error) { +func (b *FileBase) GetReader(r *Reader) (data.Reader, error) { if !b.IsRegular() { - return nil, errors.New("not a regular file") + return data.Reader{}, errors.New("not a regular file") } var blockStart uint64 var fragIndex uint32 @@ -193,11 +193,11 @@ func (b *FileBase) GetReader(r *Reader) (*data.Reader, error) { if fragIndex != 0xffffffff { ent, err := r.fragEntry(fragIndex) if err != nil { - return nil, err + return data.Reader{}, err } frag := data.NewReader(toreader.NewReader(r.r, int64(ent.Start)), r.d, []uint32{ent.Size}, uint64(r.Superblock.BlockSize), r.Superblock.BlockSize) frag.Read(make([]byte, fragOffset)) - outRdr.AddFrag(io.LimitReader(frag, int64(fragSize))) + outRdr.AddFrag(io.LimitReader(&frag, int64(fragSize))) } return outRdr, nil } diff --git a/low/inode.go b/low/inode.go index 494e428..8780feb 100644 --- a/low/inode.go +++ b/low/inode.go @@ -7,7 +7,7 @@ import ( "github.com/CalebQ42/squashfs/low/inode" ) -func (r *Reader) InodeFromRef(ref uint64) (inode.Inode, error) { +func (r Reader) InodeFromRef(ref uint64) (inode.Inode, error) { offset, meta := (ref>>16)+r.Superblock.InodeTableStart, ref&0xFFFF rdr := metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d) defer rdr.Close() @@ -18,7 +18,7 @@ func (r *Reader) InodeFromRef(ref uint64) (inode.Inode, error) { return inode.Read(rdr, r.Superblock.BlockSize) } -func (r *Reader) InodeFromEntry(e directory.Entry) (inode.Inode, error) { +func (r Reader) InodeFromEntry(e directory.Entry) (inode.Inode, error) { rdr := metadata.NewReader(toreader.NewReader(r.r, int64(r.Superblock.InodeTableStart)+int64(e.BlockStart)), r.d) defer rdr.Close() rdr.Read(make([]byte, e.Offset)) diff --git a/low/reader.go b/low/reader.go index 1f415ea..c40d277 100644 --- a/low/reader.go +++ b/low/reader.go @@ -39,21 +39,20 @@ type Reader struct { Superblock superblock } -func NewReader(r io.ReaderAt) (rdr *Reader, err error) { - rdr = new(Reader) +func NewReader(r io.ReaderAt) (rdr Reader, err error) { rdr.r = r err = binary.Read(toreader.NewReader(r, 0), binary.LittleEndian, &rdr.Superblock) if err != nil { - return nil, errors.Join(errors.New("failed to read superblock"), err) + return rdr, errors.Join(errors.New("failed to read superblock"), err) } if !rdr.Superblock.ValidMagic() { - return nil, ErrorMagic + return rdr, ErrorMagic } if !rdr.Superblock.ValidBlockLog() { - return nil, ErrorLog + return rdr, ErrorLog } if !rdr.Superblock.ValidVersion() { - return nil, ErrorVersion + return rdr, ErrorVersion } switch rdr.Superblock.CompType { case ZlibCompression: @@ -61,12 +60,12 @@ func NewReader(r io.ReaderAt) (rdr *Reader, err error) { case LZMACompression: rdr.d, err = decompress.NewLzma() if err != nil { - return nil, err + return rdr, err } case LZOCompression: rdr.d, err = decompress.NewLzo() if err != nil { - return nil, err + return rdr, err } case XZCompression: rdr.d = decompress.Xz{} @@ -75,11 +74,11 @@ func NewReader(r io.ReaderAt) (rdr *Reader, err error) { case ZSTDCompression: rdr.d = decompress.Zstd{} default: - return nil, errors.New("invalid compression type. possible corrupted archive") + return rdr, errors.New("invalid compression type. possible corrupted archive") } rdr.Root, err = rdr.directoryFromRef(rdr.Superblock.RootInodeRef, "") if err != nil { - return nil, errors.Join(errors.New("failed to read root directory"), err) + return rdr, errors.Join(errors.New("failed to read root directory"), err) } return } @@ -207,7 +206,7 @@ func (r *Reader) inodeRef(i uint32) (uint64, error) { return r.exportTable[i], nil } -func (r *Reader) Inode(i uint32) (inode.Inode, error) { +func (r Reader) Inode(i uint32) (inode.Inode, error) { ref, err := r.inodeRef(i) if err != nil { return inode.Inode{}, err diff --git a/low/reader_test.go b/low/reader_test.go index 6a01c09..403a7ba 100644 --- a/low/reader_test.go +++ b/low/reader_test.go @@ -77,7 +77,7 @@ func TestReader(t *testing.T) { path := filepath.Join(tmpDir, "extractTest") os.RemoveAll(path) os.MkdirAll(path, 0777) - err = extractToDir(rdr, &rdr.Root.FileBase, path) + err = extractToDir(rdr, rdr.Root.FileBase, path) t.Fatal(err) } @@ -101,11 +101,11 @@ func TestSingleFile(t *testing.T) { if err != nil { t.Fatal(err) } - err = extractToDir(rdr, &b, path) + err = extractToDir(rdr, b, path) t.Fatal(err) } -func extractToDir(rdr *Reader, b *FileBase, folder string) error { +func extractToDir(rdr Reader, b FileBase, folder string) error { path := filepath.Join(folder, b.Name) if b.IsDir() { d, err := b.ToDir(rdr) @@ -122,7 +122,7 @@ func extractToDir(rdr *Reader, b *FileBase, folder string) error { if err != nil { return err } - err = extractToDir(rdr, &nestBast, path) + err = extractToDir(rdr, nestBast, path) if err != nil { return err } diff --git a/reader.go b/reader.go index a31a6be..94361f0 100644 --- a/reader.go +++ b/reader.go @@ -9,26 +9,26 @@ import ( ) type Reader struct { - *FS + FS Low squashfslow.Reader } -func NewReader(r io.ReaderAt) (*Reader, error) { +func NewReader(r io.ReaderAt) (Reader, error) { rdr, err := squashfslow.NewReader(r) if err != nil { - return nil, err + return Reader{}, err } - out := &Reader{ - Low: *rdr, + out := Reader{ + Low: rdr, } - out.FS = &FS{ + out.FS = FS{ d: rdr.Root, - r: out, + r: &out, } return out, nil } -func NewReaderAtOffset(r io.ReaderAt, offset int64) (*Reader, error) { +func NewReaderAtOffset(r io.ReaderAt, offset int64) (Reader, error) { return NewReader(toreader.NewOffsetReader(r, offset)) } From 6b0e9ef2c69c59b6bcb739b18230b130754117d7 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Thu, 10 Apr 2025 06:26:41 -0500 Subject: [PATCH 24/32] Reduce use of binary.Read and, by extention, reflection --- internal/metadata/reader.go | 7 ++--- low/data/fullreader.go | 4 +-- low/data/reader.go | 3 +-- low/file_base.go | 4 +-- low/inode/dir.go | 51 ++++++++++++++++++++++-------------- low/inode/file.go | 22 +++++++++++----- squashfs.test | Bin 0 -> 10418133 bytes squashfs_test.go | 20 ++++++++++++++ 8 files changed, 75 insertions(+), 36 deletions(-) create mode 100755 squashfs.test diff --git a/internal/metadata/reader.go b/internal/metadata/reader.go index 5a810d1..e91c0a6 100644 --- a/internal/metadata/reader.go +++ b/internal/metadata/reader.go @@ -23,14 +23,15 @@ func NewReader(r io.Reader, d decompress.Decompressor) *Reader { func (r *Reader) advance() error { r.curOffset = 0 - var size uint16 - err := binary.Read(r.r, binary.LittleEndian, &size) + dat := make([]byte, 2) + _, err := r.r.Read(dat) if err != nil { return err } + size := binary.LittleEndian.Uint16(dat) realSize := size &^ 0x8000 r.dat = make([]byte, realSize) - err = binary.Read(r.r, binary.LittleEndian, &r.dat) + _, err = r.r.Read(r.dat) if err != nil { return err } diff --git a/low/data/fullreader.go b/low/data/fullreader.go index f016a57..8ab50d6 100644 --- a/low/data/fullreader.go +++ b/low/data/fullreader.go @@ -1,7 +1,6 @@ package data import ( - "encoding/binary" "errors" "io" "io/fs" @@ -10,7 +9,6 @@ import ( "sync" "github.com/CalebQ42/squashfs/internal/decompress" - "github.com/CalebQ42/squashfs/internal/toreader" ) type FragReaderConstructor func() (io.Reader, error) @@ -80,7 +78,7 @@ func (r FullReader) process(index uint64, fileOffset uint64, pool *sync.Pool, re return } ret.data = make([]byte, realSize) - ret.err = binary.Read(toreader.NewReader(r.r, int64(r.initialOffset)+int64(fileOffset)), binary.LittleEndian, &ret.data) + _, ret.err = r.r.ReadAt(ret.data, r.initialOffset+int64(fileOffset)) if r.sizes[index] == realSize { ret.data, ret.err = r.d.Decompress(ret.data) } diff --git a/low/data/reader.go b/low/data/reader.go index ba593ac..898ab09 100644 --- a/low/data/reader.go +++ b/low/data/reader.go @@ -1,7 +1,6 @@ package data import ( - "encoding/binary" "io" "io/fs" @@ -56,7 +55,7 @@ func (r *Reader) advance() error { return nil } r.dat = make([]byte, realSize) - err = binary.Read(r.r, binary.LittleEndian, &r.dat) + _, err = r.r.Read(r.dat) if err != nil { return err } diff --git a/low/file_base.go b/low/file_base.go index 90c9de3..96aa5ef 100644 --- a/low/file_base.go +++ b/low/file_base.go @@ -130,7 +130,7 @@ func (b FileBase) GetRegFileReaders(r Reader) (data.Reader, data.FullReader, err return outRdr, outFull, nil } -func (b *FileBase) GetFullReader(r *Reader) (data.FullReader, error) { +func (b FileBase) GetFullReader(r *Reader) (data.FullReader, error) { if !b.IsRegular() { return data.FullReader{}, errors.New("not a regular file") } @@ -167,7 +167,7 @@ func (b *FileBase) GetFullReader(r *Reader) (data.FullReader, error) { return outFull, nil } -func (b *FileBase) GetReader(r *Reader) (data.Reader, error) { +func (b FileBase) GetReader(r *Reader) (data.Reader, error) { if !b.IsRegular() { return data.Reader{}, errors.New("not a regular file") } diff --git a/low/inode/dir.go b/low/inode/dir.go index bffe973..ec5ff7e 100644 --- a/low/inode/dir.go +++ b/low/inode/dir.go @@ -13,7 +13,7 @@ type Directory struct { ParentNum uint32 } -type eDirectoryInit struct { +type EDirectory struct { LinkCount uint32 Size uint32 BlockStart uint32 @@ -21,42 +21,55 @@ type eDirectoryInit struct { IndCount uint16 Offset uint16 XattrInd uint32 -} - -type EDirectory struct { - eDirectoryInit - Indexes []DirectoryIndex -} - -type directoryIndexInit struct { - Ind uint32 - Start uint32 - NameSize uint32 + Indexes []DirectoryIndex } type DirectoryIndex struct { - directoryIndexInit - Name []byte + Ind uint32 + Start uint32 + NameSize uint32 + Name []byte } func ReadDir(r io.Reader) (d Directory, err error) { - err = binary.Read(r, binary.LittleEndian, &d) + dat := make([]byte, 16) + _, err = r.Read(dat) + if err != nil { + return + } + d.BlockStart = binary.LittleEndian.Uint32(dat) + d.LinkCount = binary.LittleEndian.Uint32(dat[4:]) + d.Size = binary.LittleEndian.Uint16(dat[8:]) + d.Offset = binary.LittleEndian.Uint16(dat[10:]) + d.ParentNum = binary.LittleEndian.Uint32(dat[12:]) return } func ReadEDir(r io.Reader) (d EDirectory, err error) { - err = binary.Read(r, binary.LittleEndian, &d.eDirectoryInit) + dat := make([]byte, 24) + _, err = r.Read(dat) if err != nil { return } + d.LinkCount = binary.LittleEndian.Uint32(dat) + d.Size = binary.LittleEndian.Uint32(dat[4:]) + d.BlockStart = binary.LittleEndian.Uint32(dat[8:]) + d.ParentNum = binary.LittleEndian.Uint32(dat[12:]) + d.IndCount = binary.LittleEndian.Uint16(dat[16:]) + d.Offset = binary.LittleEndian.Uint16(dat[18:]) + d.XattrInd = binary.LittleEndian.Uint32(dat[20:]) d.Indexes = make([]DirectoryIndex, d.IndCount) - for i := range d.Indexes { - err = binary.Read(r, binary.LittleEndian, &d.Indexes[i].directoryIndexInit) + for i := range d.IndCount { + dat = make([]byte, 12) + _, err = r.Read(dat) if err != nil { return } + d.Indexes[i].Ind = binary.LittleEndian.Uint32(dat) + d.Indexes[i].Start = binary.LittleEndian.Uint32(dat[4:]) + d.Indexes[i].NameSize = binary.LittleEndian.Uint32(dat[8:]) d.Indexes[i].Name = make([]byte, d.Indexes[i].NameSize+1) - err = binary.Read(r, binary.LittleEndian, &d.Indexes[i].Name) + _, err = r.Read(d.Indexes[i].Name) if err != nil { return } diff --git a/low/inode/file.go b/low/inode/file.go index 1b4d461..2b81014 100644 --- a/low/inode/file.go +++ b/low/inode/file.go @@ -6,15 +6,11 @@ import ( "math" ) -type fileInit struct { +type File struct { BlockStart uint32 FragInd uint32 FragOffset uint32 Size uint32 -} - -type File struct { - fileInit BlockSizes []uint32 } @@ -34,16 +30,28 @@ type EFile struct { } func ReadFile(r io.Reader, blockSize uint32) (f File, err error) { - err = binary.Read(r, binary.LittleEndian, &f.fileInit) + dat := make([]byte, 16) + _, err = r.Read(dat) if err != nil { return } + f.BlockStart = binary.LittleEndian.Uint32(dat) + f.FragInd = binary.LittleEndian.Uint32(dat[4:]) + f.FragOffset = binary.LittleEndian.Uint32(dat[8:]) + f.Size = binary.LittleEndian.Uint32(dat[12:]) toRead := int(math.Floor(float64(f.Size) / float64(blockSize))) if f.FragInd == 0xFFFFFFFF && f.Size%blockSize > 0 { toRead++ } + dat = make([]byte, toRead*4) + _, err = r.Read(dat) + if err != nil { + return + } f.BlockSizes = make([]uint32, toRead) - err = binary.Read(r, binary.LittleEndian, &f.BlockSizes) + for i := range toRead { + f.BlockSizes[i] = binary.LittleEndian.Uint32(dat[i*4:]) + } return } diff --git a/squashfs.test b/squashfs.test new file mode 100755 index 0000000000000000000000000000000000000000..22a7559586e3047a4931fe9cbd94d1f682d1ed71 GIT binary patch literal 10418133 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%0Ab~(-+)~_3h^J?eyk&X$vZTAs*@6qXO#M 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