Somre more stuff for parsting
Working on metadata parsing Runnning into some Reader issues so I might create my own.
This commit is contained in:
@@ -1,8 +1,22 @@
|
||||
package squashfs
|
||||
|
||||
import "io"
|
||||
|
||||
const (
|
||||
zlibCompression = 1 + iota
|
||||
lzmaCompression
|
||||
lzoCompression
|
||||
xzCompression
|
||||
lz4Compression
|
||||
zstdCompression
|
||||
)
|
||||
|
||||
//TODO: implement decompress for each type of Options
|
||||
type CompressionOptions interface {
|
||||
Decompress([]byte) []byte
|
||||
DecompressCopy(*io.Reader, *io.Writer)
|
||||
Compress([]byte) []byte
|
||||
CompressCopy(*io.Reader, *io.Writer)
|
||||
}
|
||||
|
||||
//TODO: Allow creation of options for compression.
|
||||
@@ -24,6 +38,13 @@ type GzipOptions struct {
|
||||
FixedStretegy bool
|
||||
}
|
||||
|
||||
func NewGzipOptions(raw gzipOptionsRaw) GzipOptions {
|
||||
//TODO: parse strategies
|
||||
return GzipOptions{
|
||||
raw: &raw,
|
||||
}
|
||||
}
|
||||
|
||||
type xzOptionsRaw struct {
|
||||
dictionarySize int32
|
||||
executableFilters int32
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package squashfs
|
||||
|
||||
import "io"
|
||||
|
||||
//TODO: possible custom reader because I'm havng some issuse...
|
||||
|
||||
type Reader struct {
|
||||
rdr *io.SectionReader
|
||||
Offset int //Offset is the current offset of the reader
|
||||
}
|
||||
|
||||
func NewReader(io.ReaderAt)
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package squashfs
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
//ErrNotMagical happens when making a new Squashfs and it doesn't have the magic number
|
||||
ErrNotMagical = errors.New("Not Magical")
|
||||
)
|
||||
|
||||
//Squashfs is a squashfs backed by a ReadSeeker.
|
||||
type Squashfs struct {
|
||||
rdr *io.SectionReader //underlying reader
|
||||
offset int
|
||||
super Superblock
|
||||
flags SuperblockFlags
|
||||
compressionOptions CompressionOptions
|
||||
}
|
||||
|
||||
//NewSquashfs creates a new Squashfs backed by the given reader
|
||||
func NewSquashfs(reader *io.SectionReader) (*Squashfs, error) {
|
||||
var superblock Superblock
|
||||
err := binary.Read(reader, binary.LittleEndian, &superblock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if superblock.Magic != squashfsMagic {
|
||||
return nil, ErrNotMagical
|
||||
}
|
||||
flags := superblock.GetFlags()
|
||||
var compressionOptions CompressionOptions
|
||||
if flags.CompressorOptions {
|
||||
switch superblock.Compression {
|
||||
case zlibCompression:
|
||||
var gzipOpRaw gzipOptionsRaw
|
||||
err = binary.Read(reader, binary.LittleEndian, &gzipOpRaw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compressionOptions = NewGzipOptions(gzipOpRaw)
|
||||
break
|
||||
default:
|
||||
//TODO: all the compression options
|
||||
return nil, errors.New("This type of compression isn't supported yet")
|
||||
}
|
||||
}
|
||||
//TODO: parse more info
|
||||
return &Squashfs{
|
||||
rdr: reader,
|
||||
super: superblock,
|
||||
flags: flags,
|
||||
compressionOptions: compressionOptions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
//GetFlags return the SuperblockFlags of the Squashfs
|
||||
func (s *Squashfs) GetFlags() SuperblockFlags {
|
||||
return s.super.GetFlags()
|
||||
}
|
||||
|
||||
//Metadata is a parsed metadata block
|
||||
type Metadata struct {
|
||||
Compressed bool
|
||||
Size uint16
|
||||
Data *io.SectionReader
|
||||
}
|
||||
|
||||
func (s *Squashfs) parseNextMetadata() (*Metadata, error) {
|
||||
var metaHeader uint16
|
||||
err := binary.Read(s.rdr, binary.LittleEndian, metaHeader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if metaHeader&0x8000 == 0x8000 {
|
||||
metaHeader = metaHeader &^ 0x8000
|
||||
//TODO: read compressed metadata
|
||||
return nil, errors.New("Metadata is compressed, which is not implemented yet")
|
||||
}
|
||||
return &Metadata{
|
||||
Compressed: false,
|
||||
Size: metaHeader,
|
||||
//TODO: Data: io.NewSectionReader(s.rdr, , metaHeader),
|
||||
}, nil
|
||||
}
|
||||
+2
-1
@@ -31,7 +31,8 @@ func TestAppImageSquash(t *testing.T) {
|
||||
}
|
||||
}
|
||||
defer squashFil.Close()
|
||||
squash, err := NewSquashfs(squashFil)
|
||||
stat, _ := squashFil.Stat()
|
||||
squash, err := NewSquashfs(io.NewSectionReader(squashFil, 0, stat.Size()))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package squashfs
|
||||
|
||||
const squashfsMagic = 0x73717368
|
||||
|
||||
//Superblock is a raw representation of a squashfs
|
||||
//Descriptions provided by https://dr-emann.github.io/squashfs/
|
||||
type Superblock struct {
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
package squashfs
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
//Squashfs is a squashfs backed by a ReadSeeker.
|
||||
type Squashfs struct {
|
||||
rdr *io.ReadSeeker //underlying reader
|
||||
super Superblock
|
||||
}
|
||||
|
||||
//NewSquashfs creates a new Squashfs backed by the given reader
|
||||
func NewSquashfs(reader io.ReadSeeker) (*Squashfs, error) {
|
||||
var superblock Superblock
|
||||
err := binary.Read(reader, binary.LittleEndian, &superblock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//TODO: check magic
|
||||
//TODO: parse more info
|
||||
return &Squashfs{
|
||||
rdr: &reader,
|
||||
super: superblock,
|
||||
}, nil
|
||||
}
|
||||
|
||||
//GetFlags return the SuperblockFlags of the Squashfs
|
||||
func (s *Squashfs) GetFlags() SuperblockFlags {
|
||||
return s.super.GetFlags()
|
||||
}
|
||||
Reference in New Issue
Block a user