Skip to content

Commit 28583ea

Browse files
committed
squashfs: fix error format when file larger than block size
https://dr-emann.github.io/squashfs/squashfs.html#_file_inodes Due to SquashFS spec, file inode's 'blocks start' field means the offset from the beginning of the file. This commit also fixes the fragmentData location calculation. Finally, due to Spec, if a file does not have fragment data, its frag index should be all 0xF. Fixes #282 Signed-off-by: Xynnn007 <[email protected]>
1 parent 6693615 commit 28583ea

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

filesystem/squashfs/finalize.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,13 @@ func (fs *FileSystem) Finalize(options FinalizeOptions) error {
111111
b []byte
112112
)
113113
location += superblockSize
114+
dataBlocksOffset := int64(superblockSize)
114115
if options.Compression != nil {
115116
b = options.Compression.optionsBytes()
116117
if len(b) > 0 {
117118
_, _ = f.WriteAt(b, location)
118119
location += int64(len(b))
120+
dataBlocksOffset += int64(len(b))
119121
}
120122
}
121123

@@ -137,11 +139,11 @@ func (fs *FileSystem) Finalize(options FinalizeOptions) error {
137139
// write file fragments
138140
//
139141
fragmentBlockStart := location
140-
fragmentBlocks, fragsWritten, err := writeFragmentBlocks(fileList, f, fs.workspace, blocksize, options, fragmentBlockStart)
142+
fragmentBlocks, _, err := writeFragmentBlocks(fileList, f, fs.workspace, blocksize, options, fragmentBlockStart)
141143
if err != nil {
142144
return fmt.Errorf("error writing file fragment blocks: %v", err)
143145
}
144-
location += fragsWritten
146+
location += int64(len(fragmentBlocks) * blocksize)
145147

146148
// extract extended attributes, and save them for later; these are written at the very end
147149
// this must be done *before* creating inodes, as inodes reference these
@@ -538,6 +540,7 @@ func writeFileDataBlocks(e *finalizeFileInfo, to backend.WritableFile, ws string
538540
e.dataLocation = location
539541
e.blocks = blocks
540542
e.startBlock = startBlock
543+
e.startFromBegin = location
541544

542545
// how many blocks did we write?
543546
blockCount = raw / blocksize
@@ -588,7 +591,9 @@ func writeDataBlocks(fileList []*finalizeFileInfo, f backend.WritableFile, ws st
588591
}
589592
allBlocks += blocks
590593
allWritten += written
594+
location += int64(written)
591595
}
596+
592597
return allWritten, nil
593598
}
594599

@@ -637,9 +642,10 @@ func writeFragmentBlocks(fileList []*finalizeFileInfo, f backend.WritableFile, w
637642
compressed: compressed,
638643
location: location,
639644
})
645+
location += int64((written + blocksize - 1) / blocksize * blocksize)
640646
// increment as all writes will be to next block block
641647
fragmentBlockIndex++
642-
fragmentData = fragmentData[:blocksize]
648+
fragmentData = make([]byte, 0)
643649
}
644650

645651
e.fragment = &fragmentRef{
@@ -1119,13 +1125,15 @@ func createInodes(fileList []*finalizeFileInfo, idtable map[uint32]uint16, optio
11191125
} else {
11201126
// use basicFile
11211127
bf := &basicFile{
1122-
startBlock: uint32(e.startBlock),
1128+
startBlock: uint32(e.startFromBegin),
11231129
fileSize: uint32(e.Size()),
11241130
blockSizes: e.blocks,
11251131
}
11261132
if e.fragment != nil {
11271133
bf.fragmentBlockIndex = e.fragment.block
11281134
bf.fragmentOffset = e.fragment.offset
1135+
} else {
1136+
bf.fragmentBlockIndex = 0xffffffff
11291137
}
11301138
in = bf
11311139
inodeT = inodeBasicFile

filesystem/squashfs/finalizefileinfo.go

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type finalizeFileInfo struct {
4141
links uint32
4242
blocks []*blockData
4343
startBlock uint64
44+
startFromBegin int64
4445
fragment *fragmentRef
4546
uid uint32
4647
gid uint32

0 commit comments

Comments
 (0)