diff options
| author | jakob <jakob@memeware.net> | 2017-05-11 20:18:08 -0400 |
|---|---|---|
| committer | jakob <jakob@memeware.net> | 2017-05-11 20:18:08 -0400 |
| commit | 986a9e120d79f625cbd7b4c59ccfd479a6a149ec (patch) | |
| tree | d01d04bf547d15856a1471af7312b10c9c47ff53 /src | |
| parent | 93919335b1cff88127cb1d6e2ad1762dd7bf353e (diff) | |
Reimplemented table dumping functions to operate on streams instead of file pointers
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 13 | ||||
| -rw-r--r-- | src/table.c | 100 | ||||
| -rw-r--r-- | src/table.h | 6 |
3 files changed, 63 insertions, 56 deletions
@@ -207,13 +207,20 @@ static void create_archive(char **paths, int argc, struct params p) { return; } - struct header *h = create_header(); - struct table_entry *root = calloc(sizeof(struct table_entry), 1), *cur; + struct header *h = create_header(); + struct table_entry *root = calloc(sizeof(struct table_entry), 1), *cur; + struct stream *table = stream_new(1); dump_header(fp, h); for (int i = 1; i < argc - p.vararg_index; i++) { cur = add_file(root, paths[i]); } - dump_table(fp, root); + dump_table(table, root); + /* FIXME: table->len steps the bounds of the table and leaks memory + which can potentially be a huge security risk. Either fix the + functionality that expands the stream in memory, or get a table + size. */ + stream_seek(table, 0, SEEK_SET); + stream_dump(fp, table, table->len); } diff --git a/src/table.c b/src/table.c index afd2e0f..0582467 100644 --- a/src/table.c +++ b/src/table.c @@ -46,10 +46,10 @@ static void read_segm(struct stream *s, struct table_entry *tmp, uint64_t count) for (uint64_t i = 0; i < count; i++) { tmp->segments[i] = malloc(sizeof(struct segment)); if (tmp->segments[i] == NULL) return; - stream_read(&tmp->segments[i]->compressed, s, sizeof(uint32_t)); - stream_read(&tmp->segments[i]->offset, s, sizeof(uint64_t)); + stream_read(&tmp->segments[i]->compressed, s, sizeof(uint32_t)); + stream_read(&tmp->segments[i]->offset, s, sizeof(uint64_t)); stream_read(&tmp->segments[i]->decompressed_size, s, sizeof(uint64_t)); - stream_read(&tmp->segments[i]->compressed_size, s, sizeof(uint64_t)); + stream_read(&tmp->segments[i]->compressed_size, s, sizeof(uint64_t)); } } @@ -203,86 +203,86 @@ struct table_entry *add_file(struct table_entry *root, char *path) { } -/* Dumps the adlr segment for `key` into the table at `fp` and returns +/* Dumps the adlr segment for `key` into the table at `s` and returns the number of bytes written. */ -static uint64_t dump_adlr(FILE *fp, uint32_t key) { +static uint64_t dump_adlr(struct stream *s, uint32_t key) { uint32_t magic = ADLR_MAGIC; - uint64_t written, entry_size = sizeof(uint32_t); - written = fwrite(&magic, sizeof(uint32_t), 1, fp); - written += fwrite(&entry_size, sizeof(uint64_t), 1, fp); - written += fwrite(&key, sizeof(uint32_t), 1, fp); - return written; + uint64_t entry_size = sizeof(uint32_t); + stream_write(s, &magic, sizeof(uint32_t)); + stream_write(s, &entry_size, sizeof(uint64_t)); + stream_write(s, &key, sizeof(uint32_t)); + return 16; } -/* Dumps the time segment for `timestamp` into the table at `fp` and +/* Dumps the time segment for `timestamp` into the table at `s` and returns the number of bytes written. */ -static uint64_t dump_time(FILE *fp, uint64_t timestamp) { +static uint64_t dump_time(struct stream *s, uint64_t timestamp) { uint32_t magic = TIME_MAGIC; - uint64_t written, entry_size = sizeof(uint64_t); - written = fwrite(&magic, sizeof(uint32_t), 1, fp); - written += fwrite(&entry_size, sizeof(uint32_t), 1, fp); - written += fwrite(×tamp, sizeof(uint32_t), 1, fp); - return written; + uint64_t entry_size = sizeof(uint64_t); + stream_write(s, &magic, sizeof(uint32_t)); + stream_write(s, &entry_size, sizeof(uint64_t)); + stream_write(s, ×tamp, sizeof(uint64_t)); + return 20; } -/* Dumps the segm segment for `cur` into the table at `fp` and returns +/* Dumps the segm segment for `cur` into the table at `s` and returns the number of bytes written. */ -static uint64_t dump_segm(FILE *fp, struct table_entry *cur) { - struct segment *s; +static uint64_t dump_segm(struct stream *s, struct table_entry *cur) { + struct segment *segm; uint32_t magic = SEGM_MAGIC; - uint64_t written, entry_size = cur->segment_count * 28; - written = fwrite(&magic, sizeof(uint32_t), 1, fp); - written += fwrite(&entry_size, sizeof(uint32_t), 1, fp); + uint64_t entry_size = cur->segment_count * 28; + stream_write(s, &magic, sizeof(uint32_t)); + stream_write(s, &entry_size, sizeof(uint64_t)); for (uint64_t i = 0; i < cur->segment_count; i++) { - s = cur->segments[i]; - written += fwrite(&s->compressed, sizeof(uint32_t), 1, fp); - written += fwrite(&s->offset, sizeof(uint64_t), 1, fp); - written += fwrite(&s->decompressed_size, sizeof(uint64_t), 1, fp); - written += fwrite(&s->compressed_size, sizeof(uint64_t), 1, fp); + segm = cur->segments[i]; + stream_write(s, &segm->compressed, sizeof(uint32_t)); + stream_write(s, &segm->offset, sizeof(uint64_t)); + stream_write(s, &segm->decompressed_size, sizeof(uint64_t)); + stream_write(s, &segm->compressed_size, sizeof(uint64_t)); } - return written; + return 12 + 28 * cur->segment_count; } -/* Dumps the File entry for `cur` into the table at `fp`. */ -static void dump_file(FILE *fp, struct table_entry *cur) { +/* Dumps the File entry for `cur` into the table at `s`. */ +static void dump_file(struct stream *s, struct table_entry *cur) { uint32_t magic = FILE_MAGIC; uint64_t bytes_written; - fwrite(&magic, sizeof(uint32_t), 1, fp); - fwrite(&bytes_written, sizeof(uint64_t), 1, fp); - bytes_written = dump_adlr(fp, cur->key); - bytes_written += dump_time(fp, cur->ctime); - bytes_written += dump_segm(fp, cur); + stream_write(s, &magic, sizeof(uint32_t)); + stream_write(s, &bytes_written, sizeof(uint64_t)); + bytes_written = dump_adlr(s, cur->key); + bytes_written += dump_time(s, cur->ctime); + bytes_written += dump_segm(s, cur); - fseek(fp, -bytes_written, SEEK_CUR); - fwrite(&bytes_written, sizeof(uint64_t), 1, fp); - fseek(fp, bytes_written, SEEK_CUR); + stream_seek(s, -bytes_written, SEEK_CUR); + stream_write(s, &bytes_written, sizeof(uint64_t)); + stream_seek(s, bytes_written, SEEK_CUR); } -/* Dumps the eliF entry for `cur` into the table at `fp`. */ -static void dump_elif(FILE *fp, struct table_entry *cur) { +/* Dumps the eliF entry for `cur` into the table at `s`. */ +static void dump_elif(struct stream *s, struct table_entry *cur) { uint32_t magic = ELIF_MAGIC; uint16_t name_len = strlen(cur->filename); uint64_t entry_size = name_len * 2 + 8; char *encoded = malloc(name_len * 2 + 2); utf16le_encode(cur->filename, encoded, name_len); - fwrite(&magic, sizeof(uint32_t), 1, fp); - fwrite(&entry_size, sizeof(uint64_t), 1, fp); - fwrite(&cur->key, sizeof(uint32_t), 1, fp); - fwrite(&name_len, sizeof(uint16_t), 1, fp); - fwrite(encoded, name_len * 2 + 2, 1, fp); + stream_write(s, &magic, sizeof(uint32_t)); + stream_write(s, &entry_size, sizeof(uint64_t)); + stream_write(s, &cur->key, sizeof(uint32_t)); + stream_write(s, &name_len, sizeof(uint16_t)); + stream_write(s, encoded, name_len * 2 + 2); } -/* Dumps the XP3 table specified by `root` into `fp`. */ -void dump_table(FILE *fp, struct table_entry *root) { +/* Dumps the XP3 table specified by `root` into `s`. */ +void dump_table(struct stream *s, struct table_entry *root) { struct table_entry *cur; for (cur = root->next; cur != NULL; cur = cur->next) { - dump_elif(fp, cur); - dump_file(fp, cur); + dump_elif(s, cur); + dump_file(s, cur); } } diff --git a/src/table.h b/src/table.h index d9e9f53..dd01fa3 100644 --- a/src/table.h +++ b/src/table.h @@ -27,7 +27,7 @@ /* Structure representing one segment associated with a File entry. */ struct segment { - bool compressed; /* Whether or not the segment is compressed. */ + uint32_t compressed; /* Whether or not the segment is compressed. */ uint64_t offset; /* Offset to the segment's beginning. */ uint64_t compressed_size; /* Size of compressed segment. */ uint64_t decompressed_size; /* Size of decompressed segment. */ @@ -74,8 +74,8 @@ void entry_append(struct table_entry *root, struct table_entry *e); /* Frees every entry in the linked list specified by `cur`. */ void entry_free(struct table_entry *cur); -/* Dumps the XP3 table specified by `root` into `fp`. */ -void dump_table(FILE *fp, struct table_entry *root); +/* Dumps the XP3 table specified by `root` into `s`. */ +void dump_table(struct stream *s, struct table_entry *root); /* Inserts the file specified by `path` into the table linked list specified by `root`. */ |