librlp

C library for the Recursive Length Prefix (RLP) serialization format
git clone git://git.defalsify.org/librlp.git
Log | Files | Refs | LICENSE

commit 9256d605e0a852bea498a33ac4bcec5db1c5e043
parent 321d42e146f8efb3369f62ec4b6884668bc54d70
Author: nolash <dev@holbrook.no>
Date:   Sat, 10 Apr 2021 14:20:54 +0200

Correct list length for nesting

Diffstat:
Msrc/rlp.c | 44++++++++++++++------------------------------
Msrc/rlp.h | 11+++++++----
Mtests/check_bits | 0
Mtests/check_rlp | 0
Mtests/check_rlp.c | 62+++++++++++++++++++++++++++++++++++++++++++-------------------
5 files changed, 64 insertions(+), 53 deletions(-)

diff --git a/src/rlp.c b/src/rlp.c @@ -23,10 +23,6 @@ int rlp_add(rlp_encoder_t *encoder, int len, char *data) { int lenlen; size_t r; - if (list_register(encoder) < 0) { - return -1; - } - r = (size_t)encoder->ptr; if (len == 0) { @@ -61,36 +57,24 @@ int rlp_add(rlp_encoder_t *encoder, int len, char *data) { return (int)(r - (size_t)encoder->ptr); } -int rlp_descend(rlp_encoder_t *encoder, uint32_t num_items) { +int rlp_descend(rlp_encoder_t *encoder) { encoder->depth++; -// memcpy(&encoder->list_buf[encoder->depth], &num_items, sizeof(uint32_t)); - encoder->list_buf[encoder->depth] = num_items + 1; - if (num_items < 56) { - *(encoder->ptr) = 0xc0 + num_items; - encoder->ptr++; - } + encoder->list_ptr[encoder->depth] = encoder->ptr; return encoder->depth + 1; } -static int list_register(rlp_encoder_t *encoder) { - if (encoder->depth == -1) { - return 0; - } - encoder->list_buf[encoder->depth]--; - if (encoder->list_buf[encoder->depth] < 0) { - return -1; - } else if (encoder->list_buf[encoder->depth] == 0) { - encoder->depth--; - } - return encoder->depth + 1; -} +int rlp_ascend(rlp_encoder_t *encoder) { + size_t l; + char *ptr; -int rlp_finish(rlp_encoder_t *encoder) { - while (encoder->depth > -1) { - if (encoder->list_buf[encoder->depth] > 1) { - return -1; - } - list_register(encoder); + ptr = encoder->list_ptr[encoder->depth]; + l = encoder->ptr - ptr; + if (l < 56) { + memcpy(ptr+1, ptr, l); + *(ptr) = 0xc0 + l; + encoder->ptr++; } - return 0; + encoder->depth--; + + return encoder->depth + 1; } diff --git a/src/rlp.h b/src/rlp.h @@ -3,21 +3,24 @@ #include <stdint.h> +#ifndef RLP_MAX_LIST_DEPTH #define RLP_MAX_LIST_DEPTH 1024 +#endif typedef struct rlp_encoder { int depth; - uint32_t list_buf[RLP_MAX_LIST_DEPTH]; + char *list_ptr[RLP_MAX_LIST_DEPTH]; char *buf; char *ptr; - + size_t len; } rlp_encoder_t; int rlp_init(rlp_encoder_t *encoder, int buffer_capacity); void rlp_free(rlp_encoder_t *encoder); -int rlp_descend(rlp_encoder_t *encoder, uint32_t num_items); -static int list_register(rlp_encoder_t *encoder); +int rlp_descend(rlp_encoder_t *encoder); +//static int list_register(rlp_encoder_t *encoder); +int rlp_ascend(rlp_encoder_t *encoder); int rlp_add(rlp_encoder_t *encoder, int len, char *data); int rlp_finish(rlp_encoder_t *encoder); diff --git a/tests/check_bits b/tests/check_bits Binary files differ. diff --git a/tests/check_rlp b/tests/check_rlp Binary files differ. diff --git a/tests/check_rlp.c b/tests/check_rlp.c @@ -108,22 +108,23 @@ END_TEST START_TEST(rlp_encode_list_descend_state_test) { - //char one = 42; - //char two = 13; int r; + char *ptr_chk; rlp_encoder_t encoder; rlp_init(&encoder, 1024); - r = rlp_descend(&encoder, 2); + r = rlp_descend(&encoder); + ck_assert_ptr_eq(encoder.ptr, encoder.list_ptr[encoder.depth]); + ptr_chk = encoder.ptr; ck_assert_int_eq(1, r); ck_assert_int_eq(encoder.depth, 0); - ck_assert_int_eq(encoder.list_buf[0], 3); - r = rlp_descend(&encoder, 4); + r = rlp_descend(&encoder); + ck_assert_ptr_eq(encoder.ptr, encoder.list_ptr[encoder.depth]); + ck_assert_ptr_eq(ptr_chk, encoder.list_ptr[encoder.depth-1]); ck_assert_int_eq(2, r); ck_assert_int_eq(encoder.depth, 1); - ck_assert_int_eq(encoder.list_buf[1], 5); rlp_free(&encoder); } @@ -138,22 +139,22 @@ START_TEST(rlp_encode_list_roundtrip_state_test) { rlp_encoder_t encoder; rlp_init(&encoder, 1024); - r = rlp_descend(&encoder, 2); + r = rlp_descend(&encoder); + ck_assert_int_eq(r, 1); rlp_add(&encoder, 1, &one); rlp_add(&encoder, 1, &two); ck_assert_int_eq(encoder.depth, 0); - ck_assert_int_eq(encoder.list_buf[0], 1); - r = rlp_finish(&encoder); + r = rlp_ascend(&encoder); ck_assert_int_eq(r, 0); ck_assert_int_eq(encoder.depth, -1); - ck_assert_int_eq(encoder.list_buf[0], 0); rlp_free(&encoder); } END_TEST + START_TEST(rlp_encode_list_single_depth_test) { char one = 42; char two = 13; @@ -163,9 +164,10 @@ START_TEST(rlp_encode_list_single_depth_test) { rlp_encoder_t encoder; rlp_init(&encoder, 1024); - r = rlp_descend(&encoder, 2); + r = rlp_descend(&encoder); rlp_add(&encoder, 1, &one); rlp_add(&encoder, 1, &two); + r = rlp_ascend(&encoder); ck_assert_mem_eq(encoder.buf, target, 3); rlp_free(&encoder); @@ -173,29 +175,50 @@ START_TEST(rlp_encode_list_single_depth_test) { END_TEST -START_TEST(rlp_encode_list_two_depth_test) { +START_TEST(rlp_encode_list_adjacent_test) { char one[2] = {42, 13}; char two[3] = {0x66, 0x6f, 0x6f}; - char target[8] = {0xc2, 42, 13, 0xc1, 0x83, 0x66, 0x6f, 0x6f}; + char target[8] = {0xc2, 42, 13, 0xc4, 0x83, 0x66, 0x6f, 0x6f}; int r; rlp_encoder_t encoder; rlp_init(&encoder, 1024); - r = rlp_descend(&encoder, 2); + r = rlp_descend(&encoder); rlp_add(&encoder, 1, &one[0]); rlp_add(&encoder, 1, &one[1]); - r = rlp_descend(&encoder, 1); + r = rlp_ascend(&encoder); + r = rlp_descend(&encoder); rlp_add(&encoder, 3, two); + r = rlp_ascend(&encoder); ck_assert_mem_eq(encoder.buf, target, 8); - r = rlp_finish(&encoder); - ck_assert_int_eq(r, 0); - rlp_free(&encoder); } END_TEST + +START_TEST(rlp_encode_list_nested_test) { + char one[2] = {42, 13}; + char two[3] = {0x66, 0x6f, 0x6f}; + char target[8] = {0xc7, 42, 13, 0xc4, 0x83, 0x66, 0x6f, 0x6f}; + int r; + + rlp_encoder_t encoder; + rlp_init(&encoder, 1024); + + r = rlp_descend(&encoder); + rlp_add(&encoder, 1, &one[0]); + rlp_add(&encoder, 1, &one[1]); + r = rlp_descend(&encoder); + rlp_add(&encoder, 3, two); + r = rlp_ascend(&encoder); + r = rlp_ascend(&encoder); + ck_assert_mem_eq(encoder.buf, target, 8); + + rlp_free(&encoder); +} +END_TEST Suite *rlp_suite(void) { Suite *s; TCase *tci; @@ -221,7 +244,8 @@ Suite *rlp_suite(void) { tcase_add_test(tcl, rlp_encode_list_descend_state_test); tcase_add_test(tcl, rlp_encode_list_roundtrip_state_test); tcase_add_test(tcl, rlp_encode_list_single_depth_test); - tcase_add_test(tcl, rlp_encode_list_two_depth_test); + tcase_add_test(tcl, rlp_encode_list_adjacent_test); + tcase_add_test(tcl, rlp_encode_list_nested_test); suite_add_tcase(s, tcl); return s;