Skip to content

Commit

Permalink
Remove optional array
Browse files Browse the repository at this point in the history
  • Loading branch information
relatko committed Feb 26, 2024
1 parent 316e28c commit 60c439b
Show file tree
Hide file tree
Showing 277 changed files with 1,222 additions and 3,535 deletions.
15 changes: 7 additions & 8 deletions src/parser_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ extern "C" {
#include <stdint.h>
#include <stddef.h>

#define CHECK_PARSER_ERR(__CALL) \
{ \
parser_error_t __err = __CALL; \
CHECK_APP_CANARY() \
if (__err != PARSER_OK) { \
ZEMU_TRACE(); \
return __err; \
} \
#define CHECK_PARSER_ERR(__CALL) \
{ \
parser_error_t __err = __CALL; \
CHECK_APP_CANARY() \
if (__err != PARSER_OK) { \
return __err; \
} \
}

#define CTX_CHECK_AND_ADVANCE(CTX, SIZE) \
Expand Down
82 changes: 1 addition & 81 deletions src/parser_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,50 +293,6 @@ parser_error_t json_matchOptionalKeyValue(const parsed_json_t *parsedJson,
return PARSER_UNEXPECTED_VALUE;
}

// valueTokenIdx is JSON_MATCH_VALUE_IDX_NONE if the optional is null
parser_error_t json_matchOptionalArray(const parsed_json_t *parsedJson,
uint16_t tokenIdx,
uint16_t *valueTokenIdx) {
CHECK_PARSER_ERR(json_validateToken(parsedJson, tokenIdx))

if (!(tokenIdx + 4 < parsedJson->numberOfTokens)) {
// we need this token and 4 more
return PARSER_JSON_INVALID_TOKEN_IDX;
}

if (parsedJson->tokens[tokenIdx].type != JSMN_OBJECT) {
return PARSER_UNEXPECTED_TYPE;
}

if (parsedJson->tokens[tokenIdx].size != 2) {
return PARSER_UNEXPECTED_NUMBER_ITEMS;
}

// Type key/value
CHECK_PARSER_ERR(json_matchToken(parsedJson, tokenIdx + 1, (char *) "type"))
CHECK_PARSER_ERR(json_matchToken(parsedJson, tokenIdx + 2, (char *) "Optional"))
CHECK_PARSER_ERR(json_matchToken(parsedJson, tokenIdx + 3, (char *) "value"))
if (parsedJson->tokens[tokenIdx + 4].type == JSMN_PRIMITIVE) { // optional null
CHECK_PARSER_ERR(json_matchNull(parsedJson, tokenIdx + 4))
*valueTokenIdx = JSON_MATCH_VALUE_IDX_NONE;
return PARSER_OK;
}
if (parsedJson->tokens[tokenIdx + 4].type == JSMN_OBJECT) { // optional not null
if (!(tokenIdx + 8 < parsedJson->numberOfTokens)) {
return PARSER_JSON_INVALID_TOKEN_IDX;
}
CHECK_PARSER_ERR(json_matchToken(parsedJson, tokenIdx + 5, (char *) "type"))
CHECK_PARSER_ERR(json_matchToken(parsedJson, tokenIdx + 6, (char *) "Array"))
CHECK_PARSER_ERR(json_matchToken(parsedJson, tokenIdx + 7, (char *) "value"))
if (parsedJson->tokens[tokenIdx + 8].type == JSMN_ARRAY) {
*valueTokenIdx = tokenIdx + 8;
return PARSER_OK;
}
}

return PARSER_UNEXPECTED_VALUE;
}

parser_error_t json_matchArbitraryKeyValue(const parsed_json_t *parsedJson,
uint16_t tokenIdx,
jsmntype_t *valueJsonType,
Expand Down Expand Up @@ -393,8 +349,7 @@ parser_error_t formatStrUInt8AsHex(const char *decStr, char *hexStr) {
return PARSER_OK;
}

parser_error_t _readScript(parser_context_t *c,
flow_script_hash_t *s) {
parser_error_t _readScript(parser_context_t *c, flow_script_hash_t *s) {
rlp_kind_e kind;
parser_context_t script;
uint32_t bytesConsumed;
Expand Down Expand Up @@ -637,41 +592,6 @@ parser_error_t _countArgumentItems(const flow_argument_list_t *v,
return PARSER_OK;
}

// if Optional is null, number_of_items is set to 1 as one screen is needed to display "None"
parser_error_t _countArgumentOptionalItems(const flow_argument_list_t *v,
uint8_t argumentIndex,
uint8_t min_number_of_items,
uint8_t max_number_of_items,
uint8_t *number_of_items) {
*number_of_items = 0;
parsed_json_t parsedJson = {false};

if (argumentIndex >= v->argCount) {
return PARSER_UNEXPECTED_FIELD;
}

const parser_context_t argCtx = v->argCtx[argumentIndex];
CHECK_PARSER_ERR(json_parse(&parsedJson, (char *) argCtx.buffer, argCtx.bufferLen));

uint16_t internalTokenElementIdx;
CHECK_PARSER_ERR(json_matchOptionalArray(&parsedJson, 0, &internalTokenElementIdx));
if (internalTokenElementIdx == JSON_MATCH_VALUE_IDX_NONE) {
*number_of_items = 1;
return PARSER_OK;
}

// Get number of items
uint16_t arrayTokenCount;
CHECK_PARSER_ERR(
array_get_element_count(&parsedJson, internalTokenElementIdx, &arrayTokenCount));
if (arrayTokenCount < min_number_of_items || arrayTokenCount > max_number_of_items) {
return PARSER_UNEXPECTED_NUMBER_ITEMS;
}

*number_of_items = arrayTokenCount;
return PARSER_OK;
}

void checkAddressUsedInTx() {
addressUsedInTx = 0;
uint16_t authCount = parser_tx_obj.authorizers.authorizer_count;
Expand Down
11 changes: 0 additions & 11 deletions src/parser_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,6 @@ parser_error_t _countArgumentItems(const flow_argument_list_t *v,
uint8_t max_number_of_items,
uint8_t *number_of_items);

// Same as _countArgumentItems, but the array is optional.
parser_error_t _countArgumentOptionalItems(const flow_argument_list_t *v,
uint8_t argumentIndex,
uint8_t min_number_of_items,
uint8_t max_number_of_items,
uint8_t *number_of_items);

parser_error_t json_validateToken(const parsed_json_t *parsedJson, uint16_t tokenIdx);

parser_error_t json_extractToken(char *outVal,
Expand All @@ -74,10 +67,6 @@ parser_error_t json_matchOptionalKeyValue(const parsed_json_t *parsedJson,
jsmntype_t jsonType,
uint16_t *valueTokenIdx);

parser_error_t json_matchOptionalArray(const parsed_json_t *parsedJson,
uint16_t tokenIdx,
uint16_t *valueTokenIdx);

parser_error_t json_matchArbitraryKeyValue(const parsed_json_t *parsedJson,
uint16_t tokenIdx,
jsmntype_t *valueJsonType,
Expand Down
131 changes: 21 additions & 110 deletions src/parser_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@

#define MAX_JSON_ARRAY_TOKEN_COUNT 64

parser_error_t parser_parse(parser_context_t *ctx,
const uint8_t *data,
size_t dataLen) {
parser_error_t parser_parse(parser_context_t *ctx, const uint8_t *data, size_t dataLen) {
CHECK_PARSER_ERR(parser_init(ctx, data, dataLen))
return _read(ctx, &parser_tx_obj);
}
Expand Down Expand Up @@ -282,71 +280,6 @@ parser_error_t parser_printArgumentArray(const flow_argument_list_t *v,
return PARSER_OK;
}

parser_error_t parser_printArgumentOptionalArray(const flow_argument_list_t *v,
uint8_t argIndex,
uint8_t arrayIndex,
const char *expectedType,
jsmntype_t jsonType,
char *outVal,
uint16_t outValLen,
uint8_t pageIdx,
uint8_t *pageCount) {
MEMZERO(outVal, outValLen);

if (argIndex >= v->argCount) {
return PARSER_UNEXPECTED_NUMBER_ITEMS;
}

parsed_json_t parsedJson = {false};
CHECK_PARSER_ERR(json_parse(&parsedJson,
(char *) v->argCtx[argIndex].buffer,
v->argCtx[argIndex].bufferLen));

// Estimate number of pages
uint16_t internalTokenElementIdx;
CHECK_PARSER_ERR(json_matchOptionalArray(&parsedJson, 0, &internalTokenElementIdx));
if (internalTokenElementIdx == JSON_MATCH_VALUE_IDX_NONE) {
if (outValLen < 5) {
ZEMU_TRACE();
return PARSER_UNEXPECTED_BUFFER_END;
}
*pageCount = 1;
strncpy_s(outVal, "None", 5);
} else {
uint16_t arrayTokenCount;
CHECK_PARSER_ERR(
array_get_element_count(&parsedJson, internalTokenElementIdx, &arrayTokenCount));
if (arrayTokenCount >= MAX_JSON_ARRAY_TOKEN_COUNT || arrayIndex >= arrayTokenCount) {
ZEMU_TRACE();
return PARSER_UNEXPECTED_NUMBER_ITEMS;
}

uint16_t arrayElementToken;
char bufferUI[ARGUMENT_BUFFER_SIZE_STRING];
CHECK_PARSER_ERR(array_get_nth_element(&parsedJson,
internalTokenElementIdx,
arrayIndex,
&arrayElementToken))
uint16_t internalTokenElemIdx;
CHECK_PARSER_ERR(json_matchKeyValue(&parsedJson,
arrayElementToken,
expectedType,
jsonType,
&internalTokenElemIdx))
CHECK_PARSER_ERR(
json_extractToken(bufferUI, sizeof(bufferUI), &parsedJson, internalTokenElemIdx))
pageString(outVal, outValLen, bufferUI, pageIdx, pageCount);

// Check requested page is in range
if (pageIdx > *pageCount) {
ZEMU_TRACE();
return PARSER_DISPLAY_PAGE_OUT_OF_RANGE;
}
}

return PARSER_OK;
}

#define FLAG_IS_NONE 0x1000
#define FLAG_IS_OPTIONAL_NOT_NONE 0x2000
#define FLAG_IS_ARRAY 0x4000
Expand Down Expand Up @@ -748,11 +681,11 @@ parser_error_t parser_getItem_internal(int8_t *displayIdx,
SCREEN(true) {
snprintf(outKey, outKeyLen, "Script hash");
pageStringHex(outVal,
outValLen,
(const char *) parser_tx_obj.hash.digest,
sizeof(parser_tx_obj.hash.digest),
pageIdx,
pageCount);
outValLen,
(const char *) parser_tx_obj.hash.digest,
sizeof(parser_tx_obj.hash.digest),
pageIdx,
pageCount);
return PARSER_OK;
}
SCREEN(true) {
Expand Down Expand Up @@ -828,28 +761,6 @@ parser_error_t parser_getItem_internal(int8_t *displayIdx,
}
}
break;
case ARGUMENT_TYPE_OPTIONALARRAY:
zemu_log("Argument optional array\n");
CHECK_PARSER_ERR(_countArgumentOptionalItems(&parser_tx_obj.arguments,
marg->argumentIndex,
marg->arrayMinElements,
marg->arrayMaxElements,
&screenCount));
for (size_t j = 0; j < screenCount; j++) {
SCREEN(true) {
snprintf(outKey, outKeyLen, "%s %d", marg->displayKey, (int) (j + 1));
return parser_printArgumentOptionalArray(&parser_tx_obj.arguments,
marg->argumentIndex,
j,
marg->jsonExpectedType,
marg->jsonExpectedKind,
outVal,
outValLen,
pageIdx,
pageCount);
}
}
break;
default:
return PARSER_METADATA_ERROR;
}
Expand All @@ -858,18 +769,18 @@ parser_error_t parser_getItem_internal(int8_t *displayIdx,
SCREEN(true) {
snprintf(outKey, outKeyLen, "Script arguments");
snprintf(outVal,
outValLen,
"Number of arguments: %d",
parser_tx_obj.arguments.argCount);
outValLen,
"Number of arguments: %d",
parser_tx_obj.arguments.argCount);
return PARSER_OK;
}
for (size_t i = 0; i < parser_tx_obj.arguments.argCount; i++) {
uint16_t flags = 0;
uint16_t jsonToken = 0;
CHECK_PARSER_ERR(parser_printArbitraryPrepareToDisplay(&parser_tx_obj.arguments,
i,
&flags,
&jsonToken));
i,
&flags,
&jsonToken));
SCREEN(true) {
return parser_printArbitraryArgumentFirstScreen(&parser_tx_obj.arguments,
i,
Expand All @@ -886,15 +797,15 @@ parser_error_t parser_getItem_internal(int8_t *displayIdx,
for (size_t j = 0; j < (flags & FLAGS_FURTHER_SCREENS); j++) {
SCREEN(true) {
return parser_printArbitraryArrayElements(&parser_tx_obj.arguments,
i,
j,
jsonToken,
outKey,
outKeyLen,
outVal,
outValLen,
pageIdx,
pageCount);
i,
j,
jsonToken,
outKey,
outKeyLen,
outVal,
outValLen,
pageIdx,
pageCount);
}
}
}
Expand Down
14 changes: 1 addition & 13 deletions src/parser_tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ extern "C" {
const char *parser_getErrorDescription(parser_error_t err);

//// parses a tx buffer
parser_error_t parser_parse(parser_context_t *ctx,
const uint8_t *data,
size_t dataLen);
parser_error_t parser_parse(parser_context_t *ctx, const uint8_t *data, size_t dataLen);

//// verifies tx fields
parser_error_t parser_validate(const parser_context_t *ctx);
Expand Down Expand Up @@ -77,16 +75,6 @@ parser_error_t parser_printArgumentArray(const flow_argument_list_t *v,
uint8_t pageIdx,
uint8_t *pageCount);

parser_error_t parser_printArgumentOptionalArray(const flow_argument_list_t *v,
uint8_t argIndex,
uint8_t arrayIndex,
const char *expectedType,
jsmntype_t jsonType,
char *outVal,
uint16_t outValLen,
uint8_t pageIdx,
uint8_t *pageCount);

parser_error_t parser_printArbitraryPrepareToDisplay(const flow_argument_list_t *v,
uint8_t argIndex,
uint16_t *flags,
Expand Down
12 changes: 8 additions & 4 deletions src/tx_metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,14 @@ static parser_error_t parseTxMetadataInternal(const uint8_t scriptHash[METADATA_
_Static_assert(sizeof(parsedTxMetadata->arguments) >= PARSER_MAX_ARGCOUNT,
"Too few arguments in parsed_tx_metadata_t.");
for (int i = 0; i < parsedTxMetadata->argCount; i++) {
READ_CHAR(&parsedTxMetadata->arguments[i].argumentType);
argument_type_e argumentType = parsedTxMetadata->arguments[i].argumentType;
if (argumentType == ARGUMENT_TYPE_ARRAY ||
argumentType == ARGUMENT_TYPE_OPTIONALARRAY) {
uint8_t argumentType = 0;
READ_CHAR(&argumentType);
if (argumentType != ARGUMENT_TYPE_NORMAL && argumentType != ARGUMENT_TYPE_OPTIONAL &&
argumentType != ARGUMENT_TYPE_ARRAY) {
return PARSER_METADATA_ERROR;
}
parsedTxMetadata->arguments[i].argumentType = argumentType;
if (argumentType == ARGUMENT_TYPE_ARRAY) {
READ_CHAR(&parsedTxMetadata->arguments[i].arrayMinElements);
READ_CHAR(&parsedTxMetadata->arguments[i].arrayMaxElements);
uint8_t min = parsedTxMetadata->arguments[i].arrayMinElements;
Expand Down
1 change: 0 additions & 1 deletion src/tx_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ typedef enum {
ARGUMENT_TYPE_NORMAL = 1,
ARGUMENT_TYPE_OPTIONAL = 2,
ARGUMENT_TYPE_ARRAY = 3,
ARGUMENT_TYPE_OPTIONALARRAY = 4
} argument_type_e;

#define PARSER_MAX_ARGCOUNT 9
Expand Down
Loading

0 comments on commit 60c439b

Please sign in to comment.