From 1ca521eec9c6b3948e158841ecb3b503749d3d5d Mon Sep 17 00:00:00 2001 From: Saleem Rashid Date: Wed, 2 Oct 2019 16:43:21 +0100 Subject: [PATCH] legacy/nem: Refactor nem_canonicalizeMosaics GCC is able to reason about transfer->mosaics_count using Value Range Propagation. Using transfer->mosaics_count, instead of a mosaics_count argument, satisfies GCC that the variable-length skip array cannot be too large. Renamed variables to old_count and new_count to reduce ambiguity. --- legacy/firmware/fsm_msg_nem.h | 3 +-- legacy/firmware/nem2.c | 31 +++++++++++++++++-------------- legacy/firmware/nem2.h | 2 +- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/legacy/firmware/fsm_msg_nem.h b/legacy/firmware/fsm_msg_nem.h index b9610600b..ec89f2db0 100644 --- a/legacy/firmware/fsm_msg_nem.h +++ b/legacy/firmware/fsm_msg_nem.h @@ -132,8 +132,7 @@ void fsm_msgNEMSignTx(NEMSignTx *msg) { hdnode_get_nem_address(node, common->network, address); if (msg->has_transfer) { - msg->transfer.mosaics_count = nem_canonicalizeMosaics( - msg->transfer.mosaics, msg->transfer.mosaics_count); + nem_canonicalizeMosaics(&msg->transfer); } if (msg->has_transfer && !nem_askTransfer(common, &msg->transfer, network)) { diff --git a/legacy/firmware/nem2.c b/legacy/firmware/nem2.c index 842723300..8fb7b2373 100644 --- a/legacy/firmware/nem2.c +++ b/legacy/firmware/nem2.c @@ -700,27 +700,31 @@ static inline size_t format_amount(const NEMMosaicDefinition *definition, -divisor, false, str_out, size); } -size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count) { - if (mosaics_count <= 1) { - return mosaics_count; +void nem_canonicalizeMosaics(NEMTransfer *transfer) { + size_t old_count = transfer->mosaics_count; + + if (old_count <= 1) { + return; } - size_t actual_count = 0; + NEMMosaic *const mosaics = transfer->mosaics; - bool skip[mosaics_count]; + bool skip[old_count]; memzero(skip, sizeof(skip)); + size_t new_count = 0; + // Merge duplicates - for (size_t i = 0; i < mosaics_count; i++) { + for (size_t i = 0; i < old_count; i++) { if (skip[i]) continue; - NEMMosaic *mosaic = &mosaics[actual_count]; + NEMMosaic *mosaic = &mosaics[new_count]; - if (actual_count++ != i) { + if (new_count++ != i) { memcpy(mosaic, &mosaics[i], sizeof(NEMMosaic)); } - for (size_t j = i + 1; j < mosaics_count; j++) { + for (size_t j = i + 1; j < old_count; j++) { if (skip[j]) continue; const NEMMosaic *new_mosaic = &mosaics[j]; @@ -732,24 +736,23 @@ size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count) { } } - NEMMosaic temp; + transfer->mosaics_count = new_count; // Sort mosaics - for (size_t i = 0; i < actual_count - 1; i++) { + for (size_t i = 0; i < new_count - 1; i++) { NEMMosaic *a = &mosaics[i]; - for (size_t j = i + 1; j < actual_count; j++) { + for (size_t j = i + 1; j < new_count; j++) { NEMMosaic *b = &mosaics[j]; if (nem_mosaicCompare(a, b) > 0) { + NEMMosaic temp; memcpy(&temp, a, sizeof(NEMMosaic)); memcpy(a, b, sizeof(NEMMosaic)); memcpy(b, &temp, sizeof(NEMMosaic)); } } } - - return actual_count; } void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition, diff --git a/legacy/firmware/nem2.h b/legacy/firmware/nem2.h index 835ba0e37..05592756d 100644 --- a/legacy/firmware/nem2.h +++ b/legacy/firmware/nem2.h @@ -92,7 +92,7 @@ const NEMMosaicDefinition *nem_mosaicByName(const char *namespace, const char *mosaic, uint8_t network); -size_t nem_canonicalizeMosaics(NEMMosaic *mosaics, size_t mosaics_count); +void nem_canonicalizeMosaics(NEMTransfer *transfer); void nem_mosaicFormatAmount(const NEMMosaicDefinition *definition, uint64_t quantity, const bignum256 *multiplier, char *str_out, size_t size);