Directorty table info parsing.

Futher work on reading data.
This commit is contained in:
Caleb Gardner
2020-11-13 04:47:54 -06:00
parent f135457443
commit dbf7e9465a
9 changed files with 288 additions and 114 deletions
+4
View File
@@ -19,3 +19,7 @@ I am focusing purely on unsquashing before squashing.
* Reading the Directory structure * Reading the Directory structure
* Implement other compression types * Implement other compression types
* Squashing * Squashing
# Where I'm at
* I can read the metadata, but can't read inodes just yet.
+19 -16
View File
@@ -1,12 +1,14 @@
package squashfs package squashfs
import ( import (
"compress/zlib" "compress/gzip"
"io" "io"
"gopkg.in/src-d/go-git.v4/utils/ioutil"
) )
const ( const (
zlibCompression = 1 + iota gzipCompression = 1 + iota
lzmaCompression lzmaCompression
lzoCompression lzoCompression
xzCompression xzCompression
@@ -95,13 +97,13 @@ func NewGzipOptions(raw gzipOptionsRaw) *GzipOptions {
} }
func (gzipOp *GzipOptions) Decompress(rdr *io.SectionReader, blockSize int) ([]byte, error) { func (gzipOp *GzipOptions) Decompress(rdr *io.SectionReader, blockSize int) ([]byte, error) {
zlibRdr, err := zlib.NewReader(rdr) gzipRdr, err := gzip.NewReader(rdr)
defer zlibRdr.Close() defer gzipRdr.Close()
if err != nil { if err != nil {
return nil, err return nil, err
} }
bytrw := newByteReadWrite(0) bytrw := newByteReadWrite(0)
_, err = io.Copy(bytrw, zlibRdr) _, err = io.Copy(bytrw, gzipRdr)
if err != nil { if err != nil {
return bytrw.byts, err return bytrw.byts, err
} }
@@ -109,20 +111,20 @@ func (gzipOp *GzipOptions) Decompress(rdr *io.SectionReader, blockSize int) ([]b
} }
func (gzipOp *GzipOptions) DecompressCopy(rdr *io.Reader, wrt *io.Writer) (int, error) { func (gzipOp *GzipOptions) DecompressCopy(rdr *io.Reader, wrt *io.Writer) (int, error) {
zlibRdr, err := zlib.NewReader(*rdr) gzipRdr, err := gzip.NewReader(*rdr)
defer zlibRdr.Close() defer gzipRdr.Close()
if err != nil { if err != nil {
return 0, err return 0, err
} }
n, err := io.Copy(*wrt, zlibRdr) n, err := io.Copy(*wrt, gzipRdr)
return int(n), err return int(n), err
} }
func (gzipOp *GzipOptions) Compress(rdr *io.SectionReader, blockSize int) ([]byte, error) { func (gzipOp *GzipOptions) Compress(rdr *io.SectionReader, blockSize int) ([]byte, error) {
bytWrt := newByteReadWrite(0) bytWrt := newByteReadWrite(0)
zlibWrt := zlib.NewWriter(bytWrt) //TODO: allow setting level gzipWrt := gzip.NewWriter(bytWrt) //TODO: allow setting level
defer zlibWrt.Close() defer gzipWrt.Close()
_, err := io.Copy(zlibWrt, rdr) _, err := io.Copy(gzipWrt, rdr)
if err != nil { if err != nil {
return bytWrt.byts, err return bytWrt.byts, err
} }
@@ -130,15 +132,16 @@ func (gzipOp *GzipOptions) Compress(rdr *io.SectionReader, blockSize int) ([]byt
} }
func (gzipOp *GzipOptions) CompressCopy(rdr *io.Reader, wrt *io.Writer) (int, error) { func (gzipOp *GzipOptions) CompressCopy(rdr *io.Reader, wrt *io.Writer) (int, error) {
zlibWrt := zlib.NewWriter(*wrt) //TODO: allow setting level gzipWrt := gzip.NewWriter(*wrt) //TODO: allow setting level
defer zlibWrt.Close() defer gzipWrt.Close()
n, err := io.Copy(zlibWrt, *rdr) n, err := io.Copy(gzipWrt, *rdr)
return int(n), err return int(n), err
} }
func (gzipOp *GzipOptions) Reader(rdr io.Reader) (*io.ReadCloser, error) { func (gzipOp *GzipOptions) Reader(rdr io.Reader) (*io.ReadCloser, error) {
read, err := zlib.NewReader(rdr) read, err := gzip.NewReader(rdr)
return &read, err redClo := ioutil.NewReadCloser(read, read)
return &redClo, err
} }
type xzOptionsRaw struct { type xzOptionsRaw struct {
+83
View File
@@ -0,0 +1,83 @@
package directory
import (
"encoding/binary"
"fmt"
"io"
)
//Header is the header for a directory in the directory table
type Header struct {
Count uint32
InodeOffset uint32
InodeNumber uint32
}
//EntryInit is the values that can be easily decoded
type EntryInit struct {
Offset uint16
InodeOffset int16
Type uint16
NameSize uint16
}
//Entry is an entry in a directory.
type Entry struct {
Init EntryInit
Name []byte
}
//NewEntry creates a new directory entry
func NewEntry(rdr io.Reader) (Entry, error) {
var entry Entry
err := binary.Read(rdr, binary.LittleEndian, entry.Init)
if err != nil {
return entry, err
}
entry.Name = make([]byte, entry.Init.NameSize, entry.Init.NameSize)
err = binary.Read(rdr, binary.LittleEndian, entry.Name)
return entry, err
}
//Directory is an entry in the directory table of a squashfs.
//Will only have multiple headers if there are more then 256 entries
type Directory struct {
Headers []Header
Entries []Entry
}
//NewDirectory reads the directory from rdr
func NewDirectory(rdr io.Reader) (*Directory, error) {
var dir Directory
var hdr Header
err := binary.Read(rdr, binary.LittleEndian, &hdr)
if err != nil {
return nil, err
}
headers := hdr.Count / 256
if headers%256 > 0 {
headers++
}
headersRead := 1
dir.Headers = make([]Header, headers)
dir.Headers[0] = hdr
for i := uint32(0); i < hdr.Count; i++ {
if i != 0 && i%256 == 0 {
var newHdr Header
err = binary.Read(rdr, binary.LittleEndian, &newHdr)
if err != nil {
fmt.Println("Error processing header ", headersRead)
return &dir, err
}
dir.Headers[headersRead] = newHdr
headersRead++
}
ent, err := NewEntry(rdr)
if err != nil {
fmt.Println("Error processing entry ", len(dir.Entries))
return &dir, err
}
dir.Entries = append(dir.Entries, ent)
}
return &dir, nil
}
+58 -18
View File
@@ -2,11 +2,12 @@ package inode
import ( import (
"encoding/binary" "encoding/binary"
"fmt"
"io" "io"
) )
//InodeCommon is the comon header for all inodes //Common is the comon header for all inodes
type InodeCommon struct { type Common struct {
InodeType uint16 InodeType uint16
Permissions uint16 Permissions uint16
UID uint16 UID uint16
@@ -37,25 +38,61 @@ type ExtendedDirectoryInit struct {
//ExtendedDirectory is a directory with extra info //ExtendedDirectory is a directory with extra info
type ExtendedDirectory struct { type ExtendedDirectory struct {
Init ExtendedDirectoryInit Init ExtendedDirectoryInit
//TODO: indexes []DirectoryIndex Indexes []DirectoryIndex
} }
//NewExtendedDirectory creates a new ExtendedDirectory //NewExtendedDirectory creates a new ExtendedDirectory
func NewExtendedDirectory(rdr *io.Reader) (*ExtendedDirectory, error) { func NewExtendedDirectory(rdr *io.Reader) (*ExtendedDirectory, error) {
var inode ExtendedDirectory var inode ExtendedDirectory
err := binary.Read(*rdr, binary.LittleEndian, inode.Init) err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
//TODO: Read directory indexes if err != nil {
return &inode, err
}
if inode.Init.IndexCount > 0 {
inode.Indexes = make([]DirectoryIndex, inode.Init.IndexCount)
for i := uint16(0); i < inode.Init.IndexCount; i++ {
inode.Indexes[i], err = NewDirectoryIndex(rdr)
if err != nil {
fmt.Println("Error while reading Directory Index ", i)
return &inode, err
}
}
}
return &inode, err return &inode, err
} }
//DirectoryIndexInit holds the values that can be easily decoded
type DirectoryIndexInit struct {
Offset uint32
DirTableOffset uint32
NameSize uint32
}
//DirectoryIndex is a quick lookup provided by an ExtendedDirectory
type DirectoryIndex struct {
Init DirectoryIndexInit
Name []byte
}
//NewDirectoryIndex return a new DirectoryIndex
func NewDirectoryIndex(rdr *io.Reader) (DirectoryIndex, error) {
var index DirectoryIndex
err := binary.Read(*rdr, binary.LittleEndian, index.Init)
if err != nil {
return index, err
}
index.Name = make([]byte, index.Init.NameSize, index.Init.NameSize)
err = binary.Read(*rdr, binary.LittleEndian, index.Name)
return index, err
}
//BasicFileInit is the information that can be directoy decoded //BasicFileInit is the information that can be directoy decoded
type BasicFileInit struct { type BasicFileInit struct {
BlockStart uint32 BlockStart uint32
FragmentIndex uint32 FragmentIndex uint32
FragmentOffset uint32 FragmentOffset uint32
Size uint32 Size uint32
//TODO: possibly fix BlockSizes
} }
//BasicFile is self explainatory //BasicFile is self explainatory
@@ -89,7 +126,6 @@ type ExtendedFileInit struct {
FragmentIndex uint32 FragmentIndex uint32
FragmentOffset uint32 FragmentOffset uint32
XattrIndex uint32 XattrIndex uint32
//TODO: possibly fix BlockSizes
} }
//ExtendedFile is a file with more information //ExtendedFile is a file with more information
@@ -99,11 +135,11 @@ type ExtendedFile struct {
} }
//NewExtendedFile creates a new ExtendedFile //NewExtendedFile creates a new ExtendedFile
func NewExtendedFile(rdr *io.Reader, blockSize uint32) (*ExtendedFile, error) { func NewExtendedFile(rdr *io.Reader, blockSize uint32) (ExtendedFile, error) {
var inode ExtendedFile var inode ExtendedFile
err := binary.Read(*rdr, binary.LittleEndian, inode.Init) err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
if err != nil { if err != nil {
return &inode, err return inode, err
} }
blocks := inode.Init.Size / blockSize blocks := inode.Init.Size / blockSize
if inode.Init.Size%blockSize > 0 { if inode.Init.Size%blockSize > 0 {
@@ -111,7 +147,7 @@ func NewExtendedFile(rdr *io.Reader, blockSize uint32) (*ExtendedFile, error) {
} }
inode.BlockSizes = make([]uint32, blocks, blocks) inode.BlockSizes = make([]uint32, blocks, blocks)
err = binary.Read(*rdr, binary.LittleEndian, inode.BlockSizes) err = binary.Read(*rdr, binary.LittleEndian, inode.BlockSizes)
return &inode, err return inode, err
} }
//BasicSymlinkInit is all the values that can be directly decoded //BasicSymlinkInit is all the values that can be directly decoded
@@ -123,19 +159,19 @@ type BasicSymlinkInit struct {
//BasicSymlink is a symlink //BasicSymlink is a symlink
type BasicSymlink struct { type BasicSymlink struct {
Init BasicSymlinkInit Init BasicSymlinkInit
targetPath []uint8 //len is TargetPathSize targetPath []byte //len is TargetPathSize
} }
//NewBasicSymlink creates a new BasicSymlink //NewBasicSymlink creates a new BasicSymlink
func NewBasicSymlink(rdr *io.Reader) (*BasicSymlink, error) { func NewBasicSymlink(rdr *io.Reader) (BasicSymlink, error) {
var inode BasicSymlink var inode BasicSymlink
err := binary.Read(*rdr, binary.LittleEndian, inode.Init) err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
if err != nil { if err != nil {
return nil, err return inode, err
} }
inode.targetPath = make([]uint8, inode.Init.TargetPathSize, inode.Init.TargetPathSize) inode.targetPath = make([]byte, inode.Init.TargetPathSize, inode.Init.TargetPathSize)
err = binary.Read(*rdr, binary.LittleEndian, inode.targetPath) err = binary.Read(*rdr, binary.LittleEndian, inode.targetPath)
return &inode, err return inode, err
} }
//ExtendedSymlinkInit is all the values that can be directly decoded //ExtendedSymlinkInit is all the values that can be directly decoded
@@ -152,31 +188,35 @@ type ExtendedSymlink struct {
} }
//NewExtendedSymlink creates a new ExtendedSymlink //NewExtendedSymlink creates a new ExtendedSymlink
func NewExtendedSymlink(rdr *io.Reader) (*ExtendedSymlink, error) { func NewExtendedSymlink(rdr *io.Reader) (ExtendedSymlink, error) {
var inode ExtendedSymlink var inode ExtendedSymlink
err := binary.Read(*rdr, binary.LittleEndian, inode.Init) err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
if err != nil { if err != nil {
return &inode, err return inode, err
} }
inode.TargetPath = make([]uint8, inode.Init.TargetPathSize, inode.Init.TargetPathSize) inode.TargetPath = make([]uint8, inode.Init.TargetPathSize, inode.Init.TargetPathSize)
err = binary.Read(*rdr, binary.LittleEndian, &inode.XattrIndex) err = binary.Read(*rdr, binary.LittleEndian, &inode.XattrIndex)
return &inode, err return inode, err
} }
//BasicDevice is a device
type BasicDevice struct { type BasicDevice struct {
HardLinks uint32 HardLinks uint32
Device uint32 Device uint32
} }
//ExtendedDevice is a device with more info
type ExtendedDevice struct { type ExtendedDevice struct {
BasicDevice BasicDevice
XattrIndex uint32 XattrIndex uint32
} }
//BasicIPC is a Fifo or Socket device
type BasicIPC struct { type BasicIPC struct {
HardLink uint32 HardLink uint32
} }
//ExtendedIPC is a IPC device with extra info
type ExtendedIPC struct { type ExtendedIPC struct {
BasicIPC BasicIPC
XattrIndex uint32 XattrIndex uint32
+65 -62
View File
@@ -8,80 +8,83 @@ import (
) )
const ( const (
basicDirectory = iota + 1 //The inode type from inode.Common.InodeType
basicFile
basicSymlink BasicDirectoryType = iota + 1
basicBlockDevice BasicFileType
basicCharDevice BasicSymlinkType
basicFifo BasicBlockDeviceType
basicSocket BasicCharDeviceType
extendedDirectory BasicFifoType
extendedFile BasicSocketType
extendedSymlink ExtendedDirectoryType
extendedBlockDevice ExtendedFileType
extendedCharDevice ExtendedSymlinkType
extendedFifo ExtendedBlockDeviceType
extendedSocket ExtendedCharDeviceType
ExtendedFifoType
ExtendedSocketType
) )
func ProcessInode(rdr *io.Reader) (*InodeCommon, interface{}, error) { //ProcessInode processes the next inode in the given reader
var inodeHeader InodeCommon func ProcessInode(rdr *io.Reader, blockSize uint32) (*Common, interface{}, error) {
var inodeHeader Common
err := binary.Read(*rdr, binary.LittleEndian, &inodeHeader) err := binary.Read(*rdr, binary.LittleEndian, &inodeHeader)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
switch inodeHeader.InodeType { switch inodeHeader.InodeType {
case basicDirectory: case BasicDirectoryType:
var inode BasicDirectory var inode BasicDirectory
err = binary.Read(*rdr, binary.LittleEndian, &inode) err = binary.Read(*rdr, binary.LittleEndian, &inode)
return &inodeHeader, &inode, err
case BasicFileType:
inode, err := NewBasicFile(rdr, blockSize)
return &inodeHeader, inode, err return &inodeHeader, inode, err
case basicFile: case BasicSymlinkType:
var inode BasicFile
err = binary.Read(*rdr, binary.LittleEndian, &inode)
return &inodeHeader, inode, err
case basicSymlink:
inode, err := NewBasicSymlink(rdr) inode, err := NewBasicSymlink(rdr)
return &inodeHeader, inode, err return &inodeHeader, inode, err
// case basicFile: case BasicBlockDeviceType:
// var inode BasicFile var inode BasicDevice
// err = binary.Read(*rdr, binary.LittleEndian, &inode) err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err return &inodeHeader, inode, err
// case basicFile: case BasicCharDeviceType:
// var inode BasicFile var inode BasicDevice
// err = binary.Read(*rdr, binary.LittleEndian, &inode) err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err return &inodeHeader, inode, err
// case basicFile: case BasicFifoType:
// var inode BasicFile var inode BasicIPC
// err = binary.Read(*rdr, binary.LittleEndian, &inode) err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err return &inodeHeader, inode, err
// case basicFile: case BasicSocketType:
// var inode BasicFile var inode BasicIPC
// err = binary.Read(*rdr, binary.LittleEndian, &inode) err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err return &inodeHeader, inode, err
// case basicFile: case ExtendedDirectoryType:
// var inode BasicFile inode, err := NewExtendedDirectory(rdr)
// err = binary.Read(*rdr, binary.LittleEndian, &inode) return &inodeHeader, inode, err
// return &inodeHeader, inode, err case ExtendedFileType:
// case basicFile: inode, err := NewExtendedFile(rdr, blockSize)
// var inode BasicFile return &inodeHeader, inode, err
// err = binary.Read(*rdr, binary.LittleEndian, &inode) case ExtendedSymlinkType:
// return &inodeHeader, inode, err inode, err := NewExtendedSymlink(rdr)
// case basicFile: return &inodeHeader, inode, err
// var inode BasicFile case ExtendedBlockDeviceType:
// err = binary.Read(*rdr, binary.LittleEndian, &inode) var inode ExtendedDevice
// return &inodeHeader, inode, err err = binary.Read(*rdr, binary.LittleEndian, &inode)
// case basicFile: return &inodeHeader, inode, err
// var inode BasicFile case ExtendedCharDeviceType:
// err = binary.Read(*rdr, binary.LittleEndian, &inode) var inode ExtendedDevice
// return &inodeHeader, inode, err err = binary.Read(*rdr, binary.LittleEndian, &inode)
// case basicFile: return &inodeHeader, inode, err
// var inode BasicFile case ExtendedFifoType:
// err = binary.Read(*rdr, binary.LittleEndian, &inode) var inode ExtendedIPC
// return &inodeHeader, inode, err err = binary.Read(*rdr, binary.LittleEndian, &inode)
// case basicFile: return &inodeHeader, inode, err
// var inode BasicFile case ExtendedSocketType:
// err = binary.Read(*rdr, binary.LittleEndian, &inode) var inode ExtendedIPC
// return &inodeHeader, inode, err err = binary.Read(*rdr, binary.LittleEndian, &inode)
return &inodeHeader, inode, err
//TODO: implement ALL cases //TODO: implement ALL cases
default: default:
return nil, nil, errors.New("Inode type is unrecognized: " + strconv.FormatInt(int64(inodeHeader.InodeType), 2)) return nil, nil, errors.New("Inode type is unrecognized: " + strconv.FormatInt(int64(inodeHeader.InodeType), 2))
+10
View File
@@ -0,0 +1,10 @@
package inode
//ProcessInodeRef processes an inode reference and returns two values
//The first value is the inode table offset. AKA, it's where the metadata block of the inode STARTS.
//The second value is the offset of the inode, INSIDE of the metadata.
func ProcessInodeRef(inodeRef uint64) (tableOffset uint32, metaOffset uint16) {
tableOffset = uint32(inodeRef >> 16)
metaOffset = uint16(inodeRef &^ 0xFFFFFFFF0000)
return
}
-3
View File
@@ -9,9 +9,6 @@ import (
//Reader is a reader which implements Reader, ReaderAt, and Seeker, all with an accesible offset (for reasons) //Reader is a reader which implements Reader, ReaderAt, and Seeker, all with an accesible offset (for reasons)
type Reader struct { type Reader struct {
io.Reader
io.ReaderAt
io.Seeker
rdr io.ReaderAt rdr io.ReaderAt
offset int64 offset int64
} }
+45 -11
View File
@@ -3,7 +3,10 @@ package squashfs
import ( import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"io" "io"
"github.com/CalebQ42/GoSquashfs/internal/inode"
) )
var ( var (
@@ -34,7 +37,7 @@ func NewSquashfs(reader io.ReaderAt) (*Squashfs, error) {
flags := superblock.GetFlags() flags := superblock.GetFlags()
var compressionOptions CompressionOptions var compressionOptions CompressionOptions
switch superblock.Compression { switch superblock.Compression {
case zlibCompression: case gzipCompression:
if flags.CompressorOptions { if flags.CompressorOptions {
var gzipOpRaw gzipOptionsRaw var gzipOpRaw gzipOptionsRaw
err = binary.Read(&rdr, binary.LittleEndian, &gzipOpRaw) err = binary.Read(&rdr, binary.LittleEndian, &gzipOpRaw)
@@ -69,9 +72,39 @@ func NewSquashfs(reader io.ReaderAt) (*Squashfs, error) {
}, nil }, nil
} }
func (s *Squashfs) readRootDirectoryTable() error {
offset, metaOffset := inode.ProcessInodeRef(s.super.RootInode)
meta, err := s.parseMetadataAt(int64(s.super.InodeTableOffset) + int64(offset))
if err != nil {
fmt.Println("Error processing metadata")
return err
}
_, err = meta.Data.Read(make([]byte, metaOffset))
if err != nil {
fmt.Println("error reading forward to offset")
return err
}
common, _, err := inode.ProcessInode(&meta.Data, s.super.BlockSize)
if err != nil {
fmt.Println("Error reading inode")
return err
}
if common.InodeType != inode.BasicDirectoryType {
return errors.New("Not a basic directory")
}
// dirTable, err := directory.NewDirectory(meta.Data)
// if err != nil {
// return err
// }
// for _, entry := range dirTable.Entries {
// fmt.Println(entry.Name)
// }
return nil
}
//GetFlags return the SuperblockFlags of the Squashfs //GetFlags return the SuperblockFlags of the Squashfs
func (s *Squashfs) GetFlags() SuperblockFlags { func (s *Squashfs) GetFlags() SuperblockFlags {
return s.super.GetFlags() return s.flags
} }
//metadata is a parsed metadata block //metadata is a parsed metadata block
@@ -90,13 +123,14 @@ func (m *metadata) close() {
func (s *Squashfs) parseNextMetadata() (*metadata, error) { func (s *Squashfs) parseNextMetadata() (*metadata, error) {
var metaHeader uint16 var metaHeader uint16
err := binary.Read(s.rdr, binary.LittleEndian, metaHeader) err := binary.Read(s.rdr, binary.LittleEndian, &metaHeader)
if err != nil { if err != nil {
return nil, err return nil, err
} }
reader := io.NewSectionReader(s.rdr, s.rdr.offset, s.rdr.offset+int64(metaHeader))
if metaHeader&0x8000 == 0x8000 { if metaHeader&0x8000 == 0x8000 {
metaHeader = metaHeader &^ 0x8000 metaHeader = metaHeader &^ 0x8000
compressRead, err := s.compressionOptions.Reader(io.NewSectionReader(s.rdr, s.rdr.offset, int64(metaHeader))) compressRead, err := s.compressionOptions.Reader(reader)
return &metadata{ return &metadata{
Compressed: true, Compressed: true,
Size: metaHeader, Size: metaHeader,
@@ -106,19 +140,19 @@ func (s *Squashfs) parseNextMetadata() (*metadata, error) {
return &metadata{ return &metadata{
Compressed: false, Compressed: false,
Size: metaHeader, Size: metaHeader,
Data: io.NewSectionReader(s.rdr, s.rdr.offset, int64(metaHeader)), Data: reader,
}, nil }, nil
} }
func (s *Squashfs) parseMetadataAt(offset int64) (*metadata, error) { func (s *Squashfs) parseMetadataAt(offset int64) (*metadata, error) {
var metaHeader uint16 var metaHeader uint16
err := binary.Read(s.rdr, binary.LittleEndian, metaHeader) var headerBytes []byte
if err != nil { headerBytes = make([]byte, 2)
return nil, err s.rdr.ReadAt(headerBytes, offset)
} metaHeader = binary.LittleEndian.Uint16(headerBytes)
if metaHeader&0x8000 == 0x8000 { if metaHeader&0x8000 == 0x8000 {
metaHeader = metaHeader &^ 0x8000 metaHeader = metaHeader &^ 0x8000
compressRead, err := s.compressionOptions.Reader(io.NewSectionReader(s.rdr, offset, int64(metaHeader))) compressRead, err := s.compressionOptions.Reader(io.NewSectionReader(s.rdr, s.rdr.offset, s.rdr.offset+int64(s.super.BlockSize)))
return &metadata{ return &metadata{
Compressed: true, Compressed: true,
Size: metaHeader, Size: metaHeader,
@@ -128,6 +162,6 @@ func (s *Squashfs) parseMetadataAt(offset int64) (*metadata, error) {
return &metadata{ return &metadata{
Compressed: false, Compressed: false,
Size: metaHeader, Size: metaHeader,
Data: io.NewSectionReader(s.rdr, offset, int64(metaHeader)), Data: io.NewSectionReader(s.rdr, s.rdr.offset, s.rdr.offset+int64(s.super.BlockSize)),
}, nil }, nil
} }
+3 -3
View File
@@ -1,7 +1,6 @@
package squashfs package squashfs
import ( import (
"fmt"
"io" "io"
"net/http" "net/http"
"os" "os"
@@ -36,8 +35,8 @@ func TestAppImageSquash(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
fmt.Println(squash.GetFlags()) err = squash.readRootDirectoryTable()
t.Fatal("Testing") t.Fatal(err)
} }
func TestCreateSquashFromAppImage(t *testing.T) { func TestCreateSquashFromAppImage(t *testing.T) {
@@ -78,6 +77,7 @@ func TestCreateSquashFromAppImage(t *testing.T) {
} }
func downloadTestAppImage(t *testing.T, dir string) { func downloadTestAppImage(t *testing.T, dir string) {
//seems to time out. Need to fix that at some point
appImage, err := os.Create(dir + "/" + appImageName) appImage, err := os.Create(dir + "/" + appImageName)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)