From a37ccaff50e50cf3553d4bc7852a3e389e85535d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 27 Nov 2021 16:31:03 +0100 Subject: [PATCH] otrx: support unsorted partitions offsets MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit TRX format doesn't guarantee that it contains partitions offsets in a sorted order. Store partitions info in context struct and make sure it's sorted. Signed-off-by: Rafał Miłecki --- src/otrx.c | 54 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/otrx.c b/src/otrx.c index 7f661ca..5ee310c 100644 --- a/src/otrx.c +++ b/src/otrx.c @@ -42,9 +42,16 @@ struct trx_header { uint32_t offset[3]; }; +struct otrx_part { + int idx; + size_t offset; + size_t length; +}; + struct otrx_ctx { FILE *fp; struct trx_header hdr; + struct otrx_part parts[TRX_MAX_PARTS]; /* Sorted partitions */ }; char *trx_path; @@ -174,12 +181,26 @@ static void otrx_close(FILE *fp) { fclose(fp); } +static int otrx_part_compar(const void *a, const void *b) +{ + const struct otrx_part *partA = a; + const struct otrx_part *partB = b; + + if (!partA->offset) + return 1; + if (!partB->offset) + return -1; + + return partA->offset - partB->offset; +} + static int otrx_open_parse(const char *pathname, const char *mode, struct otrx_ctx *otrx) { size_t length; size_t bytes; int err; + int i; otrx->fp = otrx_open(pathname, mode); if (!otrx->fp) { @@ -214,6 +235,22 @@ static int otrx_open_parse(const char *pathname, const char *mode, goto err_close; } + for (i = 0; i < TRX_MAX_PARTS; i++) { + otrx->parts[i].idx = i; + otrx->parts[i].offset = le32_to_cpu(otrx->hdr.offset[i]); + } + qsort(otrx->parts, TRX_MAX_PARTS, sizeof(otrx->parts[0]), otrx_part_compar); + + /* Calculate length of every partition */ + for (i = 0; i < TRX_MAX_PARTS; i++) { + if (otrx->parts[i].offset) { + if (i + 1 >= TRX_MAX_PARTS || !otrx->parts[i + 1].offset) + otrx->parts[i].length = le32_to_cpu(otrx->hdr.length) - otrx->parts[i].offset; + else + otrx->parts[i].length = otrx->parts[i + 1].offset - otrx->parts[i].offset; + } + } + return 0; err_close: @@ -589,21 +626,14 @@ static int otrx_extract(int argc, char **argv) { } for (i = 0; i < TRX_MAX_PARTS; i++) { - size_t length; + struct otrx_part *part = &otrx.parts[i]; - if (!partition[i]) - continue; - if (!otrx.hdr.offset[i]) { - printf("TRX doesn't contain partition %d, can't extract %s\n", i + 1, partition[i]); + if (!part->offset && partition[part->idx]) + printf("TRX doesn't contain partition %d, can't extract %s\n", part->idx + 1, partition[part->idx]); + if (!part->offset || !partition[part->idx]) continue; - } - - if (i + 1 >= TRX_MAX_PARTS || !otrx.hdr.offset[i + 1]) - length = le32_to_cpu(otrx.hdr.length) - le32_to_cpu(otrx.hdr.offset[i]); else - length = le32_to_cpu(otrx.hdr.offset[i + 1]) - le32_to_cpu(otrx.hdr.offset[i]); - - otrx_extract_copy(otrx.fp, trx_offset + le32_to_cpu(otrx.hdr.offset[i]), length, partition[i]); + otrx_extract_copy(otrx.fp, trx_offset + part->offset, part->length, partition[part->idx]); } otrx_close(otrx.fp); -- 2.30.2