Re-wrote metadata reader. Seems to work now.
Need to work on test now.
This commit is contained in:
+27
-32
@@ -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)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
return
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Reader) Read(p []byte) (n int, err error) {
|
func (r *Reader) Read(p []byte) (n int, err error) {
|
||||||
|
if r.cur == nil {
|
||||||
|
err = r.advance()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user