diff options
author | Dave Barach <dave@barachs.net> | 2023-01-12 16:07:26 -0500 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2023-01-12 23:03:22 +0000 |
commit | 809eb669c7a353cd06da58ccdf8578053b1233ca (patch) | |
tree | 4fcf4884aeedc116a40a622a27d616fb9681134b | |
parent | dcca9e75a17aca6fd83586a4de66fed65ec5d11b (diff) |
vppinfra: fix longstanding corner case bug in serialize_get()
serialize_get() -> serialize_write_not_inline(...) was losing track of
the current buffer index when it managed to empty the overflow vector
but had to turn around and use it again.
Test-case added to test_serialize.c.
This issue dates from 2010.
Type: fix
Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: I024a03f7a50fd6df543ddbc7c45d85def4f1981d
-rw-r--r-- | src/vppinfra/serialize.c | 1 | ||||
-rw-r--r-- | src/vppinfra/test_serialize.c | 46 |
2 files changed, 47 insertions, 0 deletions
diff --git a/src/vppinfra/serialize.c b/src/vppinfra/serialize.c index f5c00649627..ceda617f872 100644 --- a/src/vppinfra/serialize.c +++ b/src/vppinfra/serialize.c @@ -741,6 +741,7 @@ serialize_write_not_inline (serialize_main_header_t * m, if (n_left_o > 0 || n_left_b < n_bytes_to_write) { u8 *r; + s->current_buffer_index = cur_bi; vec_add2 (s->overflow_buffer, r, n_bytes_to_write); return r; } diff --git a/src/vppinfra/test_serialize.c b/src/vppinfra/test_serialize.c index 5c931b76023..0dcff031364 100644 --- a/src/vppinfra/test_serialize.c +++ b/src/vppinfra/test_serialize.c @@ -136,6 +136,46 @@ typedef struct serialize_main_t unserialize_main; } test_serialize_main_t; +u8 *test_pattern; + +int +vl (void *p) +{ + return vec_len (p); +} + +void +test_serialize_not_inline_double_vector_expand (void) +{ + serialize_main_t _m, *m = &_m; + u8 *serialized = 0; + u64 *magic; + void *p; + int i; + + vec_validate (test_pattern, 1023); + + for (i = 0; i < vec_len (test_pattern); i++) + test_pattern[i] = i & 0xff; + + serialize_open_vector (m, serialized); + p = serialize_get (m, 61); + clib_memcpy_fast (p, test_pattern, 61); + serialize_integer (m, 0xDEADBEEFFEEDFACEULL, 8); + p = serialize_get (m, vec_len (test_pattern) - 62); + clib_memcpy_fast (p, test_pattern + 61, vec_len (test_pattern) - 62); + serialized = serialize_close_vector (m); + + magic = (u64 *) (serialized + 61); + + if (*magic != clib_net_to_host_u64 (0xDEADBEEFFEEDFACEULL)) + { + fformat (stderr, "BUG!\n"); + exit (1); + } + return; +} + int test_serialize_main (unformat_input_t * input) { @@ -168,6 +208,12 @@ test_serialize_main (unformat_input_t * input) ; else if (unformat (input, "verbose %=", &tm->verbose, 1)) ; + else if (unformat (input, "double-expand")) + { + test_serialize_not_inline_double_vector_expand (); + clib_warning ("serialize_not_inline double vector expand OK"); + exit (0); + } else { error = clib_error_create ("unknown input `%U'\n", |