Re-wrote metadata reader. Seems to work now.

Need to work on test now.
This commit is contained in:
Caleb Gardner
2022-06-18 14:31:17 -05:00
parent 96b38935a6
commit 49595de3f2
5 changed files with 38 additions and 69 deletions
+27 -32
View File
@@ -2,8 +2,6 @@ package metadata
import ( import (
"encoding/binary" "encoding/binary"
"errors"
"fmt"
"io" "io"
"github.com/CalebQ42/squashfs/internal/decompress" "github.com/CalebQ42/squashfs/internal/decompress"
@@ -15,54 +13,51 @@ type Reader struct {
d decompress.Decompressor d decompress.Decompressor
} }
func NewReader(r io.Reader, d decompress.Decompressor) (*Reader, error) { func NewReader(master io.Reader, d decompress.Decompressor) *Reader {
var out Reader return &Reader{
out.d = d master: master,
out.master = r d: d,
return &out, out.Advance() }
} }
func (r *Reader) Advance() error { func realSize(siz uint16) uint16 {
return siz &^ 0x8000
}
//For some reason things get closed improperly and causes issues. func (r *Reader) advance() (err error) {
//NO IDEA HOW THIS IS HAPPENING. if clr, ok := r.cur.(io.Closer); ok {
clr.Close()
// if clr, ok := r.cur.(io.Closer); ok { }
// clr.Close() var raw uint16
// r.cur = nil err = binary.Read(r.master, binary.LittleEndian, &raw)
// }
var size uint16
err := binary.Read(r.master, binary.LittleEndian, &size)
if err != nil { if err != nil {
return err return
}
comp := size&0x8000 != 0x8000
size &^= 0x8000
if size > 8196 {
fmt.Println("uhoh")
return errors.New("AH")
} }
size := realSize(raw)
r.cur = io.LimitReader(r.master, int64(size)) r.cur = io.LimitReader(r.master, int64(size))
if comp { if size == raw {
r.cur, err = r.d.Reader(r.cur) 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 { if err != nil {
return err return
} }
} }
return nil
}
func (r Reader) Read(p []byte) (n int, err error) {
n, err = r.cur.Read(p) n, err = r.cur.Read(p)
if err == io.EOF { if err == io.EOF {
err = r.Advance() err = r.advance()
if err != nil { if err != nil {
return return
} }
var tmpN int var tmpN int
tmp := make([]byte, len(p)-n) tmp := make([]byte, len(p)-n)
tmpN, err = r.Read(tmp) tmpN, err = r.Read(tmp)
for i := range tmp { for i := 0; i < tmpN; i++ {
p[n+i] = tmp[i] p[n+i] = tmp[i]
} }
n += tmpN n += tmpN
+5 -22
View File
@@ -87,11 +87,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) {
} }
squash.fragEntries = make([]fragEntry, squash.s.FragCount) squash.fragEntries = make([]fragEntry, squash.s.FragCount)
if len(fragOffsets) == 1 { if len(fragOffsets) == 1 {
var rdr *metadata.Reader rdr := metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[0])), squash.d)
rdr, err = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[0])), squash.d)
if err != nil {
return nil, err
}
err = binary.Read(rdr, binary.LittleEndian, &squash.fragEntries) err = binary.Read(rdr, binary.LittleEndian, &squash.fragEntries)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -105,10 +101,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) {
for i := range fragOffsets { for i := range fragOffsets {
curRead = uint16(math.Min(512, float64(toRead))) curRead = uint16(math.Min(512, float64(toRead)))
tmp = make([]fragEntry, curRead) tmp = make([]fragEntry, curRead)
rdr, err = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[i])), squash.d) rdr = metadata.NewReader(toreader.NewReader(r, int64(fragOffsets[i])), squash.d)
if err != nil {
return nil, err
}
err = binary.Read(rdr, binary.LittleEndian, &tmp) err = binary.Read(rdr, binary.LittleEndian, &tmp)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -129,11 +122,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) {
} }
squash.ids = make([]uint32, squash.s.IdCount) squash.ids = make([]uint32, squash.s.IdCount)
if len(idOffsets) == 1 { if len(idOffsets) == 1 {
var rdr *metadata.Reader rdr := metadata.NewReader(toreader.NewReader(r, int64(idOffsets[0])), squash.d)
rdr, err = metadata.NewReader(toreader.NewReader(r, int64(idOffsets[0])), squash.d)
if err != nil {
return nil, err
}
err = binary.Read(rdr, binary.LittleEndian, &squash.ids) err = binary.Read(rdr, binary.LittleEndian, &squash.ids)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -147,10 +136,7 @@ func NewReader(r io.ReaderAt) (*Reader, error) {
for i := range idOffsets { for i := range idOffsets {
curRead = uint16(math.Min(2048, float64(toRead))) curRead = uint16(math.Min(2048, float64(toRead)))
tmp = make([]uint32, curRead) tmp = make([]uint32, curRead)
rdr, err = metadata.NewReader(toreader.NewReader(r, int64(idOffsets[i])), squash.d) rdr = metadata.NewReader(toreader.NewReader(r, int64(idOffsets[i])), squash.d)
if err != nil {
return nil, err
}
err = binary.Read(rdr, binary.LittleEndian, &tmp) err = binary.Read(rdr, binary.LittleEndian, &tmp)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -202,10 +188,7 @@ func (r *Reader) initExport() (err error) {
var new []uint64 var new []uint64
var rdr *metadata.Reader var rdr *metadata.Reader
for i := range offsets { for i := range offsets {
rdr, err = metadata.NewReader(toreader.NewReader(r.r, int64(offsets[i])), r.d) rdr = metadata.NewReader(toreader.NewReader(r.r, int64(offsets[i])), r.d)
if err != nil {
return
}
toRead = uint32(math.Min(1024, float64(left))) toRead = uint32(math.Min(1024, float64(left)))
new = make([]uint64, toRead) new = make([]uint64, toRead)
err = binary.Read(rdr, binary.LittleEndian, &new) err = binary.Read(rdr, binary.LittleEndian, &new)
-1
View File
@@ -79,7 +79,6 @@ func (f FS) Open(name string) (fs.File, error) {
} }
return out, err return out, err
} }
// fmt.Println(f.e[i])
out, err := f.r.newFile(f.e[i], &f) out, err := f.r.newFile(f.e[i], &f)
if err != nil { if err != nil {
err = &fs.PathError{ err = &fs.PathError{
+4 -13
View File
@@ -13,10 +13,7 @@ import (
func (r Reader) inodeFromRef(ref uint64) (i inode.Inode, err error) { func (r Reader) inodeFromRef(ref uint64) (i inode.Inode, err error) {
offset, meta := (ref>>16)+r.s.InodeTableStart, ref&0xFFFF offset, meta := (ref>>16)+r.s.InodeTableStart, ref&0xFFFF
rdr, err := metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d) rdr := metadata.NewReader(toreader.NewReader(r.r, int64(offset)), r.d)
if err != nil {
return
}
_, err = rdr.Read(make([]byte, meta)) _, err = rdr.Read(make([]byte, meta))
if err != nil { if err != nil {
return 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) { 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) rdr := metadata.NewReader(toreader.NewReader(r.r, int64(uint64(e.BlockStart)+r.s.InodeTableStart)), r.d)
if err != nil {
return
}
_, err = rdr.Read(make([]byte, e.Offset)) _, err = rdr.Read(make([]byte, e.Offset))
if err != nil { if err != nil {
return return
@@ -103,11 +97,8 @@ func (r Reader) readDirectory(i inode.Inode) ([]directory.Entry, error) {
} else { } else {
return nil, errors.New("readDirectory called on non-directory type") 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) rdr := metadata.NewReader(toreader.NewReader(r.r, int64(offset+r.s.DirTableStart)), r.d)
if err != nil { _, err := rdr.Read(make([]byte, blockOffset))
return nil, err
}
_, err = rdr.Read(make([]byte, blockOffset))
if err != nil { if err != nil {
return nil, err return nil, err
} }
+2 -1
View File
@@ -3,6 +3,7 @@ package squashfs_test
//Actually proper tests go here. //Actually proper tests go here.
import ( import (
"fmt"
"io" "io"
"io/fs" "io/fs"
"net/http" "net/http"
@@ -89,7 +90,7 @@ func TestExtractQuick(t *testing.T) {
squashFils := os.DirFS(unsquashPath) squashFils := os.DirFS(unsquashPath)
err = fs.WalkDir(squashFils, "", func(path string, d fs.DirEntry, err error) error { err = fs.WalkDir(squashFils, "", func(path string, d fs.DirEntry, err error) error {
t.Log(path) fmt.Println(path)
return nil return nil
}) })
if err != nil { if err != nil {