librlp

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

commit b9673535b29c4aeee9231cf37e2f6ad0b2cda342
parent 669b086a12b9388f5f8d1fee015b7d9a0a63168b
Author: nolash <dev@holbrook.no>
Date:   Sun, 11 Apr 2021 12:04:15 +0200

Add short list decode

Diffstat:
Msrc/decode.c | 23+++++++++++++++++++++--
Mtests/check_decoder.c | 39+++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/src/decode.c b/src/decode.c @@ -9,7 +9,18 @@ static int process_state_token(rlp_encoder_t *encoder) { token = *encoder->ptr; - if (token >= 0xb7) { + if (token >= 0xc0) { + len = token - 0xc0; + if (is_le()) { + to_endian(CONVERT_LITTLEENDIAN, sizeof(len), &len); + } + encoder->list_ptr[encoder->depth] = &len; + encoder->ptr++; + + r = encoder->depth; + encoder->depth++; + encoder->state = RLP_LIST; + } else if (token >= 0xb7) { lenlen = token - 0xb7; encoder->ptr++; len = 0; @@ -54,7 +65,15 @@ int rlp_next(rlp_encoder_t *encoder, int *zlen, char **zdest) { r = process_state_token(encoder); - *zlen = encoder->ptr - encoder->list_ptr[r]; + switch (encoder->state) { + case RLP_LIST: + *zlen = *((int*)encoder->list_ptr[r]); + break; + + case RLP_STRING: + *zlen = encoder->ptr - encoder->list_ptr[r]; + break; + } *zdest = encoder->list_ptr[r]; return 0; diff --git a/tests/check_decoder.c b/tests/check_decoder.c @@ -12,10 +12,13 @@ START_TEST(rlp_decode_single_test) { int r; int l; + char state = RLP_STRING; + rlp_encoder_t encoder; rlp_init(&encoder, 1, &s); r = rlp_next(&encoder, &l, &zbuf); + ck_assert_mem_eq(&encoder.state, &state, 1); ck_assert_int_eq(r, 0); ck_assert_int_eq(l, 1); ck_assert_mem_eq(zbuf, &s, l); @@ -34,10 +37,13 @@ START_TEST(rlp_decode_short_string_test) { char buf[1024]; char *zbuf = buf; + char state = RLP_STRING; + rlp_encoder_t encoder; rlp_init(&encoder, 5, s); r = rlp_next(&encoder, &l, &zbuf); + ck_assert_mem_eq(&encoder.state, &state, 1); ck_assert_int_eq(r, 0); ck_assert_int_eq(l, 3); ck_assert_mem_eq(zbuf, target, l); @@ -59,11 +65,14 @@ START_TEST(rlp_decode_long_string_test) { char buf[1024]; char *zbuf = buf; + char state = RLP_STRING; + rlp_encoder_t encoder; rlp_init(&encoder, 57, s); r = rlp_next(&encoder, &l, &zbuf); + ck_assert_mem_eq(&encoder.state, &state, 1); ck_assert_int_eq(l, 56); ck_assert_int_eq(r, 0); ck_assert_mem_eq(zbuf, s+2, l); @@ -73,17 +82,47 @@ START_TEST(rlp_decode_long_string_test) { } END_TEST + +START_TEST(rlp_decode_short_list_test) { + int l; + int r; + + char s = 0xc0; + char buf = 0; + char *zbuf = &buf; + + char state = RLP_LIST; + + rlp_encoder_t encoder; + + rlp_init(&encoder, 1, &s); + r = rlp_next(&encoder, &l, &zbuf); + ck_assert_mem_eq(&encoder.state, &state, 1); + ck_assert_int_eq(l, 0); + ck_assert_int_eq(r, 0); + + rlp_free(&encoder); +} +END_TEST + + Suite *rlp_decode_suite(void) { Suite *s; TCase *tcb; + TCase *tcl; s = suite_create("rlp_decode"); tcb = tcase_create("bytes"); + tcl = tcase_create("list"); + tcase_add_test(tcb, rlp_decode_single_test); tcase_add_test(tcb, rlp_decode_short_string_test); tcase_add_test(tcb, rlp_decode_long_string_test); suite_add_tcase(s, tcb); + tcase_add_test(tcl, rlp_decode_short_list_test); + suite_add_tcase(s, tcl); + return s; }