Extracting is mostly finished.

Fixed reading metadata and data blocks that are the exactly correct size
This commit is contained in:
Caleb Gardner
2020-12-02 01:05:31 -06:00
parent 28bb0f873a
commit fef7bec20d
5 changed files with 67 additions and 41 deletions
+5 -2
View File
@@ -153,9 +153,12 @@ func (d *dataReader) Close() error {
func (d *dataReader) Read(p []byte) (int, error) {
if d.curData == nil {
d.readCurBlock()
err := d.readCurBlock()
if err != nil {
return 0, err
}
}
if d.curReadOffset+len(p) < len(d.curData) {
if d.curReadOffset+len(p) <= len(d.curData) {
for i := 0; i < len(p); i++ {
p[i] = d.curData[d.curReadOffset+i]
}
+46 -20
View File
@@ -255,14 +255,15 @@ func (f *File) ExtractWithOptions(path string, unbreakSymlink bool, folderPerm o
errs = append(errs, err)
return
}
err = fil.Chown(int(f.r.idTable[f.in.Header.UID]), int(f.r.idTable[f.in.Header.GID]))
if err != nil {
if verbose {
fmt.Println("Error while changing owner:", path+"/"+f.Name)
fmt.Println(err)
}
errs = append(errs, err)
}
fil.Chown(int(f.r.idTable[f.in.Header.UID]), int(f.r.idTable[f.in.Header.GID]))
//don't mention anything when it fails. Because it fails often. Probably has something to do about uid & gid 0
// if err != nil {
// if verbose {
// fmt.Println("Error while changing owner:", path+"/"+f.Name)
// fmt.Println(err)
// }
// errs = append(errs, err)
// }
err = fil.Chmod(f.Permission())
if err != nil {
if verbose {
@@ -324,8 +325,7 @@ func (f *File) ExtractWithOptions(path string, unbreakSymlink bool, folderPerm o
}
errs = append(errs, err)
return
}
// defer f.Close() //Since we will be reading from the file
} //Since we will be reading from the file
_, err = io.Copy(fil, f)
if err != nil {
if verbose {
@@ -335,15 +335,17 @@ func (f *File) ExtractWithOptions(path string, unbreakSymlink bool, folderPerm o
errs = append(errs, err)
return
}
f.Close()
err = fil.Chown(int(f.r.idTable[f.in.Header.UID]), int(f.r.idTable[f.in.Header.GID]))
if err != nil {
if verbose {
fmt.Println("Error while changing owner:", path+"/"+f.Name)
fmt.Println(err)
}
errs = append(errs, err)
return
}
//don't mention anything when it fails. Because it fails often. Probably has something to do about uid & gid 0
// if err != nil {
// if verbose {
// fmt.Println("Error while changing owner:", path+"/"+f.Name)
// fmt.Println(err)
// }
// errs = append(errs, err)
// return
// }
err = fil.Chmod(f.Permission())
if err != nil {
if verbose {
@@ -354,8 +356,32 @@ func (f *File) ExtractWithOptions(path string, unbreakSymlink bool, folderPerm o
}
return
case f.IsSymlink():
//just a temp thing real quick
os.Symlink(f.SymlinkPath(), path+"/"+f.Name)
symPath := f.SymlinkPath()
if unbreakSymlink {
fil := f.GetSymlinkFile()
if fil != nil {
symPath = path + "/" + symPath
paths := strings.Split(symPath, "/")
extracSymErrs := fil.ExtractWithOptions(strings.Join(paths[:len(paths)-1], "/"), unbreakSymlink, folderPerm, verbose)
if len(extracSymErrs) > 0 {
if verbose {
fmt.Println("Error(s) while extracting the symlink's file:", path+"/"+f.Name)
fmt.Println(extracSymErrs)
}
errs = append(errs, extracSymErrs...)
}
} else {
fmt.Println("Symlink path(", symPath, ") is outside the archive:"+path+"/"+f.Name)
}
}
err = os.Symlink(f.SymlinkPath(), path+"/"+f.Name)
if err != nil {
if verbose {
fmt.Println("Error while making symlink:", path+"/"+f.Name)
fmt.Println(err)
}
errs = append(errs, err)
}
}
return
}
+1 -1
View File
@@ -104,7 +104,7 @@ func (br *metadataReader) readNextDataBlock() error {
//Read reads bytes into the given byte slice. Returns the amount of data read.
func (br *metadataReader) Read(p []byte) (int, error) {
if br.readOffset+len(p) < len(br.data) {
if br.readOffset+len(p) <= len(br.data) {
for i := 0; i < len(p); i++ {
p[i] = br.data[br.readOffset+i]
}
+10 -5
View File
@@ -3,6 +3,7 @@ package squashfs
import (
"encoding/binary"
"errors"
"fmt"
"io"
"math"
@@ -44,6 +45,9 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
if rdr.super.Magic != magic {
return nil, errNoMagic
}
// if rdr.super.BlockLog == uint16(math.Log2(float64(rdr.super.BlockSize))) {
// return nil, errors.New("BlockSize and BlockLog doesn't match. The archive is probably corrupt")
// }
rdr.flags = rdr.super.GetFlags()
switch rdr.super.CompressionType {
case gzipCompression:
@@ -54,10 +58,11 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
//TODO: all compression types.
return nil, errIncompatibleCompression
}
// if rdr.flags.CompressorOptions {
// //TODO: parse compressor options
// return nil, errCompressorOptions
// }
if rdr.flags.CompressorOptions {
fmt.Println("has options")
//TODO: parse compressor options
return nil, errCompressorOptions
}
fragBlocks := int(math.Ceil(float64(rdr.super.FragCount) / 512))
if fragBlocks > 0 {
offset := int64(rdr.super.FragTableStart)
@@ -74,7 +79,7 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
unread := rdr.super.IDCount
blockOffsets := make([]uint64, int(math.Ceil(float64(rdr.super.IDCount)/2048)))
for i := range blockOffsets {
secRdr := io.NewSectionReader(r, int64(rdr.super.IDTableStart)+8*int64(i), 8)
secRdr := io.NewSectionReader(r, int64(rdr.super.IDTableStart)+(8*int64(i)), 8)
err = binary.Read(secRdr, binary.LittleEndian, &blockOffsets[i])
if err != nil {
return nil, err
+5 -13
View File
@@ -1,7 +1,6 @@
package squashfs
import (
"fmt"
"io"
"net/http"
"os"
@@ -17,7 +16,6 @@ const (
)
func TestSquashfs(t *testing.T) {
fmt.Println("YOOO")
wd, err := os.Getwd()
if err != nil {
t.Fatal(err)
@@ -31,12 +29,9 @@ func TestSquashfs(t *testing.T) {
t.Fatal(err)
}
os.RemoveAll(wd + "/testing/" + squashfsName + ".d")
fmt.Println("Whaaaa")
root, _ := rdr.GetRootFolder()
fmt.Println("WHYYYY")
errs := root.ExtractWithOptions(wd+"/testing/"+squashfsName+".d", false, os.ModePerm, true)
fmt.Println(errs)
t.Fatal("No prolems here!")
t.Fatal(errs)
}
func TestAppImage(t *testing.T) {
@@ -62,13 +57,10 @@ func TestAppImage(t *testing.T) {
if err != nil {
t.Fatal(err)
}
fil := rdr.GetFileAtPath("/usr/bin/cool-retro-term")
if fil != nil {
fmt.Println("Worked!", fil.Path())
} else {
t.Fatal("NOOOOOO!")
}
t.Fatal("No problems here!")
os.RemoveAll(wd + "/testing/" + appImageName + ".d")
root, _ := rdr.GetRootFolder()
errs := root.ExtractWithOptions(wd+"/testing/"+appImageName+".d", true, os.ModePerm, true)
t.Fatal(errs)
}
func downloadTestAppImage(t *testing.T, dir string) {