Some quick fixes for "correctness"

This commit is contained in:
Caleb Gardner
2021-04-03 01:17:09 -05:00
parent 2a8310a724
commit 7f5fa3ba1f
9 changed files with 41 additions and 36 deletions
+5 -10
View File
@@ -10,9 +10,9 @@ import (
var ( var (
//ErrInodeNotFile is given when giving an inode, but the function requires a file inode. //ErrInodeNotFile is given when giving an inode, but the function requires a file inode.
errInodeNotFile = errors.New("Given inode is NOT a file type") errInodeNotFile = errors.New("given inode is NOT a file type")
//ErrInodeOnlyFragment is given when trying to make a DataReader from an inode, but the inode only had data in a fragment //ErrInodeOnlyFragment is given when trying to make a DataReader from an inode, but the inode only had data in a fragment
errInodeOnlyFragment = errors.New("Given inode ONLY has fragment data") errInodeOnlyFragment = errors.New("given inode ONLY has fragment data")
) )
//DataReader reads data from data blocks. //DataReader reads data from data blocks.
@@ -49,9 +49,7 @@ func (r *Reader) newDataReaderFromInode(i *inode.Inode) (*dataReader, error) {
return nil, errInodeOnlyFragment return nil, errInodeOnlyFragment
} }
rdr.offset = int64(fil.BlockStart) rdr.offset = int64(fil.BlockStart)
for _, sizes := range fil.BlockSizes { rdr.sizes = append(rdr.sizes, fil.BlockSizes...)
rdr.sizes = append(rdr.sizes, sizes)
}
if fil.Fragmented { if fil.Fragmented {
rdr.sizes = rdr.sizes[:len(rdr.sizes)-1] rdr.sizes = rdr.sizes[:len(rdr.sizes)-1]
} }
@@ -61,9 +59,7 @@ func (r *Reader) newDataReaderFromInode(i *inode.Inode) (*dataReader, error) {
return nil, errInodeOnlyFragment return nil, errInodeOnlyFragment
} }
rdr.offset = int64(fil.BlockStart) rdr.offset = int64(fil.BlockStart)
for _, sizes := range fil.BlockSizes { rdr.sizes = append(rdr.sizes, fil.BlockSizes...)
rdr.sizes = append(rdr.sizes, sizes)
}
if fil.Fragmented { if fil.Fragmented {
rdr.sizes = rdr.sizes[:len(rdr.sizes)-1] rdr.sizes = rdr.sizes[:len(rdr.sizes)-1]
} }
@@ -173,7 +169,7 @@ func (d *dataReader) Read(p []byte) (int, error) {
} }
} }
if read != len(p) { if read != len(p) {
return read, errors.New("Didn't read enough data") return read, errors.New("didn't read enough data")
} }
return read, nil return read, nil
} }
@@ -199,7 +195,6 @@ func (d *dataReader) WriteTo(w io.Writer) (int64, error) {
return return
} }
cache.data = data cache.data = data
return
}(i, dataChan) }(i, dataChan)
} }
curIndex := 0 curIndex := 0
+8 -6
View File
@@ -78,7 +78,7 @@ func (f File) Read(p []byte) (int, error) {
} }
return f.reader.Read(p) return f.reader.Read(p)
} }
return 0, errors.New("Can only read files") return 0, errors.New("can only read files")
} }
//WriteTo writes all data from the file to the writer. This is multi-threaded. //WriteTo writes all data from the file to the writer. This is multi-threaded.
@@ -89,7 +89,7 @@ func (f File) WriteTo(w io.Writer) (int64, error) {
} }
return f.reader.WriteTo(w) return f.reader.WriteTo(w)
} }
return 0, errors.New("Can only read files") return 0, errors.New("can only read files")
} }
//Close simply nils the underlying reader. Here mostly to satisfy fs.File //Close simply nils the underlying reader. Here mostly to satisfy fs.File
@@ -236,6 +236,9 @@ func (f File) ExtractWithOptions(folder string, op ExtractionOptions) error {
} }
} }
stat, err := f.Stat() stat, err := f.Stat()
if err != nil {
return err
}
if f.IsDir() { if f.IsDir() {
if op.notBase { if op.notBase {
err = os.Mkdir(folder+"/"+f.name, stat.Mode()) err = os.Mkdir(folder+"/"+f.name, stat.Mode())
@@ -264,7 +267,6 @@ func (f File) ExtractWithOptions(folder string, op ExtractionOptions) error {
} }
errChan <- fil.ExtractWithOptions(folder+"/"+f.name, op) errChan <- fil.ExtractWithOptions(folder+"/"+f.name, op)
fil.Close() fil.Close()
return
}(ents[i].(*DirEntry)) }(ents[i].(*DirEntry))
} }
for i := 0; i < len(ents); i++ { for i := 0; i < len(ents); i++ {
@@ -301,7 +303,7 @@ func (f File) ExtractWithOptions(folder string, op ExtractionOptions) error {
if op.Verbose { if op.Verbose {
log.Println("Symlink path(", symPath, ") is unobtainable:", folder+"/"+f.name) log.Println("Symlink path(", symPath, ") is unobtainable:", folder+"/"+f.name)
} }
return errors.New("Cannot get symlink target") return errors.New("cannot get symlink target")
} }
fil.name = f.name fil.name = f.name
err = fil.ExtractWithOptions(folder, op) err = fil.ExtractWithOptions(folder, op)
@@ -318,7 +320,7 @@ func (f File) ExtractWithOptions(folder string, op ExtractionOptions) error {
if op.Verbose { if op.Verbose {
log.Println("Symlink path(", symPath, ") is unobtainable:", folder+"/"+f.name) log.Println("Symlink path(", symPath, ") is unobtainable:", folder+"/"+f.name)
} }
return errors.New("Cannot get symlink target") return errors.New("cannot get symlink target")
} }
extractLoc := path.Clean(folder + "/" + path.Dir(symPath)) extractLoc := path.Clean(folder + "/" + path.Dir(symPath))
err = fil.ExtractWithOptions(extractLoc, op) err = fil.ExtractWithOptions(extractLoc, op)
@@ -361,7 +363,7 @@ func (r *Reader) readDirFromInode(i *inode.Inode) ([]*directory.Entry, error) {
metaOffset = i.Info.(inode.ExtDir).DirectoryOffset metaOffset = i.Info.(inode.ExtDir).DirectoryOffset
size = i.Info.(inode.ExtDir).DirectorySize size = i.Info.(inode.ExtDir).DirectorySize
default: default:
return nil, errors.New("Not a directory inode") return nil, errors.New("not a directory inode")
} }
br, err := r.newMetadataReader(int64(r.super.DirTableStart + uint64(offset))) br, err := r.newMetadataReader(int64(r.super.DirTableStart + uint64(offset)))
if err != nil { if err != nil {
+7 -1
View File
@@ -22,7 +22,7 @@ type fileReader struct {
var ( var (
//ErrPathIsNotFile returns when trying to read from a file, but the given path is NOT a file. //ErrPathIsNotFile returns when trying to read from a file, but the given path is NOT a file.
errPathIsNotFile = errors.New("The given path is not a file") errPathIsNotFile = errors.New("the given path is not a file")
) )
//ReadFile provides a squashfs.FileReader for the file at the given location. //ReadFile provides a squashfs.FileReader for the file at the given location.
@@ -53,6 +53,9 @@ func (r *Reader) newFileReader(in *inode.Inode) (*fileReader, error) {
} }
if !rdr.fragOnly { if !rdr.fragOnly {
rdr.data, err = r.newDataReaderFromInode(in) rdr.data, err = r.newDataReaderFromInode(in)
if err != nil {
return nil, err
}
} }
return &rdr, nil return &rdr, nil
} }
@@ -72,6 +75,9 @@ func (f *fileReader) Read(p []byte) (int, error) {
if f.fragged && err == io.EOF { if f.fragged && err == io.EOF {
if f.fragmentData == nil { if f.fragmentData == nil {
f.fragmentData, err = f.r.getFragmentDataFromInode(f.in) f.fragmentData, err = f.r.getFragmentDataFromInode(f.in)
if err != nil {
return read, err
}
} }
n, err = bytes.NewBuffer(f.fragmentData).Read(p[read:]) n, err = bytes.NewBuffer(f.fragmentData).Read(p[read:])
read += n read += n
+1 -1
View File
@@ -46,7 +46,7 @@ func (r *Reader) getFragmentDataFromInode(in *inode.Inode) ([]byte, error) {
fragIndex = bf.FragmentIndex fragIndex = bf.FragmentIndex
fragOffset = bf.FragmentOffset fragOffset = bf.FragmentOffset
} else { } else {
return nil, errors.New("Inode type not supported") return nil, errors.New("inode type not supported")
} }
//reading the fragment entry first //reading the fragment entry first
fragEntryRdr, err := r.newMetadataReader(int64(r.fragOffsets[int(fragIndex/512)])) fragEntryRdr, err := r.newMetadataReader(int64(r.fragOffsets[int(fragIndex/512)]))
+10 -6
View File
@@ -39,7 +39,7 @@ func (f FS) Open(name string) (fs.File, error) {
Op: "open", Op: "open",
Path: name, Path: name,
//TODO: make error clearer //TODO: make error clearer
Err: errors.New("Trying to get file outside of squashfs"), Err: errors.New("trying to get file outside of squashfs"),
} }
} }
return f.parent.Open(strings.Join(split[1:], "/")) return f.parent.Open(strings.Join(split[1:], "/"))
@@ -107,7 +107,7 @@ func (f FS) Glob(pattern string) (out []string, err error) {
Op: "readdir", Op: "readdir",
Path: pattern, Path: pattern,
//TODO: make error clearer //TODO: make error clearer
Err: errors.New("Trying to get file outside of squashfs"), Err: errors.New("trying to get file outside of squashfs"),
} }
} }
return f.parent.Glob(strings.Join(split[1:], "/")) return f.parent.Glob(strings.Join(split[1:], "/"))
@@ -178,7 +178,7 @@ func (f FS) ReadDir(name string) ([]fs.DirEntry, error) {
Op: "readdir", Op: "readdir",
Path: name, Path: name,
//TODO: make error clearer //TODO: make error clearer
Err: errors.New("Trying to get file outside of squashfs"), Err: errors.New("trying to get file outside of squashfs"),
} }
} }
return f.parent.ReadDir(strings.Join(split[1:], "/")) return f.parent.ReadDir(strings.Join(split[1:], "/"))
@@ -294,7 +294,7 @@ func (f FS) Stat(name string) (fs.FileInfo, error) {
Op: "stat", Op: "stat",
Path: name, Path: name,
//TODO: make error clearer //TODO: make error clearer
Err: errors.New("Trying to get file outside of squashfs"), Err: errors.New("trying to get file outside of squashfs"),
} }
} }
return f.parent.Stat(strings.Join(split[1:], "/")) return f.parent.Stat(strings.Join(split[1:], "/"))
@@ -377,7 +377,7 @@ func (f FS) Sub(dir string) (fs.FS, error) {
Op: "sub", Op: "sub",
Path: dir, Path: dir,
//TODO: make error clearer //TODO: make error clearer
Err: errors.New("Trying to get file outside of squashfs"), Err: errors.New("trying to get file outside of squashfs"),
} }
} }
return f.parent.Sub(strings.Join(split[1:], "/")) return f.parent.Sub(strings.Join(split[1:], "/"))
@@ -435,6 +435,11 @@ func (f FS) Sub(dir string) (fs.FS, error) {
} }
func (f FS) path() string { func (f FS) path() string {
if f.name == "/" {
return f.name
} else if f.parent.name == "/" {
return f.name
}
return f.parent.path() + "/" + f.name return f.parent.path() + "/" + f.name
} }
@@ -472,7 +477,6 @@ func (f FS) ExtractWithOptions(folder string, op ExtractionOptions) error {
} }
errChan <- fil.ExtractWithOptions(folder, op) errChan <- fil.ExtractWithOptions(folder, op)
fil.Close() fil.Close()
return
}(&DirEntry{ }(&DirEntry{
en: f.entries[i], en: f.entries[i],
parent: &f, parent: &f,
+2 -2
View File
@@ -133,7 +133,7 @@ func (br *metadataReader) Read(p []byte) (int, error) {
} }
br.readOffset += read br.readOffset += read
if read != len(p) { if read != len(p) {
return read, errors.New("Didn't read enough data") return read, errors.New("didn't read enough data")
} }
return read, nil return read, nil
} }
@@ -181,7 +181,7 @@ func (br *metadataReader) Seek(offset int64, whence int) (int64, error) {
br.readOffset = len(br.data) - int(offset) br.readOffset = len(br.data) - int(offset)
if br.readOffset < 0 { if br.readOffset < 0 {
br.readOffset = 0 br.readOffset = 0
return int64(br.readOffset), errors.New("Trying to seek to a negative value") return int64(br.readOffset), errors.New("trying to seek to a negative value")
} }
} }
return int64(br.readOffset), nil return int64(br.readOffset), nil
+3 -6
View File
@@ -17,13 +17,11 @@ const (
var ( var (
//ErrNoMagic is returned if the magic number in the superblock isn't correct. //ErrNoMagic is returned if the magic number in the superblock isn't correct.
errNoMagic = errors.New("Magic number doesn't match. Either isn't a squashfs or corrupted") errNoMagic = errors.New("magic number doesn't match. Either isn't a squashfs or corrupted")
//ErrIncompatibleCompression is returned if the compression type in the superblock doesn't work. //ErrIncompatibleCompression is returned if the compression type in the superblock doesn't work.
errIncompatibleCompression = errors.New("Compression type unsupported") errIncompatibleCompression = errors.New("compression type unsupported")
//ErrCompressorOptions is returned if compressor options is present. It's not currently supported.
errCompressorOptions = errors.New("Compressor options is not currently supported")
//ErrOptions is returned when compression options that I haven't tested is set. When this is returned, the Reader is also returned. //ErrOptions is returned when compression options that I haven't tested is set. When this is returned, the Reader is also returned.
ErrOptions = errors.New("Possibly incompatible compressor options") ErrOptions = errors.New("possibly incompatible compressor options")
) )
//TODO: implement fs.FS, possibly more FS types for compatibility. Most of this work will mostly be handed off to root anyway so this shouldn't be too difficult. //TODO: implement fs.FS, possibly more FS types for compatibility. Most of this work will mostly be handed off to root anyway so this shouldn't be too difficult.
@@ -33,7 +31,6 @@ type Reader struct {
FS FS
r *io.SectionReader r *io.SectionReader
decompressor compression.Decompressor decompressor compression.Decompressor
root *File
fragOffsets []uint64 fragOffsets []uint64
idTable []uint32 idTable []uint32
super superblock super superblock
+4 -3
View File
@@ -42,13 +42,14 @@ func NewWriter() (*Writer, error) {
//NewWriterWithOptions creates a new squashfs.Writer with the given options. //NewWriterWithOptions creates a new squashfs.Writer with the given options.
//compressionType can be of any types, except LZO (which this library doesn't have support for yet) //compressionType can be of any types, except LZO (which this library doesn't have support for yet)
//allowErrors determines if, when adding folders, it allows errors encountered with it's sub-directories and instead logs the errors. //allowErrors determines, when adding folders, if it allows errors encountered with it's sub-directories
//and instead just logs the errors.
func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error) { func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error) {
if compressionType < 0 || compressionType > 6 { if compressionType < 0 || compressionType > 6 {
return nil, errors.New("Incorrect compression type") return nil, errors.New("incorrect compression type")
} }
if compressionType == 3 { if compressionType == 3 {
return nil, errors.New("Lzo compression is not (currently) supported") return nil, errors.New("LZO compression is not (currently) supported")
} }
writer := &Writer{ writer := &Writer{
structure: map[string][]*fileHolder{ structure: map[string][]*fileHolder{
+1 -1
View File
@@ -32,5 +32,5 @@ func (w *Writer) WriteTo(write io.Writer) (int64, error) {
MajorVersion: 4, MajorVersion: 4,
MinorVersion: 0, MinorVersion: 0,
} }
return 0, errors.New("I SAID DON'T") return 0, errors.New("i SAID DON'T")
} }