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
|
package squashfs
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
const (
|
||||||
|
zlibCompression = 1 + iota
|
||||||
|
lzmaCompression
|
||||||
|
lzoCompression
|
||||||
|
xzCompression
|
||||||
|
lz4Compression
|
||||||
|
zstdCompression
|
||||||
|
)
|
||||||
|
|
||||||
//TODO: implement decompress for each type of Options
|
//TODO: implement decompress for each type of Options
|
||||||
type CompressionOptions interface {
|
type CompressionOptions interface {
|
||||||
Decompress([]byte) []byte
|
Decompress([]byte) []byte
|
||||||
|
DecompressCopy(*io.Reader, *io.Writer)
|
||||||
|
Compress([]byte) []byte
|
||||||
|
CompressCopy(*io.Reader, *io.Writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Allow creation of options for compression.
|
//TODO: Allow creation of options for compression.
|
||||||
@@ -24,6 +38,13 @@ type GzipOptions struct {
|
|||||||
FixedStretegy bool
|
FixedStretegy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewGzipOptions(raw gzipOptionsRaw) GzipOptions {
|
||||||
|
//TODO: parse strategies
|
||||||
|
return GzipOptions{
|
||||||
|
raw: &raw,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type xzOptionsRaw struct {
|
type xzOptionsRaw struct {
|
||||||
dictionarySize int32
|
dictionarySize int32
|
||||||
executableFilters 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()
|
defer squashFil.Close()
|
||||||
squash, err := NewSquashfs(squashFil)
|
stat, _ := squashFil.Stat()
|
||||||
|
squash, err := NewSquashfs(io.NewSectionReader(squashFil, 0, stat.Size()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package squashfs
|
package squashfs
|
||||||
|
|
||||||
|
const squashfsMagic = 0x73717368
|
||||||
|
|
||||||
//Superblock is a raw representation of a squashfs
|
//Superblock is a raw representation of a squashfs
|
||||||
//Descriptions provided by https://dr-emann.github.io/squashfs/
|
//Descriptions provided by https://dr-emann.github.io/squashfs/
|
||||||
type Superblock struct {
|
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