Some quick fixes for "correctness"
This commit is contained in:
+5
-10
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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)]))
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user