Skip to content

Commit

Permalink
sectorsize should not be a global
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlehane committed Jun 16, 2018
1 parent 5013c87 commit ed4c008
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 29 deletions.
12 changes: 6 additions & 6 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ func (r *Reader) setDirEntries() error {
}
de := make([]*File, 0, c)
cycles := make(map[uint32]bool)
num := int(sectorSize / 128)
num := int(r.sectorSize / 128)
sn := r.header.directorySectorLoc
for sn != endOfChain {
buf, err := r.readAt(fileOffset(sn), int(sectorSize))
buf, err := r.readAt(fileOffset(r.sectorSize, sn), int(r.sectorSize))
if err != nil {
return Error{ErrRead, "directory entries read error (" + err.Error() + ")", fileOffset(sn)}
return Error{ErrRead, "directory entries read error (" + err.Error() + ")", fileOffset(r.sectorSize, sn)}
}
for i := 0; i < num; i++ {
f := &File{r: r}
Expand Down Expand Up @@ -388,7 +388,7 @@ func (f *File) seek(sz int64) error {
mini = true
ss = 64
} else {
ss = int64(sectorSize)
ss = int64(f.r.sectorSize)
}

var j int64
Expand Down Expand Up @@ -444,8 +444,8 @@ func (f *File) stream(sz int) ([][2]int64, error) {
l = sz/64 + 2
ss = 64
} else {
l = sz/int(sectorSize) + 2
ss = int64(sectorSize)
l = sz/int(f.r.sectorSize) + 2
ss = int64(f.r.sectorSize)
}

sectors := make([][2]int64, 0, l)
Expand Down
41 changes: 18 additions & 23 deletions mscfb.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,8 @@ import (
"time"
)

var sectorSize uint32

func setSectorSize(ss uint16) {
sectorSize = uint32(1 << ss)
}

func fileOffset(sn uint32) int64 {
return int64((sn + 1) * sectorSize)
func fileOffset(ss, sn uint32) int64 {
return int64((sn + 1) * ss)
}

const (
Expand Down Expand Up @@ -131,13 +125,13 @@ func (r *Reader) setHeader() error {
}
// check for legal sector size
if r.header.sectorSize == 0x0009 || r.header.sectorSize == 0x000c {
setSectorSize(r.header.sectorSize)
r.sectorSize = uint32(1 << r.header.sectorSize)
} else {
return Error{ErrFormat, "illegal sector size", int64(r.header.sectorSize)}
}
// check for DIFAT overflow
if r.header.numDifatSectors > 0 {
sz := (sectorSize / 4) - 1
sz := (r.sectorSize / 4) - 1
if int(r.header.numDifatSectors*sz+109) < 0 {
return Error{ErrFormat, "DIFAT int overflow", int64(r.header.numDifatSectors)}
}
Expand All @@ -147,10 +141,10 @@ func (r *Reader) setHeader() error {
}
// check for mini FAT overflow
if r.header.numMiniFatSectors > 0 {
if int(sectorSize/4*r.header.numMiniFatSectors) < 0 {
if int(r.sectorSize/4*r.header.numMiniFatSectors) < 0 {
return Error{ErrFormat, "mini FAT int overflow", int64(r.header.numMiniFatSectors)}
}
if r.header.numMiniFatSectors > r.header.numFatSectors*(sectorSize/miniStreamSectorSize) {
if r.header.numMiniFatSectors > r.header.numFatSectors*(r.sectorSize/miniStreamSectorSize) {
return Error{ErrFormat, "num mini FATs exceeds FAT sectors", int64(r.header.numFatSectors)}
}
}
Expand All @@ -163,13 +157,13 @@ func (r *Reader) setDifats() error {
if r.header.numDifatSectors == 0 {
return nil
}
sz := (sectorSize / 4) - 1
sz := (r.sectorSize / 4) - 1
n := make([]uint32, 109, r.header.numDifatSectors*sz+109)
copy(n, r.header.difats)
r.header.difats = n
off := r.header.difatSectorLoc
for i := 0; i < int(r.header.numDifatSectors); i++ {
buf, err := r.readAt(fileOffset(off), int(sectorSize))
buf, err := r.readAt(fileOffset(r.sectorSize, off), int(r.sectorSize))
if err != nil {
return Error{ErrFormat, "error setting DIFAT(" + err.Error() + ")", int64(off)}
}
Expand Down Expand Up @@ -199,7 +193,7 @@ func (r *Reader) setMiniStream() error {
r.header.miniFatLocs[i] = loc
}
// build a slice of ministream sectors
c = int(sectorSize / 4 * r.header.numMiniFatSectors)
c = int(r.sectorSize / 4 * r.header.numMiniFatSectors)
r.header.miniStreamLocs = make([]uint32, 0, c)
sn := r.direntries[0].startingSectorLoc
var err error
Expand Down Expand Up @@ -232,20 +226,20 @@ func (r *Reader) readAt(offset int64, length int) ([]byte, error) {

func (r *Reader) getOffset(sn uint32, mini bool) (int64, error) {
if mini {
num := sectorSize / 64
num := r.sectorSize / 64
sec := int(sn / num)
if sec >= len(r.header.miniStreamLocs) {
return 0, Error{ErrRead, "minisector number is outside minisector range", int64(sec)}
}
dif := sn % num
return int64((r.header.miniStreamLocs[sec]+1)*sectorSize + dif*64), nil
return int64((r.header.miniStreamLocs[sec]+1)*r.sectorSize + dif*64), nil
}
return fileOffset(sn), nil
return fileOffset(r.sectorSize, sn), nil
}

// check the FAT sector for the next sector in a chain
func (r *Reader) findNext(sn uint32, mini bool) (uint32, error) {
entries := sectorSize / 4
entries := r.sectorSize / 4
index := int(sn / entries) // find position in DIFAT or minifat array
var sect uint32
if mini {
Expand All @@ -260,7 +254,7 @@ func (r *Reader) findNext(sn uint32, mini bool) (uint32, error) {
sect = r.header.difats[index]
}
fatIndex := sn % entries // find position within FAT or MiniFAT sector
offset := fileOffset(sect) + int64(fatIndex*4)
offset := fileOffset(r.sectorSize, sect) + int64(fatIndex*4)
buf, err := r.readAt(offset, 4)
if err != nil {
return 0, Error{ErrRead, "bad read finding next sector (" + err.Error() + ")", offset}
Expand All @@ -271,6 +265,7 @@ func (r *Reader) findNext(sn uint32, mini bool) (uint32, error) {
// Reader provides sequential access to the contents of a MS compound file (MSCFB)
type Reader struct {
slicer bool
sectorSize uint32
buf []byte
header *header
File []*File // File is an ordered slice of final directory entries.
Expand All @@ -293,8 +288,8 @@ func New(ra io.ReaderAt) (*Reader, error) {
return nil, err
}
// resize the buffer to 4096 if sector size isn't 512
if !r.slicer && int(sectorSize) > len(r.buf) {
r.buf = make([]byte, sectorSize)
if !r.slicer && int(r.sectorSize) > len(r.buf) {
r.buf = make([]byte, r.sectorSize)
}
if err := r.setDifats(); err != nil {
return nil, err
Expand Down Expand Up @@ -347,7 +342,7 @@ func (r *Reader) Read(b []byte) (n int, err error) {
// Debug provides granular information from an mscfb file to assist with debugging
func (r *Reader) Debug() map[string][]uint32 {
ret := map[string][]uint32{
"sector size": []uint32{sectorSize},
"sector size": []uint32{r.sectorSize},
"mini fat locs": r.header.miniFatLocs,
"mini stream locs": r.header.miniStreamLocs,
"directory sector": []uint32{r.header.directorySectorLoc},
Expand Down

0 comments on commit ed4c008

Please sign in to comment.