diff --git a/umdiff/compare.c b/umdiff/compare.c index de8e54e..46c4a27 100644 --- a/umdiff/compare.c +++ b/umdiff/compare.c @@ -115,6 +115,7 @@ umdiff_File_fromCompare(umdiff_File *file, int source_fd, int target_fd) rs_job_drive(sigJob, &buffers, _impl_umdiff_fileJobSource, source_fd_.opaque, _impl_umdiff_sigJobSink, workSignatures); + dprintf(1, "Extracted signatures.\n"); buffers = (rs_buffers_t) { .eof_in = 0, .avail_in = 0, @@ -125,6 +126,7 @@ umdiff_File_fromCompare(umdiff_File *file, int source_fd, int target_fd) rs_job_drive(deltaJob, &buffers, _impl_umdiff_fileJobSource, target_fd_.opaque, _impl_umdiff_deltaJobSink, file); + dprintf(1, "Generated deltas.\n"); free(workSignatures); diff --git a/umdiff/file.c b/umdiff/file.c index 392d2e9..73843aa 100644 --- a/umdiff/file.c +++ b/umdiff/file.c @@ -69,10 +69,19 @@ umdiff_File_write(umdiff_File *file, int outfd) _impl_umdiff_RawHeader rheader; int ret; - if (!file || file->mode != umdiff_FileFlags_LOAD_FULL - || !file->commands || !file->data - || !file->hdr.cmd_count || !file->hdr.index[0]) + if (!file || file->mode != umdiff_FileFlags_LOAD_FULL) { + dprintf(1, "File object is in incomplete mode. Cannot proceed.\n"); return 1; + } else if (!file->commands || !file->data) { + dprintf(1, "File object is missing commands or data buffer. Cannot proceed.\n"); + return 1; + } else if (!file->hdr.cmd_count) { + dprintf(1, "File object has zero commands. Cannot proceed.\n"); + return 1; + } else if (!file->hdr.index[0]) { + dprintf(1, "File object has an empty index.\n"); + //return 1; + } rheader.hdr = file->hdr; diff --git a/umdiff/main.c b/umdiff/main.c index 581f7f4..83a65b7 100644 --- a/umdiff/main.c +++ b/umdiff/main.c @@ -11,6 +11,7 @@ #include #include +#include #include "usage.rl.h" #include "compare.h" @@ -19,11 +20,23 @@ int umdiff_delta(char *source, char *target, char *output) { int source_fd, target_fd, output_fd; + size_t tgt_sz; umdiff_File result; source_fd = open(source, O_RDONLY); target_fd = open(target, O_RDONLY); + tgt_sz = lseek(target_fd, 0, SEEK_END); + lseek(target_fd, 0, SEEK_SET); + + // Naive worst case alloc + //TODO: Use progressive block-based reallocs instead + result.commands = malloc(sizeof(umdiff_Command) * (tgt_sz / ISO_SECTOR_SIZE)); + result.data = malloc(tgt_sz); + result.mode = umdiff_FileFlags_LOAD_FULL; + result.data_len = 0; + result.hdr.cmd_count = 0; + umdiff_File_fromCompare(&result, source_fd, target_fd); output_fd = open(output, O_WRONLY|O_CREAT|O_TRUNC, 0644); diff --git a/umdiff/rdiff.c b/umdiff/rdiff.c index 3d52bbe..b076d4d 100644 --- a/umdiff/rdiff.c +++ b/umdiff/rdiff.c @@ -15,6 +15,7 @@ #include #include #include +#include typedef struct { enum rs_op_kind kind; @@ -40,7 +41,23 @@ _impl_umdiff_RdiffCommand_parse(_impl_umdiff_RdiffCommand *cmd, char *buf, size_ if (entry.kind == RS_KIND_COPY) { memcpy(&cmd->copy_offset, buf+1, entry.len_1); + switch (entry.len_1) { + case 2: + cmd->copy_offset = be16toh(cmd->copy_offset); break; + case 4: + cmd->copy_offset = be32toh(cmd->copy_offset); break; + case 8: + cmd->copy_offset = be64toh(cmd->copy_offset); break; + } memcpy(&cmd->len, buf+entry.len_1+1, entry.len_2); + switch (entry.len_2) { + case 2: + cmd->len = be16toh(cmd->len); break; + case 4: + cmd->len = be32toh(cmd->len); break; + case 8: + cmd->len = be64toh(cmd->len); break; + } return entry.len_1 + entry.len_2 + 1; } else { memcpy(&cmd->len, buf+1, entry.len_1); @@ -73,13 +90,14 @@ _impl_umdiff_File_feedData(umdiff_File *file, char *buf, size_t len) int umdiff_File_feedCommands(umdiff_File *file, char *buf, size_t len) { - umdiff_Command *lastCommand, *newCommand; + umdiff_Command *lastCommand = NULL, *newCommand; _impl_umdiff_RdiffCommand rdiffCommand; int ret, progress = 0; if (file->hdr.cmd_count == 0 && file->data_len == 0 - && (int) *buf == RS_DELTA_MAGIC) { + && (int) *buf == htobe32(RS_DELTA_MAGIC)) { + dprintf(1, "Encountered magic"); buf += sizeof RS_DELTA_MAGIC; len -= sizeof RS_DELTA_MAGIC; } @@ -89,10 +107,10 @@ umdiff_File_feedCommands(umdiff_File *file, char *buf, size_t len) && (x->patch_start + x->patch_sector_count) > (file->data_len / ISO_SECTOR_SIZE)) if (file->hdr.cmd_count > 0) - lastCommand = &file->commands[file->hdr.cmd_count - 1]; + lastCommand = &(file->commands[file->hdr.cmd_count - 1]); while (len) { - if (_impl_umdiff_Command_isUnfinished$(lastCommand)) { + if (lastCommand && _impl_umdiff_Command_isUnfinished$(lastCommand)) { ret = _impl_umdiff_File_feedData(file, buf, len); buf += ret; len -= ret; @@ -106,9 +124,11 @@ umdiff_File_feedCommands(umdiff_File *file, char *buf, size_t len) buf += ret; progress += ret; + dprintf(1, "Length: %ld, offset: %ld\n", rdiffCommand.len, rdiffCommand.copy_offset); + if (rdiffCommand.len % ISO_SECTOR_SIZE || rdiffCommand.copy_offset % ISO_SECTOR_SIZE) { - dprintf(1, "Misaligned command!\n"); + dprintf(1, "Misaligned command! Length %ld, offset %ld\n", rdiffCommand.len, rdiffCommand.copy_offset); exit(4); } @@ -116,7 +136,9 @@ umdiff_File_feedCommands(umdiff_File *file, char *buf, size_t len) file->hdr.cmd_count += 1; newCommand->data_source = (rdiffCommand.kind == RS_KIND_COPY); - newCommand->sector_start = lastCommand->sector_start + lastCommand->sector_count; + newCommand->sector_start = lastCommand + ? lastCommand->sector_start + lastCommand->sector_count + : 0; newCommand->sector_count = rdiffCommand.len / ISO_SECTOR_SIZE; newCommand->patch_sector_count = rdiffCommand.len / ISO_SECTOR_SIZE; newCommand->patch_start = (rdiffCommand.kind == RS_KIND_COPY)