I figured out the cause for the segfault in writeClusterChain.
Boris, I previously reported this issue to the Debian bug tracking
system. If that report didn't reach you, you can read it at
http://bugs.debian.org/543986 .
You can download a disk image at:
http://igwe.vub.ac.be/~pdewacht/fatsort-bug-image2.bz2
(54MB compressed, 8GB uncompressed).
On this file system, the root directory looks like this:
cluster 2:
entry 1: long name: ##MUSIC#
entry 2: short name: ##MUSIC#
...
entry 15: long name: SYS_CONF.SYS
entry 16: short name: SYS_CONF.SYS
entry 17: empty
cluster 549234:
entry 1: deleted file: ?SCK0000.050
entry 2: empty
When the parseClusterChain function sees the empty entry in the first
cluster, it stops processing that cluster but continues with the next
one in the chain. It then encounters the deleted file, for which it
generates a sDirEntryList record with an incorrect entries field.
When fatsort later tries to write out that record, it segfaults.
The information I collected on FAT indicates that after an empty
entry, no in-use entry can follow (i.e. only empty entries and deleted
files can follow). So it should be okay for fatsort to stop following
the chain after encountering the first empty entry. The attached patch
implements this, and fixes my segfault.
Peter De Wachter
--- a/src/sort.c
+++ b/src/sort.c
@@ -206,7 +206,7 @@ int32_t parseClusterChain(FILE *fd, struct sBootSector *bs, struct sClusterChain
myerror("Failed to parse directory entry!");
return -1;
} else if (ret == 0) {
- break;
+ goto no_more_files;
} else if (ret == 2) {
parseLongFilenamePart(&de.LongDirEntry, tmp);
@@ -246,6 +246,7 @@ int32_t parseClusterChain(FILE *fd, struct sBootSector *bs, struct sClusterChain
}
chain=chain->next;
}
+no_more_files:
return 0;
}