diff --git a/sys-utils/libcmt/src/abi.c b/sys-utils/libcmt/src/abi.c index a68f298..ac33963 100644 --- a/sys-utils/libcmt/src/abi.c +++ b/sys-utils/libcmt/src/abi.c @@ -39,7 +39,7 @@ int cmt_abi_put_funsel(cmt_buf_t *me, uint32_t funsel) { int cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]) { if (n > CMT_WORD_LENGTH) { - return EDOM; + return -EDOM; } for (size_t i = 0; i < n; ++i) { out[CMT_WORD_LENGTH - 1 - i] = data[i]; @@ -52,7 +52,7 @@ int cmt_abi_encode_uint_nr(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_L int cmt_abi_encode_uint_nn(size_t n, const uint8_t *data, uint8_t out[CMT_WORD_LENGTH]) { if (n > CMT_WORD_LENGTH) { - return EDOM; + return -EDOM; } for (size_t i = 0; i < CMT_WORD_LENGTH - n; ++i) { out[i] = 0; @@ -73,7 +73,7 @@ int cmt_abi_encode_uint(size_t n, const void *data, uint8_t out[CMT_WORD_LENGTH] int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out) { if (n > CMT_WORD_LENGTH) { - return EDOM; + return -EDOM; } for (size_t i = 0; i < CMT_WORD_LENGTH - n; ++i) { if (data[i]) { @@ -88,7 +88,7 @@ int cmt_abi_decode_uint_nr(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_ int cmt_abi_decode_uint_nn(const uint8_t data[CMT_WORD_LENGTH], size_t n, uint8_t *out) { if (n > CMT_WORD_LENGTH) { - return EDOM; + return -EDOM; } for (size_t i = 0; i < CMT_WORD_LENGTH - n; ++i) { if (data[i]) { diff --git a/sys-utils/libcmt/src/io-mock.c b/sys-utils/libcmt/src/io-mock.c index 79a1dd7..e40b243 100644 --- a/sys-utils/libcmt/src/io-mock.c +++ b/sys-utils/libcmt/src/io-mock.c @@ -16,7 +16,6 @@ #include "io.h" #include "util.h" -#include #include #include #include @@ -25,9 +24,6 @@ /** track the number of open "devices". Mimic the kernel driver behavior by limiting it to 1 */ static int open_count = 0; -static int read_whole_file(const char *name, size_t max, void *data, size_t *length); -static int write_whole_file(const char *name, size_t length, const void *data); - int cmt_io_init(cmt_io_driver_t *_me) { if (!_me) { return -EINVAL; @@ -116,7 +112,7 @@ static int load_next_input(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { } size_t file_length = 0; - int rc = read_whole_file(filepath, cmt_buf_length(me->rx), me->rx->begin, &file_length); + int rc = cmt_util_read_whole_file(filepath, cmt_buf_length(me->rx), me->rx->begin, &file_length); if (rc) { if (cmt_util_debug_enabled()) { (void) fprintf(stderr, "failed to load \"%s\". %s\n", filepath, strerror(-rc)); @@ -130,8 +126,6 @@ static int load_next_input(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { } return -EINVAL; } - - assert(file_length <= INT32_MAX); rr->reason = me->input_type; rr->data = file_length; @@ -150,7 +144,7 @@ static int store_output(cmt_io_driver_mock_t *me, const char *filepath, struct c return -ENOBUFS; } - int rc = write_whole_file(filepath, rr->data, me->tx->begin); + int rc = cmt_util_write_whole_file(filepath, rr->data, me->tx->begin); if (rc) { (void) fprintf(stderr, "failed to store \"%s\". %s\n", filepath, strerror(-rc)); return rc; @@ -205,7 +199,7 @@ static int mock_rx_rejected(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { } (void) fprintf(stderr, "%s:%d no revert for the mock implementation\n", __FILE__, __LINE__); if (load_next_input(me, rr)) { - return -1; + return -ENOSYS; } return 0; } @@ -255,9 +249,6 @@ static int mock_tx_gio(cmt_io_driver_mock_t *me, struct cmt_io_yield *rr) { /* These behaviours are defined by the cartesi-machine emulator */ static int cmt_io_yield_inner(cmt_io_driver_t *_me, struct cmt_io_yield *rr) { - if (!_me) { - return -EINVAL; - } cmt_io_driver_mock_t *me = &_me->mock; if (rr->cmd == HTIF_YIELD_CMD_MANUAL) { @@ -326,38 +317,3 @@ int cmt_io_yield(cmt_io_driver_t *_me, struct cmt_io_yield *rr) { } return rc; } - -static int read_whole_file(const char *name, size_t max, void *data, size_t *length) { - int rc = 0; - - FILE *file = fopen(name, "rb"); - if (!file) { - return -errno; - } - - *length = fread(data, 1, max, file); - if (!feof(file)) { - rc = -ENOBUFS; - } - if (fclose(file) != 0) { - rc = -errno; - } - return rc; -} - -static int write_whole_file(const char *name, size_t length, const void *data) { - int rc = 0; - - FILE *file = fopen(name, "wb"); - if (!file) { - return -errno; - } - - if (fwrite(data, 1, length, file) != length) { - rc = -EIO; - } - if (fclose(file) != 0) { - rc = -errno; - } - return rc; -} diff --git a/sys-utils/libcmt/src/merkle.c b/sys-utils/libcmt/src/merkle.c index 261cc81..e58007d 100644 --- a/sys-utils/libcmt/src/merkle.c +++ b/sys-utils/libcmt/src/merkle.c @@ -14,6 +14,7 @@ * limitations under the License. */ #include "merkle.h" +#include "util.h" #include #include @@ -128,35 +129,22 @@ void cmt_merkle_fini(cmt_merkle_t *me) { } int cmt_merkle_load(cmt_merkle_t *me, const char *filepath) { - FILE *fin = fopen(filepath, "rb"); - if (!fin) { - return -errno; + if (!me) { + return -EINVAL; } - size_t read = fread(me, 1, sizeof(*me), fin); - int rc = 0; - if (read < sizeof(*me)) { - rc = -ENOBUFS; - } - if (fclose(fin) != 0 && rc == 0) { - return -errno; + size_t length = 0; + int rc = cmt_util_read_whole_file(filepath, sizeof *me, me, &length); + if (length != sizeof *me) { + return -EINVAL; } return rc; } int cmt_merkle_save(cmt_merkle_t *me, const char *filepath) { - FILE *fout = fopen(filepath, "wb"); - if (!fout) { - return -errno; - } - size_t written = fwrite(me, 1, sizeof(*me), fout); - int rc = 0; - if (written < sizeof(*me)) { - rc = -EIO; + if (!me) { + return -EINVAL; } - if (fclose(fout) != 0 && rc == 0) { - return -errno; - } - return rc; + return cmt_util_write_whole_file(filepath, sizeof *me, me); } uint64_t cmt_merkle_get_leaf_count(cmt_merkle_t *me) { diff --git a/sys-utils/libcmt/src/util.c b/sys-utils/libcmt/src/util.c index 07e806a..95a3137 100644 --- a/sys-utils/libcmt/src/util.c +++ b/sys-utils/libcmt/src/util.c @@ -1,4 +1,6 @@ +#include #include +#include #include #include @@ -13,3 +15,38 @@ bool cmt_util_debug_enabled(void) { return enabled; } + +int cmt_util_read_whole_file(const char *name, size_t max, void *data, size_t *length) { + int rc = 0; + + FILE *file = fopen(name, "rb"); + if (!file) { + return -errno; + } + *length = fread(data, 1, max, file); + int eof = (fseek(file, 0, SEEK_END) == 0) && (*length == (size_t) ftell(file)); + if (!eof) { + rc = -EIO; + } + if (fclose(file) != 0) { + rc = -errno; + } + return rc; +} + +int cmt_util_write_whole_file(const char *name, size_t length, const void *data) { + int rc = 0; + + FILE *file = fopen(name, "wb"); + if (!file) { + return -errno; + } + + if (fwrite(data, 1, length, file) != length) { + rc = -EIO; + } + if (fclose(file) != 0) { + rc = -errno; + } + return rc; +} diff --git a/sys-utils/libcmt/src/util.h b/sys-utils/libcmt/src/util.h index 5bdd302..87d8c0e 100644 --- a/sys-utils/libcmt/src/util.h +++ b/sys-utils/libcmt/src/util.h @@ -6,4 +6,29 @@ */ bool cmt_util_debug_enabled(void); +/** Read whole file `name` contents into `data` and set `length`. + * @param name[in] - file path + * @param max[in] - size of `data` in bytes + * @param data[out] - file contents + * @param length[out] - actual size in `bytes` written to `data` + * + * @return + * | | | + * |-----|--------------------| + * | 0 |success | + * | < 0 |negative errno value| */ +int cmt_util_read_whole_file(const char *name, size_t max, void *data, size_t *length); + +/** Write the contents of `data` into file `name`. + * @param name[in] - file path + * @param length[in] - size of `data` in bytes + * @param data[out] - file contents + * + * @return + * | | | + * |-----|--------------------| + * | 0 |success | + * | < 0 |negative errno value| */ +int cmt_util_write_whole_file(const char *name, size_t length, const void *data); + #endif /* CMT_UTIL_H */ diff --git a/sys-utils/libcmt/tests/abi-multi.c b/sys-utils/libcmt/tests/abi-multi.c index 9f04d86..1c5fc88 100644 --- a/sys-utils/libcmt/tests/abi-multi.c +++ b/sys-utils/libcmt/tests/abi-multi.c @@ -19,14 +19,11 @@ #include #include -// EvmAdvance(address,uint256,uint256,uint256,bytes) -#define ADVANCE CMT_ABI_FUNSEL(0xd2, 0x0c, 0x60, 0xb4) +// Request(address,uint256,uint256,uint256,bytes) +#define REQUEST CMT_ABI_FUNSEL(0xf2, 0xbd, 0x3e, 0x8e) -// Voucher(address,bytes) -#define VOUCHER CMT_ABI_FUNSEL(0xef, 0x61, 0x5e, 0x2f) - -// Notice(bytes) -#define NOTICE CMT_ABI_FUNSEL(0xc2, 0x58, 0xd6, 0xe5) +// Reply(address,bytes) +#define REPLY CMT_ABI_FUNSEL(0x88, 0x6c, 0xbf, 0xaa) static int memeq(uint8_t *x, uint8_t *y, size_t n, const char *file, int line) { for (size_t i = 0; i < n; ++i) { @@ -40,22 +37,27 @@ static int memeq(uint8_t *x, uint8_t *y, size_t n, const char *file, int line) { return 0; } -static int advance(void) { - // cast calldata "EvmAdvance(address,uint256,uint256,uint256,bytes)" `cast address-zero` 1 2 3 0xdeadbeef | xxd -r - // -p | xxd -n advance -i - uint8_t evm_advance[] = {0xd2, 0x0c, 0x60, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static int test_request(void) { + // cast calldata "Request(address,uint256,uint256,uint256,bytes)" `cast address-zero` 1 2 3 0xdeadbeef | xxd -r -p | xxd -n request -i + unsigned char request[] = { + // clang-format off + 0xf2, 0xbd, 0x3e, 0x8e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + // clang-format on + }; uint8_t mem[256]; cmt_buf_t bb[1] = {{mem, mem + sizeof mem}}; cmt_buf_t wr[1] = {*bb}; @@ -64,7 +66,7 @@ static int advance(void) { uint8_t address[20] = {0}; uint8_t bytes[] = {0xde, 0xad, 0xbe, 0xef}; - cmt_abi_put_funsel(wr, ADVANCE); + cmt_abi_put_funsel(wr, REQUEST); uint8_t *frame = wr->begin; // dynamic frame begins after funsel cmt_abi_put_address(wr, address); cmt_abi_put_uint(wr, sizeof(int), &(int[]){1}); @@ -73,20 +75,24 @@ static int advance(void) { cmt_abi_put_bytes_s(wr, of); cmt_abi_put_bytes_d(wr, of, sizeof bytes, bytes, frame); - return sizeof evm_advance != (wr->begin - bb->begin) || - memeq(evm_advance, bb->begin, sizeof evm_advance, __FILE__, __LINE__); + return sizeof request != (wr->begin - bb->begin) || memeq(request, bb->begin, sizeof request, __FILE__, __LINE__); } -static int voucher(void) { - // cast calldata "Voucher(address,bytes)" `cast address-zero` 0xdeadbeef | xxd -r -p | xxd -n voucher -i - unsigned char evm_voucher[] = {0xef, 0x61, 0x5e, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xde, 0xad, 0xbe, 0xef, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static int test_reply(void) { + // cast calldata "Reply(address,bytes)" `cast address-zero` 0xdeadbeef | xxd -r -p | xxd -n reply -i + unsigned char reply[] = { + // clang-format off + 0x88, 0x6c, 0xbf, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + // clang-format on + }; uint8_t mem[256]; cmt_buf_t bb[1] = {{mem, mem + sizeof mem}}; @@ -96,43 +102,17 @@ static int voucher(void) { uint8_t address[20] = {0}; uint8_t bytes[] = {0xde, 0xad, 0xbe, 0xef}; - cmt_abi_put_funsel(wr, VOUCHER); + cmt_abi_put_funsel(wr, REPLY); uint8_t *frame = wr->begin; // dynamic frame begins after funsel cmt_abi_put_address(wr, address); cmt_abi_put_bytes_s(wr, of); cmt_abi_put_bytes_d(wr, of, sizeof bytes, bytes, frame); - return sizeof evm_voucher != (wr->begin - bb->begin) || - memeq(evm_voucher, bb->begin, sizeof evm_voucher, __FILE__, __LINE__); -} - -static int notice(void) { - unsigned char evm_notice[] = {0xc2, 0x58, 0xd6, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - uint8_t mem[256]; - cmt_buf_t bb[1] = {{mem, mem + sizeof mem}}; - cmt_buf_t wr[1] = {*bb}; - cmt_buf_t of[1]; - - uint8_t bytes[] = {0xde, 0xad, 0xbe, 0xef}; - - cmt_abi_put_funsel(wr, NOTICE); - uint8_t *frame = wr->begin; // dynamic frame begins after funsel - cmt_abi_put_bytes_s(wr, of); - cmt_abi_put_bytes_d(wr, of, sizeof bytes, bytes, frame); - - return sizeof evm_notice != (wr->begin - bb->begin) || - memeq(evm_notice, bb->begin, sizeof evm_notice, __FILE__, __LINE__); + return sizeof reply != (wr->begin - bb->begin) || memeq(reply, bb->begin, sizeof reply, __FILE__, __LINE__); } int main(void) { - assert(advance() == 0); - assert(voucher() == 0); - assert(notice() == 0); + assert(test_request() == 0); + assert(test_reply() == 0); return 0; } diff --git a/sys-utils/libcmt/tests/abi-single.c b/sys-utils/libcmt/tests/abi-single.c index e4da5c2..cf63e63 100644 --- a/sys-utils/libcmt/tests/abi-single.c +++ b/sys-utils/libcmt/tests/abi-single.c @@ -22,16 +22,12 @@ /** Declare a cmt_buf_t with stack backed memory. * @param [in] N - size in bytes * @note don't port */ -#define CMT_BUF_DECL(S, L) \ - cmt_buf_t S[1] = {{.begin = (uint8_t[L]){0}, \ - .end = (S)->begin + (L)}} // NOLINT(clang-analyzer-core.UndefinedBinaryOperatorResult) +#define CMT_BUF_DECL(S, L) cmt_buf_t S[1] = {{.begin = (uint8_t[L]){0}, .end = (S)->begin + (L)}} /** Declare a cmt_buf_t with parameters backed memory. * @param [in] L - size in bytes * @note don't port */ -#define CMT_BUF_DECL3(S, L, P) \ - cmt_buf_t S[1] = { \ - {.begin = (P), .end = (S)->begin + (L)}} // NOLINT(clang-analyzer-core.UndefinedBinaryOperatorResult) +#define CMT_BUF_DECL3(S, L, P) cmt_buf_t S[1] = {{.begin = (P), .end = (S)->begin + (L)}} // funsel(address) #define FUNSEL CMT_ABI_FUNSEL(0xe6, 0x36, 0xe3, 0x33) @@ -119,8 +115,8 @@ static void encode_edom(void) { // clang-format on }; uint8_t en[CMT_WORD_LENGTH]; - assert(cmt_abi_encode_uint_nr(sizeof(x), x, en) == EDOM); - assert(cmt_abi_encode_uint_nn(sizeof(x), x, en) == EDOM); + assert(cmt_abi_encode_uint_nr(sizeof(x), x, en) == -EDOM); + assert(cmt_abi_encode_uint_nn(sizeof(x), x, en) == -EDOM); } static void decode_u8(void) { @@ -193,16 +189,32 @@ static void decode_u256(void) { assert(memcmp(x, ex, sizeof(ex)) == 0); } -/* encoded value can't be represented in a uint64_t. */ -static void decode_edom(void) { - uint64_t x = 0; +static void decode_uint_edom(void) { uint8_t be[CMT_WORD_LENGTH] = { // clang-format off 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // clang-format on }; - assert(cmt_abi_decode_uint(be, sizeof(x), (void *) &x) == -EDOM); + { + uint8_t x[8] = {0}; + assert(cmt_abi_decode_uint_nr(be, sizeof(x), x) == -EDOM); + } + + { + uint8_t x[8] = {0}; + assert(cmt_abi_decode_uint_nn(be, sizeof(x), x) == -EDOM); + } + + { + uint8_t x[CMT_WORD_LENGTH + 1] = {0}; + assert(cmt_abi_decode_uint_nr(be, sizeof(x), x) == -EDOM); + } + + { + uint8_t x[CMT_WORD_LENGTH + 1] = {0}; + assert(cmt_abi_decode_uint_nn(be, sizeof(x), x) == -EDOM); + } } static void put_funsel(void) { @@ -215,6 +227,15 @@ static void put_funsel(void) { assert(memcmp(b->begin, data, 4) == 0); } +static void put_funsel_enobufs(void) { + uint8_t data[] = {0xcd, 0xcd, 0x77, 0xc0}; + uint32_t funsel = CMT_ABI_FUNSEL(data[0], data[1], data[2], data[3]); + CMT_BUF_DECL(b, 1); + cmt_buf_t it[1] = {*b}; + + assert(cmt_abi_put_funsel(it, funsel) == -ENOBUFS); +} + static void put_uint(void) { uint64_t x = UINT64_C(0x0123456789abcdef); uint8_t be[CMT_WORD_LENGTH] = { @@ -230,6 +251,24 @@ static void put_uint(void) { assert(memcmp(b->begin, be, sizeof(be)) == 0); } +static void put_uint_enobufs(void) { + uint64_t x = UINT64_C(0x0123456789abcdef); + CMT_BUF_DECL(b, 31); + cmt_buf_t it[1] = {*b}; + + assert(cmt_abi_put_uint(it, sizeof(x), &x) == -ENOBUFS); + assert(cmt_abi_put_uint_be(it, sizeof(x), &x) == -ENOBUFS); +} + +static void put_uint_edom(void) { + uint64_t x[CMT_WORD_LENGTH + 1] = {0}; + CMT_BUF_DECL(b, CMT_WORD_LENGTH); + cmt_buf_t it[1] = {*b}; + + assert(cmt_abi_put_uint(it, sizeof(x), &x) == -EDOM); + assert(cmt_abi_put_uint_be(it, sizeof(x), &x) == -EDOM); +} + static void put_bool(void) { uint8_t be[CMT_WORD_LENGTH] = { // clang-format off @@ -264,6 +303,14 @@ static void put_address(void) { assert(memcmp(b->begin, be, sizeof(be)) == 0); } +static void put_address_enobufs(void) { + uint8_t x[CMT_ADDRESS_LENGTH] = {0}; + CMT_BUF_DECL(b, CMT_WORD_LENGTH - 1); + cmt_buf_t it[1] = {*b}; + + assert(cmt_abi_put_address(it, x) == -ENOBUFS); +} + static void put_bytes(void) { uint64_t x = UINT64_C(0x0123456789abcdef); uint8_t be[] = { @@ -284,15 +331,38 @@ static void put_bytes(void) { assert(memcmp(b->begin, be, sizeof(be)) == 0); } +static void put_bytes_enobufs(void) { + uint64_t x = UINT64_C(0x0123456789abcdef); + cmt_buf_t of[1]; + + { + CMT_BUF_DECL(b, 3 * 32 - 1); + cmt_buf_t it[1] = {*b}; + assert(cmt_abi_put_bytes_s(it, of) == 0); + assert(cmt_abi_put_bytes_d(it, of, sizeof(x), &x, b->begin) == -ENOBUFS); + } +} + static void get_funsel(void) { CMT_BUF_DECL(b, 64); cmt_buf_t wr[1] = {*b}; cmt_buf_t rd[1] = {*b}; - uint32_t funsel = CMT_ABI_FUNSEL(1, 2, 3, 4); + uint32_t right = CMT_ABI_FUNSEL(1, 2, 3, 4); + uint32_t wrong = CMT_ABI_FUNSEL(1, 2, 3, 3); - assert(cmt_abi_put_funsel(wr, funsel) == 0); - assert(cmt_abi_peek_funsel(rd) == funsel); - assert(cmt_abi_check_funsel(rd, funsel) == 0); + assert(cmt_abi_put_funsel(wr, right) == 0); + assert(cmt_abi_peek_funsel(rd) == right); + assert(cmt_abi_check_funsel(rd, wrong) == -EBADMSG); // don't advance + assert(cmt_abi_check_funsel(rd, right) == 0); +} + +static void peek_funsel_error(void) { + CMT_BUF_DECL(b, 3); + uint32_t wrong = 0; // value doesn't matter + cmt_buf_t rd[1] = {*b}; + + assert(cmt_abi_peek_funsel(rd) == 0); + assert(cmt_abi_check_funsel(rd, wrong) == -ENOBUFS); // don't advance } static void get_uint(void) { @@ -311,6 +381,24 @@ static void get_uint(void) { assert(x == ex); } +static void get_uint_enobufs(void) { + uint64_t x = UINT64_C(0x0123456789abcdef); + CMT_BUF_DECL(b, 31); + cmt_buf_t it[1] = {*b}; + + assert(cmt_abi_get_uint(it, sizeof(x), &x) == -ENOBUFS); + assert(cmt_abi_get_uint_be(it, sizeof(x), &x) == -ENOBUFS); +} + +static void get_uint_edom(void) { + uint64_t x[CMT_WORD_LENGTH + 1] = {0}; + CMT_BUF_DECL(b, CMT_WORD_LENGTH); + cmt_buf_t it[1] = {*b}; + + assert(cmt_abi_get_uint(it, sizeof(x), &x) == -EDOM); + assert(cmt_abi_get_uint_be(it, sizeof(x), &x) == -EDOM); +} + static void get_uint_be(void) { uint64_t x = 0; uint64_t ex = UINT64_C(0x0123456789abcdef); @@ -343,6 +431,20 @@ static void get_bool(void) { assert(x == ex); } +static void get_bool_enobufs(void) { + bool x = false; + uint8_t be[CMT_WORD_LENGTH - 1] = { + // clang-format off + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // clang-format on + }; + CMT_BUF_DECL3(b, sizeof(be), be); + cmt_buf_t rd[1] = {*b}; + + assert(cmt_abi_get_bool(rd, &x) == -ENOBUFS); +} + static void get_address(void) { uint8_t x[CMT_ADDRESS_LENGTH]; uint8_t ex[CMT_ADDRESS_LENGTH] = { @@ -364,6 +466,19 @@ static void get_address(void) { assert(memcmp(x, ex, sizeof(ex)) == 0); } +static void get_address_enobufs(void) { + uint8_t x[CMT_ADDRESS_LENGTH]; + uint8_t be[CMT_WORD_LENGTH - 1] = { + // clang-format off + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, + 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, + // clang-format on + }; + CMT_BUF_DECL3(b, sizeof(be), be); + cmt_buf_t it[1] = {*b}; + assert(cmt_abi_get_address(it, x) == -ENOBUFS); +} + static void get_bytes(void) { uint64_t ex = UINT64_C(0x0123456789abcdef); uint8_t be[] = { @@ -385,6 +500,48 @@ static void get_bytes(void) { assert(memcmp(bytes->begin, &ex, sizeof(ex)) == 0); } +static void get_bytes_enobufs(void) { + uint8_t be[] = { + // clang-format off + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // clang-format on + }; + + { // when offset of dynamic reagion failed + CMT_BUF_DECL3(b, 1 * CMT_WORD_LENGTH - 1, be); + cmt_buf_t it[1] = {*b}; + cmt_buf_t of[1] = {0}; + cmt_buf_t bytes[1]; + + assert(cmt_abi_peek_bytes_d(it, of, bytes) == -ENOBUFS); + } + + { // dynamic reagion is too small to peek bytes + CMT_BUF_DECL3(b, 3 * CMT_WORD_LENGTH - 1, be); + cmt_buf_t it[1] = {*b}; + cmt_buf_t of[1] = {0}; + cmt_buf_t bytes[1]; + + assert(cmt_abi_get_bytes_s(it, of) == 0); + assert(cmt_abi_peek_bytes_d(it, of, bytes) == -ENOBUFS); + } + + { // dynamic reagion is too small to copy bytes + CMT_BUF_DECL3(b, 3 * CMT_WORD_LENGTH - 1, be); + cmt_buf_t it[1] = {*b}; + cmt_buf_t of[1] = {0}; + + size_t n; + void *data; + assert(cmt_abi_get_bytes_s(it, of) == 0); + assert(cmt_abi_get_bytes_d(it, of, &n, &data) == -ENOBUFS); + } +} + int main(void) { abi_funsel(); @@ -400,20 +557,31 @@ int main(void) { decode_u32(); decode_u64(); decode_u256(); - decode_edom(); + decode_uint_edom(); put_funsel(); + put_funsel_enobufs(); put_uint(); + put_uint_enobufs(); + put_uint_edom(); put_bool(); put_address(); + put_address_enobufs(); put_bytes(); + put_bytes_enobufs(); get_funsel(); + peek_funsel_error(); get_uint(); get_uint_be(); + get_uint_enobufs(); + get_uint_edom(); get_bool(); + get_bool_enobufs(); get_address(); + get_address_enobufs(); get_bytes(); + get_bytes_enobufs(); return 0; } diff --git a/sys-utils/libcmt/tests/buf.c b/sys-utils/libcmt/tests/buf.c index 3fc5669..2a43597 100644 --- a/sys-utils/libcmt/tests/buf.c +++ b/sys-utils/libcmt/tests/buf.c @@ -17,8 +17,17 @@ #include #include #include +#include -void split_in_bounds_must_succeed(void) { +static void passing_null(void) { + uint8_t _[8]; + + // just test if it crashes + cmt_buf_init(NULL, sizeof _, _); + assert(cmt_buf_length(NULL) == 0); +} + +static void split_in_bounds_must_succeed(void) { uint8_t _[8]; cmt_buf_t b; cmt_buf_init(&b, sizeof _, _); @@ -62,7 +71,7 @@ void split_in_bounds_must_succeed(void) { printf("test_buf_split_in_bounds_must_succeed passed\n"); } -void split_out_of_bounds_must_fail(void) { +static void split_out_of_bounds_must_fail(void) { uint8_t _[8]; cmt_buf_t b; cmt_buf_t lhs; @@ -74,8 +83,50 @@ void split_out_of_bounds_must_fail(void) { printf("test_buf_split_out_of_bounds_must_fail passed\n"); } +static void split_invalid_parameters(void) { + uint8_t _[8]; + cmt_buf_t b; + cmt_buf_t lhs; + cmt_buf_t rhs; + cmt_buf_init(&b, sizeof _, _); + + assert(cmt_buf_split(NULL, 8, &lhs, &rhs) == -EINVAL); + assert(cmt_buf_split(&b, 8, NULL, &rhs) == -EINVAL); + assert(cmt_buf_split(&b, 8, &lhs, NULL) == -EINVAL); +} + +static void split_by_comma_until_the_end(void) { + uint8_t _[] = "a,b,c"; + cmt_buf_t x; + cmt_buf_t xs; + + cmt_buf_init(&x, sizeof _ - 1, _); + cmt_buf_init(&xs, sizeof _ - 1, _); + assert(cmt_buf_split_by_comma(&x, &xs) == true); + assert(strncmp((char *) x.begin, "a", 1UL) == 0); + assert(cmt_buf_split_by_comma(&x, &xs) == true); + assert(strncmp((char *) x.begin, "b", 1UL) == 0); + assert(cmt_buf_split_by_comma(&x, &xs) == true); + assert(strncmp((char *) x.begin, "c", 1UL) == 0); + assert(cmt_buf_split_by_comma(&x, &xs) == false); +} + +static void xxd(void) { + uint8_t _[] = ""; + cmt_buf_xxd(_, _ + sizeof _, 0); + cmt_buf_xxd(_, _ + sizeof _, 1); + cmt_buf_xxd(_, _ + sizeof _, 3); + cmt_buf_xxd(NULL, _ + sizeof _, 1); + cmt_buf_xxd(_, NULL, 1); + cmt_buf_xxd(_, _, 1); +} + int main(void) { + passing_null(); split_in_bounds_must_succeed(); split_out_of_bounds_must_fail(); + split_invalid_parameters(); + split_by_comma_until_the_end(); + xxd(); return 0; } diff --git a/sys-utils/libcmt/tests/gio.c b/sys-utils/libcmt/tests/gio.c index abe1756..2bd4d8c 100644 --- a/sys-utils/libcmt/tests/gio.c +++ b/sys-utils/libcmt/tests/gio.c @@ -1,54 +1,19 @@ -#include -#include +#include "data.h" +#include "rollup.h" +#include "util.h" #include #include #include -#include "rollup.h" -#include "data.h" - -static int read_whole_file(const char *name, size_t max, void *data, size_t *length) { - int rc = 0; - - FILE *file = fopen(name, "rb"); - if (!file) { - return -errno; - } - - *length = fread(data, 1, max, file); - if (!feof(file)) { - rc = -ENOBUFS; - } - if (fclose(file) != 0) { - rc = -errno; - } - return rc; -} - -static int write_whole_file(const char *name, size_t length, const void *data) { - int rc = 0; - - FILE *file = fopen(name, "wb"); - if (!file) { - return -errno; - } - - if (fwrite(data, 1, length, file) != length) { - rc = -EIO; - } - if (fclose(file) != 0) { - rc = -errno; - } - return rc; -} +#include +#include -int main(void) -{ +int main(void) { uint8_t buffer[1024]; - size_t buffer_length; + size_t buffer_length = 0; cmt_rollup_t rollup; - assert(write_whole_file("build/gio.bin", sizeof valid_gio_reply_0, valid_gio_reply_0) == 0); - assert(setenv("CMT_INPUTS", "42:build/gio.bin", 1) == 0); + assert(cmt_util_write_whole_file("gio.bin", sizeof valid_gio_reply_0, valid_gio_reply_0) == 0); + assert(setenv("CMT_INPUTS", "42:gio.bin", 1) == 0); assert(cmt_rollup_init(&rollup) == 0); char request[] = "gio-request-0"; @@ -61,7 +26,7 @@ int main(void) }; assert(cmt_gio_request(&rollup, &req) == 0); - assert(read_whole_file("none.gio-0.bin", sizeof buffer, buffer, &buffer_length) == 0); + assert(cmt_util_read_whole_file("none.gio-0.bin", sizeof buffer, buffer, &buffer_length) == 0); assert(req.response_code == 42); assert(req.response_data_length == strlen(reply)); assert(memcmp(req.response_data, reply, req.response_data_length) == 0); diff --git a/sys-utils/libcmt/tests/io.c b/sys-utils/libcmt/tests/io.c new file mode 100644 index 0000000..12a3797 --- /dev/null +++ b/sys-utils/libcmt/tests/io.c @@ -0,0 +1,81 @@ +#include "io.h" +#include +#include +#include +#include +#include +#include + +void invalid_parameters(void) { + assert(cmt_io_init(NULL) == -EINVAL); + cmt_io_fini(NULL); + + cmt_buf_t tx = cmt_io_get_tx(NULL); + assert(tx.begin == NULL && tx.end == NULL); + + cmt_buf_t rx = cmt_io_get_rx(NULL); + assert(rx.begin == NULL && rx.end == NULL); + + setenv("CMT_INPUTS", "invalid", 1); + cmt_io_driver_t io[1]; + assert(cmt_io_init(io) == 0); + + { // invalid cmd + reason + cmt_io_yield_t rr[1] = {{ + .cmd = HTIF_YIELD_CMD_AUTOMATIC, + .reason = UINT16_MAX, + }}; + assert(cmt_io_yield(io, rr) == -EINVAL); + } + + { // invalid cmd + cmt_io_yield_t rr[1] = {{ + .cmd = 0xff, + .reason = 0, + }}; + assert(cmt_io_yield(io, rr) == -EINVAL); + } + + { // invalid args + cmt_io_yield_t rr[1] = {{ + .reason = HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED, + .cmd = HTIF_YIELD_CMD_MANUAL, + .data = 0, + }}; + assert(cmt_io_yield(io, NULL) == -EINVAL); + assert(cmt_io_yield(NULL, rr) == -EINVAL); + assert(cmt_io_yield(io, rr) == -ENODATA); + } + cmt_io_fini(io); +} + +void file_too_large(void) { + // create a 4MB file (any value larger than buffer works) + char valid[] = "/tmp/tmp.XXXXXX"; + assert(mkstemp(valid) > 0); + assert(truncate(valid, 4 << 20) == 0); + + { // setup input + char buf[64]; + (void) snprintf(buf, sizeof buf, "0:%s", valid); + setenv("CMT_DEBUG", "yes", 1); + setenv("CMT_INPUTS", buf, 1); + } + + cmt_io_driver_t io[1]; + cmt_io_yield_t rr[1] = {{ + .cmd = HTIF_YIELD_CMD_MANUAL, + .reason = HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED, + }}; + assert(cmt_io_init(io) == 0); + assert(cmt_io_yield(io, rr) == -ENODATA); + cmt_io_fini(NULL); + + (void) remove(valid); +} + +int main(void) { + invalid_parameters(); + file_too_large(); + return 0; +} diff --git a/sys-utils/libcmt/tests/merkle.c b/sys-utils/libcmt/tests/merkle.c index 47d5f67..882b282 100644 --- a/sys-utils/libcmt/tests/merkle.c +++ b/sys-utils/libcmt/tests/merkle.c @@ -17,8 +17,10 @@ #include #include +#include #include #include +#include #if 0 // NOLINT static void print(int m, uint8_t md[CMT_KECCAK_LENGTH]) { @@ -124,9 +126,14 @@ void test_cmt_merkle_push_back_data(void) { } void test_cmt_merkle_save_load(void) { - const char *test_file = "/tmp/cmt_merkle_test.bin"; cmt_merkle_t merkle1; cmt_merkle_t merkle2; + char valid[] = "/tmp/tmp.XXXXXX"; + char invalid[] = "/tmp/tmp.XXXXXX/invalid.bin"; + + // create a unique file and an invalid file from it. + (void) !mkstemp(valid); + memcpy(invalid, valid, strlen(valid)); // Initialize merkle1 and add some data cmt_merkle_init(&merkle1); @@ -138,24 +145,50 @@ void test_cmt_merkle_save_load(void) { assert(cmt_merkle_push_back_data(&merkle1, CMT_KECCAK_LENGTH, data) == 0); } - assert(cmt_merkle_save(&merkle1, test_file) == 0); - assert(cmt_merkle_load(&merkle2, test_file) == 0); - assert(memcmp(&merkle1, &merkle2, sizeof(cmt_merkle_t)) == 0); + // succeed with normal usage + assert(cmt_merkle_save(&merkle1, valid) == 0); + assert(cmt_merkle_load(&merkle2, valid) == 0); + assert(memcmp(&merkle1, &merkle2, sizeof(merkle1)) == 0); + + // fail to load smaller file + (void) !truncate(valid, sizeof(merkle1) - 1); + assert(cmt_merkle_load(&merkle2, valid) != 0); + (void) !remove(valid); + + // fail to save/load invalid filepath + assert(cmt_merkle_save(&merkle1, invalid) != 0); + assert(cmt_merkle_load(&merkle2, invalid) != 0); + + // invalid state + assert(cmt_merkle_save(NULL, valid) == -EINVAL); + assert(cmt_merkle_load(NULL, valid) == -EINVAL); - // Cleanup - if (remove(test_file) != 0) { - (void) fprintf(stderr, "Error deleting file %s: %s\n", test_file, strerror(errno)); - } printf("test_cmt_merkle_save_load passed\n"); } +void test_cmt_merkle_full(void) { + const uint64_t max_count = + (CMT_MERKLE_TREE_HEIGHT < 8 * sizeof(uint64_t)) ? (UINT64_C(1) << CMT_MERKLE_TREE_HEIGHT) : UINT64_MAX; + cmt_merkle_t merkle = { + .leaf_count = max_count - 1, + }; + assert(cmt_merkle_get_leaf_count(&merkle) == max_count - 1); + + uint8_t data[] = {0}; + assert(cmt_merkle_push_back_data(&merkle, sizeof(data), data) == 0); + assert(cmt_merkle_push_back_data(&merkle, sizeof(data), data) == -ENOBUFS); + assert(cmt_merkle_get_leaf_count(&merkle) == max_count); +} + int main(void) { + setenv("CMT_DEBUG", "yes", 1); test_merkle_init_and_reset(); test_merkle_push_back_and_get_root(); test_cmt_merkle_push_back_data_and_get_root(); test_cmt_merkle_push_back(); test_cmt_merkle_push_back_data(); test_cmt_merkle_save_load(); + test_cmt_merkle_full(); printf("All merkle tests passed!\n"); return 0; } diff --git a/sys-utils/libcmt/tests/rollup.c b/sys-utils/libcmt/tests/rollup.c index d2831c2..1071621 100644 --- a/sys-utils/libcmt/tests/rollup.c +++ b/sys-utils/libcmt/tests/rollup.c @@ -15,6 +15,7 @@ */ #include "rollup.h" #include "data.h" +#include "util.h" #include #include #include @@ -22,40 +23,6 @@ #include #include -static int read_whole_file(const char *name, size_t max, void *data, size_t *length) { - int rc = 0; - - FILE *file = fopen(name, "rb"); - if (!file) { - return -errno; - } - - *length = fread(data, 1, max, file); - if (!feof(file)) { - rc = -ENOBUFS; - } - if (fclose(file) != 0) { - rc = -errno; - } - return rc; -} - -static int write_whole_file(const char *name, size_t length, const void *data) { - int rc = 0; - - FILE *file = fopen(name, "wb"); - if (!file) { - return -errno; - } - - if (fwrite(data, 1, length, file) != length) { - rc = -EIO; - } - if (fclose(file) != 0) { - rc = -errno; - } - return rc; -} void test_rollup_init_and_fini(void) { cmt_rollup_t rollup; @@ -127,11 +94,11 @@ void test_rollup_parse_inputs(void) { uint8_t data[] = {0}; // synthesize inputs and feed them to io-mock via CMT_INPUTS env. - assert(write_whole_file("build/0.bin", sizeof valid_advance_0, valid_advance_0) == 0); - assert(write_whole_file("build/1.bin", sizeof valid_inspect_0, valid_inspect_0) == 0); - assert(write_whole_file("build/2.bin", sizeof data, data) == 0); - assert(truncate("build/2.bin", 3 << 20) == 0); - assert(setenv("CMT_INPUTS", "0:build/0.bin,1:build/1.bin,0:build/2.bin", 1) == 0); + assert(cmt_util_write_whole_file("0.bin", sizeof valid_advance_0, valid_advance_0) == 0); + assert(cmt_util_write_whole_file("1.bin", sizeof valid_inspect_0, valid_inspect_0) == 0); + assert(cmt_util_write_whole_file("2.bin", sizeof data, data) == 0); + assert(truncate("2.bin", 3 << 20) == 0); + assert(setenv("CMT_INPUTS", "0:0.bin,1:1.bin,0:2.bin", 1) == 0); assert(cmt_rollup_init(&rollup) == 0); assert(cmt_rollup_finish(&rollup, &finish) == 0); @@ -142,6 +109,9 @@ void test_rollup_parse_inputs(void) { assert(cmt_rollup_finish(&rollup, &finish) == -ENODATA); + finish.accept_previous_request = false; + assert(cmt_rollup_finish(&rollup, &finish) == -ENOSYS); + cmt_rollup_fini(&rollup); printf("test_rollup_parse_inputs passed!\n"); } @@ -172,37 +142,63 @@ void test_rollup_outputs_reports_and_exceptions(void) { assert(cmt_rollup_emit_voucher(&rollup, sizeof address, address, sizeof value, value, strlen(voucher_data), voucher_data, &index) == 0); assert(index == 0); - assert(read_whole_file("none.output-0.bin", sizeof buffer, buffer, &read_size) == 0); + assert(cmt_util_read_whole_file("none.output-0.bin", sizeof buffer, buffer, &read_size) == 0); assert(sizeof valid_voucher_0 == read_size); assert(memcmp(valid_voucher_0, buffer, sizeof valid_voucher_0) == 0); + // voucher (invalid) + assert(cmt_rollup_emit_voucher(NULL, sizeof address, address, sizeof value, value, strlen(voucher_data), + voucher_data, &index) == -EINVAL); + assert(cmt_rollup_emit_voucher(&rollup, sizeof address - 1, address, sizeof value, value, strlen(voucher_data), + NULL, &index) == -EINVAL); + assert(cmt_rollup_emit_voucher(&rollup, sizeof address - 1, address, sizeof value, value, strlen(voucher_data), + voucher_data, &index) == -EINVAL); + assert(cmt_rollup_emit_voucher(&rollup, sizeof address, address, sizeof value, value, UINT32_MAX, voucher_data, + &index) == -ENOBUFS); + // notice char notice_data[] = "notice-0"; assert(cmt_rollup_emit_notice(&rollup, strlen(notice_data), notice_data, &index) == 0); - assert(read_whole_file("none.output-1.bin", sizeof buffer, buffer, &read_size) == 0); + assert(cmt_util_read_whole_file("none.output-1.bin", sizeof buffer, buffer, &read_size) == 0); assert(sizeof valid_notice_0 == read_size); assert(memcmp(valid_notice_0, buffer, sizeof valid_notice_0) == 0); assert(index == 1); + // notice (invalid) + assert(cmt_rollup_emit_notice(NULL, strlen(notice_data), notice_data, &index) == -EINVAL); + assert(cmt_rollup_emit_notice(&rollup, strlen(notice_data), NULL, &index) == -EINVAL); + assert(cmt_rollup_emit_notice(&rollup, UINT32_MAX, notice_data, &index) == -ENOBUFS); + // report char report_data[] = "report-0"; assert(cmt_rollup_emit_report(&rollup, strlen(report_data), report_data) == 0); - assert(read_whole_file("none.report-0.bin", sizeof buffer, buffer, &read_size) == 0); + assert(cmt_util_read_whole_file("none.report-0.bin", sizeof buffer, buffer, &read_size) == 0); assert(sizeof valid_report_0 == read_size); assert(memcmp(valid_report_0, buffer, sizeof valid_report_0) == 0); + // report (invalid) + assert(cmt_rollup_emit_report(NULL, strlen(report_data), report_data) == -EINVAL); + assert(cmt_rollup_emit_report(&rollup, strlen(report_data), NULL) == -EINVAL); + assert(cmt_rollup_emit_report(&rollup, UINT32_MAX, report_data) == -ENOBUFS); + // exception char exception_data[] = "exception-0"; assert(cmt_rollup_emit_exception(&rollup, strlen(exception_data), exception_data) == 0); - assert(read_whole_file("none.exception-0.bin", sizeof buffer, buffer, &read_size) == 0); + assert(cmt_util_read_whole_file("none.exception-0.bin", sizeof buffer, buffer, &read_size) == 0); assert(sizeof valid_exception_0 == read_size); assert(memcmp(valid_exception_0, buffer, sizeof valid_exception_0) == 0); + // exception (invalid) + assert(cmt_rollup_emit_exception(NULL, strlen(exception_data), exception_data) == -EINVAL); + assert(cmt_rollup_emit_exception(&rollup, strlen(exception_data), NULL) == -EINVAL); + assert(cmt_rollup_emit_exception(&rollup, UINT32_MAX, exception_data) == -ENOBUFS); + cmt_rollup_fini(&rollup); printf("test_rollup_outputs_reports_and_exceptions passed!\n"); } int main(void) { + setenv("CMT_DEBUG", "yes", 1); test_rollup_init_and_fini(); test_rollup_parse_inputs(); test_rollup_outputs_reports_and_exceptions();