Initial work

Create Reader
Pulled back in Inode decoding and superblock
New Data and Metadata readers
Added getting of id, fragment, and export table data lazily
Added README to squashfs/squashfs
This commit is contained in:
Caleb Gardner
2023-12-23 02:48:54 -06:00
parent d4d1b2c2b2
commit 707391baba
23 changed files with 860 additions and 2 deletions
+73
View File
@@ -0,0 +1,73 @@
package data
import (
"encoding/binary"
"io"
"github.com/CalebQ42/squashfs/internal/decompress"
)
type Reader struct {
r io.Reader
d decompress.Decompressor
frag io.Reader
sizes []uint32
dat []byte
curOffset uint16
curIndex uint64
}
func NewReader(r io.Reader, d decompress.Decompressor, sizes []uint32) (*Reader, error) {
return &Reader{
r: r,
d: d,
sizes: sizes,
}, nil
}
func (r *Reader) AddFrag(fragRdr io.Reader) {
r.frag = fragRdr
}
func (r *Reader) advance() error {
r.curOffset = 0
defer func() { r.curIndex++ }()
var err error
if r.curIndex == uint64(len(r.sizes))-1 && r.frag != nil {
r.dat, err = io.ReadAll(r.frag)
return err
} else if r.curIndex >= uint64(len(r.sizes))-1 {
return io.EOF
}
realSize := r.sizes[r.curIndex] &^ 0x8000
r.dat = make([]byte, realSize)
err = binary.Read(r.r, binary.LittleEndian, &r.dat)
if err != nil {
return err
}
if r.sizes[r.curIndex] != realSize {
return nil
}
r.dat, err = r.d.Decompress(r.dat)
return err
}
func (r *Reader) Read(b []byte) (int, error) {
curRead := 0
var toRead int
for curRead < len(b) {
if r.curOffset >= uint16(len(r.dat)) {
if err := r.advance(); err != nil {
return curRead, err
}
}
toRead = len(b) - curRead
if toRead > len(r.dat)-int(r.curOffset) {
toRead = len(r.dat) - int(r.curOffset)
}
copy(b[curRead:], r.dat[r.curOffset:int(r.curOffset)+toRead])
r.curOffset += uint16(toRead)
curRead += toRead
}
return curRead, nil
}
+5
View File
@@ -0,0 +1,5 @@
package decompress
type Decompressor interface {
Decompress([]byte) ([]byte, error)
}
+15
View File
@@ -0,0 +1,15 @@
package decompress
import (
"bytes"
"io"
"github.com/pierrec/lz4/v4"
)
type Lz4 struct{}
func (l Lz4) Decompress(data []byte) ([]byte, error) {
rdr := lz4.NewReader(bytes.NewReader(data))
return io.ReadAll(rdr)
}
+18
View File
@@ -0,0 +1,18 @@
package decompress
import (
"bytes"
"io"
"github.com/ulikunitz/xz/lzma"
)
type Lzma struct{}
func (l Lzma) Decompress(data []byte) ([]byte, error) {
rdr, err := lzma.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err
}
return io.ReadAll(rdr)
}
+13
View File
@@ -0,0 +1,13 @@
package decompress
import (
"bytes"
"github.com/rasky/go-lzo"
)
type Lzo struct{}
func (l Lzo) Decompress(data []byte) ([]byte, error) {
return lzo.Decompress1X(bytes.NewReader(data), len(data), 0)
}
+18
View File
@@ -0,0 +1,18 @@
package decompress
import (
"bytes"
"io"
"github.com/therootcompany/xz"
)
type Xz struct{}
func (x Xz) Decompress(data []byte) ([]byte, error) {
rdr, err := xz.NewReader(bytes.NewReader(data), 0)
if err != nil {
return nil, err
}
return io.ReadAll(rdr)
}
+18
View File
@@ -0,0 +1,18 @@
package decompress
import (
"bytes"
"compress/zlib"
"io"
)
type Zlib struct{}
func (z Zlib) Decompress(data []byte) ([]byte, error) {
rdr, err := zlib.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err
}
defer rdr.Close()
return io.ReadAll(rdr)
}
+19
View File
@@ -0,0 +1,19 @@
package decompress
import (
"bytes"
"io"
"github.com/klauspost/compress/zstd"
)
type Zstd struct{}
func (z Zstd) Decompress(data []byte) ([]byte, error) {
rdr, err := zstd.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err
}
defer rdr.Close()
return io.ReadAll(rdr)
}
+62
View File
@@ -0,0 +1,62 @@
package metadata
import (
"encoding/binary"
"io"
"github.com/CalebQ42/squashfs/internal/decompress"
)
type Reader struct {
r io.Reader
d decompress.Decompressor
dat []byte
curOffset uint16
}
func NewReader(r io.Reader, d decompress.Decompressor) *Reader {
return &Reader{
r: r,
d: d,
}
}
func (r *Reader) advance() error {
r.curOffset = 0
var size uint16
err := binary.Read(r.r, binary.LittleEndian, &size)
if err != nil {
return err
}
realSize := size &^ 0x8000
r.dat = make([]byte, realSize)
err = binary.Read(r.r, binary.LittleEndian, &r.dat)
if err != nil {
return err
}
if size != realSize {
return nil
}
r.dat, err = r.d.Decompress(r.dat)
return err
}
func (r *Reader) Read(b []byte) (int, error) {
curRead := 0
var toRead int
for curRead < len(b) {
if r.curOffset >= uint16(len(r.dat)) {
if err := r.advance(); err != nil {
return curRead, err
}
}
toRead = len(b) - curRead
if toRead > len(r.dat)-int(r.curOffset) {
toRead = len(r.dat) - int(r.curOffset)
}
copy(b[curRead:], r.dat[r.curOffset:int(r.curOffset)+toRead])
r.curOffset += uint16(toRead)
curRead += toRead
}
return curRead, nil
}
+21
View File
@@ -0,0 +1,21 @@
package toreader
import "io"
type Reader struct {
r io.ReaderAt
offset int64
}
func NewReader(r io.ReaderAt, start int64) *Reader {
return &Reader{
r: r,
offset: start,
}
}
func (r *Reader) Read(b []byte) (int, error) {
n, err := r.r.ReadAt(b, r.offset)
r.offset += int64(n)
return n, err
}