diff --git a/src_features/signMessageEIP712/field_hash.c b/src_features/signMessageEIP712/field_hash.c index 0ea583c..a265867 100644 --- a/src_features/signMessageEIP712/field_hash.c +++ b/src_features/signMessageEIP712/field_hash.c @@ -228,7 +228,7 @@ static bool field_hash_finalize(const void *const field_ptr, return false; } } - path_advance(); + path_advance(true); fh->state = FHS_IDLE; ui_712_finalize_field(); return true; diff --git a/src_features/signMessageEIP712/path.c b/src_features/signMessageEIP712/path.c index 8a5d05d..4381280 100644 --- a/src_features/signMessageEIP712/path.c +++ b/src_features/signMessageEIP712/path.c @@ -285,11 +285,14 @@ static bool array_depth_list_pop(void) { * Updates the path so that it doesn't point to a struct-type field, but rather * only to actual fields. * + * @param[in] skip_if_array skip if path is already pointing at an array + * @param[in] stop_at_array stop at the first downstream array * @return whether the path update worked or not */ -static bool path_update(void) { +static bool path_update(bool skip_if_array, bool stop_at_array) { uint8_t fields_count; const void *struct_ptr; + const void *starting_field_ptr; const void *field_ptr; const char *typename; uint8_t typename_len; @@ -298,10 +301,17 @@ static bool path_update(void) { if (path_struct == NULL) { return false; } - if ((field_ptr = get_field(NULL)) == NULL) { + if ((starting_field_ptr = get_field(NULL)) == NULL) { return false; } + field_ptr = starting_field_ptr; while (struct_field_type(field_ptr) == TYPE_CUSTOM) { + if (((field_ptr == starting_field_ptr) && skip_if_array) || + ((field_ptr != starting_field_ptr) && stop_at_array)) { + if (struct_field_is_array(field_ptr)) { + break; + } + } typename = get_struct_field_typename(field_ptr, &typename_len); if ((struct_ptr = get_structn(typename, typename_len)) == NULL) { return false; @@ -381,7 +391,7 @@ bool path_set_root(const char *const struct_name, uint8_t name_length) { struct_state = DEFINED; // because the first field could be a struct type - path_update(); + path_update(true, true); return true; } @@ -449,6 +459,9 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) { } array_size = *data; + if (!path_update(false, array_size > 0)) { + return false; + } array_depth_count_bak = path_struct->array_depth_count; for (pidx = 0; pidx < path_struct->depth_count; ++pidx) { if ((field_ptr = get_nth_field(NULL, pidx + 1)) == NULL) { @@ -492,7 +505,7 @@ bool path_new_array_depth(const uint8_t *const data, uint8_t length) { } if (array_size == 0) { do { - path_advance(); + path_advance(false); } while (path_struct->array_depth_count != array_depth_count_bak); } @@ -563,7 +576,7 @@ static bool path_advance_in_array(void) { * * @return whether the advancement was successful or not */ -bool path_advance(void) { +bool path_advance(bool array_check) { bool end_reached; do { @@ -573,8 +586,7 @@ bool path_advance(void) { end_reached = false; } } while (end_reached); - path_update(); - return true; + return path_update(array_check, array_check); } /** diff --git a/src_features/signMessageEIP712/path.h b/src_features/signMessageEIP712/path.h index d03b4c5..b7a31cb 100644 --- a/src_features/signMessageEIP712/path.h +++ b/src_features/signMessageEIP712/path.h @@ -27,7 +27,7 @@ typedef struct { bool path_set_root(const char *const struct_name, uint8_t length); const void *path_get_field(void); -bool path_advance(void); +bool path_advance(bool array_check); bool path_init(void); void path_deinit(void); bool path_new_array_depth(const uint8_t *const data, uint8_t length);