From 49595de3f2706a0a35b77cf6540ecfecf175a8ac Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Sat, 18 Jun 2022 14:31:17 -0500 Subject: [PATCH] Re-wrote metadata reader. Seems to work now. Need to work on test now. --- internal/metadata/reader.go | 59 +++++++++++++++++-------------------- reader.go | 27 ++++------------- reader_fs.go | 1 - reader_inode.go | 17 +++-------- squashfs_test.go | 3 +- 5 files changed, 38 insertions(+), 69 deletions(-) diff --git a/internal/metadata/reader.go b/internal/metadata/reader.go index 3496150..4567cbe 100644 --- a/internal/metadata/reader.go +++ b/internal/metadata/reader.go @@ -2,8 +2,6 @@ package metadata import ( "encoding/binary" - "errors" - "fmt" "io" "github.com/CalebQ42/squashfs/internal/decompress" @@ -15,54 +13,51 @@ type Reader struct { d decompress.Decompressor } -func NewReader(r io.Reader, d decompress.Decompressor) (*Reader, error) { - var out Reader - out.d = d - out.master = r - return &out, out.Advance() +func NewReader(master io.Reader, d decompress.Decompressor) *Reader { + return &Reader{ + master: master, + d: d, + } } -func (r *Reader) Advance() error { +func realSize(siz uint16) uint16 { + return siz &^ 0x8000 +} - //For some reason things get closed improperly and causes issues. - //NO IDEA HOW THIS IS HAPPENING. - - // if clr, ok := r.cur.(io.Closer); ok { - // clr.Close() - // r.cur = nil - // } - var size uint16 - err := binary.Read(r.master, binary.LittleEndian, &size) +func (r *Reader) advance() (err error) { + if clr, ok := r.cur.(io.Closer); ok { + clr.Close() + } + var raw uint16 + err = binary.Read(r.master, binary.LittleEndian, &raw) if err != nil { - return err - } - comp := size&0x8000 != 0x8000 - size &^= 0x8000 - if size > 8196 { - fmt.Println("uhoh") - return errors.New("AH") + return } + size := realSize(raw) r.cur = io.LimitReader(r.master, int64(size)) - if comp { + if size == raw { r.cur, err = r.d.Reader(r.cur) + } + return +} + +func (r *Reader) Read(p []byte) (n int, err error) { + if r.cur == nil { + err = r.advance() if err != nil { - return err + return } } - return nil -} - -func (r Reader) Read(p []byte) (n int, err error) { n, err = r.cur.Read(p) if err == io.EOF { - err = r.Advance() + err = r.advance() if err != nil { return } var tmpN int tmp := make([]byte, len(p)-n) tmpN, err = r.Read(tmp) - for i := range tmp { + for i := 0; i < tmpN; i++ { p[n+i] = tmp[i] } n += tmpN diff --git a/reader.go b/reader.go index 60dc5d1..b72383d 100644 --- a/reader.go +++ b/reader.go @@ -87,11 +87,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) { } squash.fragEntries = make([]fragEntry, squash.s.FragCount) if len(fragOffsets) == 1 { - var rdr *metadata.Reader - rdr, err = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[0])), squash.d) - if err != nil { - return nil, err - } + rdr := metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[0])), squash.d) err = binary.Read(rdr, binary.LittleEndian, &squash.fragEntries) if err != nil { return nil, err @@ -105,10 +101,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) { for i := range fragOffsets { curRead = uint16(math.Min(512, float64(toRead))) tmp = make([]fragEntry, curRead) - rdr, err = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[i])), squash.d) - if err != nil { - return nil, err - } + rdr = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[i])), squash.d) err = binary.Read(rdr, binary.LittleEndian, &tmp) if err != nil { return nil, err @@ -129,11 +122,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) { } squash.ids = make([]uint32, squash.s.IdCount) if len(idOffsets) == 1 { - var rdr *metadata.Reader - rdr, err = metadata.NewReader(toreader.NewReader(r, int64(idOffsets[0])), squash.d) - if err != nil { - return nil, err - } + rdr := metadata.NewReader(toreader.NewReader(r, int64(idOffsets[0])), squash.d) err = binary.Read(rdr, binary.LittleEndian, &squash.ids) if err != nil { return nil, err @@ -147,10 +136,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) { for i := range idOffsets { curRead = uint16(math.Min(2048, float64(toRead))) tmp = make([]uint32, curRead) - rdr, err = metadata.NewReader(toreader.NewReader(r, int64(idOffsets[i])), squash.d) - if err != nil { - return nil, err - } + rdr = metadata.NewReader(toreader.NewReader(r, int64(idOffsets[i])), squash.d) err = binary.Read(rdr, binary.LittleEndian, &tmp) if err != nil { return nil, err @@ -202,10 +188,7 @@ func (r *Reader) initExport() (err error) { var new []uint64 var rdr *metadata.Reader for i := range offsets { - rdr, err = metadata.NewReader(toreader.NewReader(r.r, int64(offsets[i])), r.d) - if err != nil { - return - } + rdr = metadata.NewReader(toreader.NewReader(r.r, int64(offsets[i])), r.d) toRead = uint32(math.Min(1024, float64(left))) new = make([]uint64, toRead) err = binary.Read(rdr, binary.LittleEndian, &new) diff --git a/reader_fs.go b/reader_fs.go index a1ed718..b1d1f77 100644 --- a/reader_fs.go +++ b/reader_fs.go @@ -79,7 +79,6 @@ func (f FS) Open(name string) (fs.File, error) { } return out, err } - // fmt.Println(f.e[i]) out, err := f.r.newFile(f.e[i], &f) if err != nil { err = &fs.PathError{ diff --git a/reader_inode.go b/reader_inode.go index cc444d2..f5f2144 100644 --- a/reader_inode.go +++ b/reader_inode.go @@ -13,10 +13,7 @@ import ( func (r Reader) inodeFromRef(ref uint64) (i inode.Inode, err error) { offset, meta := (ref>>16)+r.s.InodeTableStart, ref&0xFFFF - rdr, err := metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d) - if err != nil { - return - } + rdr := metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d) _, err = rdr.Read(make([]byte, meta)) if err != nil { return @@ -25,10 +22,7 @@ func (r Reader) inodeFromRef(ref uint64) (i inode.Inode, err error) { } func (r Reader) inodeFromDir(e directory.Entry) (i inode.Inode, err error) { - rdr, err := metadata.NewReader(toreader.NewReader(r.r, int64(uint64(e.BlockStart)+r.s.InodeTableStart)), r.d) - if err != nil { - return - } + rdr := metadata.NewReader(toreader.NewReader(r.r, int64(uint64(e.BlockStart)+r.s.InodeTableStart)), r.d) _, err = rdr.Read(make([]byte, e.Offset)) if err != nil { return @@ -103,11 +97,8 @@ func (r Reader) readDirectory(i inode.Inode) ([]directory.Entry, error) { } else { return nil, errors.New("readDirectory called on non-directory type") } - rdr, err := metadata.NewReader(toreader.NewReader(r.r, int64(offset+r.s.DirTableStart)), r.d) - if err != nil { - return nil, err - } - _, err = rdr.Read(make([]byte, blockOffset)) + rdr := metadata.NewReader(toreader.NewReader(r.r, int64(offset+r.s.DirTableStart)), r.d) + _, err := rdr.Read(make([]byte, blockOffset)) if err != nil { return nil, err } diff --git a/squashfs_test.go b/squashfs_test.go index d22c000..a7ef612 100644 --- a/squashfs_test.go +++ b/squashfs_test.go @@ -3,6 +3,7 @@ package squashfs_test //Actually proper tests go here. import ( + "fmt" "io" "io/fs" "net/http" @@ -89,7 +90,7 @@ func TestExtractQuick(t *testing.T) { squashFils := os.DirFS(unsquashPath) err = fs.WalkDir(squashFils, "", func(path string, d fs.DirEntry, err error) error { - t.Log(path) + fmt.Println(path) return nil }) if err != nil {