Compare commits

..

4 commits

Author SHA1 Message Date
6ab4de1ddb dosfs: use calloc instead of malloc
calloc zeroes out the memory it allocates, which helps avoid
segfaults related to linked list traversal.
2020-11-17 12:58:11 -08:00
7f7b05cf05 dosfs: parsing fixes
* don't include spaces in fext
* read fat12 chains properly
2020-11-17 12:55:16 -08:00
c078497b40 TODO: update TODO
Continuing to use pread/pwrite since we'll probably be dealing a
lot with random fragmented files. The rest that were removed have
been dealt with.
2020-11-16 22:58:07 -08:00
cfc1f19ec6 config: deal with whitespace at line start 2020-11-16 22:56:40 -08:00
3 changed files with 30 additions and 16 deletions

4
TODO
View file

@ -1,5 +1 @@
Implement randomness (xorshift? https://www.jstatsoft.org/article/view/v008i14)
Config parser (config.c)
Do the actual corrupty things Do the actual corrupty things
Use fopen(3) and friends instead of open(2)

View file

@ -62,6 +62,11 @@ parse_config(char *path)
continue; continue;
} }
/* Assume there's some extra whitespace at the start and ignore it */
if (state == ST_FILENAME && i == 0) {
break;
}
/* only run on the first whitespace */ /* only run on the first whitespace */
if (!ws) { if (!ws) {
DPRINTF(("i = %d\n", i)); DPRINTF(("i = %d\n", i));

View file

@ -126,7 +126,7 @@ dos_listdir(dosfs_t *fsd, unsigned int offset)
} }
if (i > 0) { if (i > 0) {
cur->next = malloc(sizeof(dosfile_t)); cur->next = calloc(1, sizeof(dosfile_t));
if (cur->next == NULL) { if (cur->next == NULL) {
DPRINTF(("inner malloc failed!?\n")); DPRINTF(("inner malloc failed!?\n"));
res = -1; res = -1;
@ -147,9 +147,14 @@ dos_listdir(dosfs_t *fsd, unsigned int offset)
cur->fname[8] = 0; cur->fname[8] = 0;
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
cur->fext[j] = dirs[i].filename[j+8]; if (dirs[i].filename[j+8] == ' ') {
cur->fext[j] = 0;
break;
} else {
cur->fext[j] = dirs[i].filename[j+8];
}
} }
cur->fext[4] = 0; cur->fext[3] = 0;
(void)memcpy(&cur->ent, &dirs[i], sizeof(struct dos_dirent)); (void)memcpy(&cur->ent, &dirs[i], sizeof(struct dos_dirent));
@ -190,8 +195,9 @@ dos_freedir(dosfile_t *dirs)
static unsigned int * static unsigned int *
read_fat_chain(dosfs_t *fsd, unsigned int first, int *length) read_fat_chain(dosfs_t *fsd, unsigned int first, int *length)
{ {
unsigned int cur, foff, byte_off, *chain = NULL; unsigned int foff, byte_off, *chain = NULL;
uint16_t next; uint16_t next, cur;
uint8_t nbuf[3];
int len = 0, res; int len = 0, res;
cur = first; cur = first;
@ -204,12 +210,12 @@ read_fat_chain(dosfs_t *fsd, unsigned int first, int *length)
return NULL; return NULL;
} }
foff = (fsd->fs_ver == 12) ? (cur + (cur / 2)) : /* fat12 */ /* get byte offset of FAT entry */
foff = (fsd->fs_ver == 12) ? ((cur / 2)*3) : /* fat12 */
(cur * 2); /* fat16 */ (cur * 2); /* fat16 */
byte_off = (fsd->ib.resv_sect * fsd->ib.sect_size) + foff; byte_off = (fsd->ib.resv_sect * fsd->ib.sect_size) + foff;
/* XXX: endianness */ res = pread(fsd->ifd, &nbuf, 3, byte_off);
res = pread(fsd->ifd, &next, 2, byte_off);
if (res == -1) { if (res == -1) {
DPRINTF(("pread failed\n")); DPRINTF(("pread failed\n"));
free(chain); free(chain);
@ -217,21 +223,27 @@ read_fat_chain(dosfs_t *fsd, unsigned int first, int *length)
} }
if (fsd->fs_ver == 12) { if (fsd->fs_ver == 12) {
if (cur & 0x0001) { if (cur % 2) {
next = next >> 4; next = (nbuf[1] >> 4) | (uint16_t)(nbuf[2] << 4);
} else { } else {
next = next & 0x0FFF; next = (uint16_t)(nbuf[1] & 0x0f) << 8 | nbuf[0];
} }
if (next == 0x0FFF) { if (next == 0x0FFF) {
break; break;
} else if (next < 2 || next > 0xFF7) {
DPRINTF(("got weird sector %x from %x, bailing...\n", next, cur));
free(chain);
return NULL;
} }
} else { } else {
next = nbuf[0] | (uint16_t)nbuf[1] << 8;
if (next == 0xFFFF) { if (next == 0xFFFF) {
break; break;
} }
} }
chain[len-1] = next; chain[len-1] = next;
cur = next;
} }
*length = len; *length = len;
@ -249,7 +261,7 @@ get_byte_offset(dosfs_t *fsd, dosfile_t *file, unsigned int f_offset)
if (f_offset > file->ent.size) { if (f_offset > file->ent.size) {
DPRINTF(("offset requested is out of bounds!\n")); DPRINTF(("offset requested is out of bounds!\n"));
return -EINVAL; return -ERANGE;
} }
/* size in bytes of a cluster */ /* size in bytes of a cluster */
@ -265,3 +277,4 @@ get_byte_offset(dosfs_t *fsd, dosfile_t *file, unsigned int f_offset)
return (file->fat_chain[coff] * csz) + (f_offset % csz); return (file->fat_chain[coff] * csz) + (f_offset % csz);
} }