From d17cf888e5569a6ebffbe5697a22dbba7471d58d Mon Sep 17 00:00:00 2001
From: Lev Walkin <vlm@lionet.info>
Date: Sun, 1 Oct 2017 22:46:23 -0700
Subject: [PATCH] check and fix oer length encoding

---
 skeletons/oer_support.c                   |  7 +--
 tests/tests-skeletons/Makefile.am         |  1 +
 tests/tests-skeletons/check-OER-support.c | 57 +++++++++++++++++++++++
 3 files changed, 62 insertions(+), 3 deletions(-)
 create mode 100644 tests/tests-skeletons/check-OER-support.c

diff --git a/skeletons/oer_support.c b/skeletons/oer_support.c
index cd3d6b9c..37e0909f 100644
--- a/skeletons/oer_support.c
+++ b/skeletons/oer_support.c
@@ -92,7 +92,7 @@ oer_serialize_length(size_t length, asn_app_consume_bytes_f *cb,
     }
 
     if(*(char *)&littleEndian) {
-        pstart = (const uint8_t *)&length + sizeof(length);
+        pstart = (const uint8_t *)&length + sizeof(length) - 1;
         pend = (const uint8_t *)&length;
         add = -1;
     } else {
@@ -106,8 +106,9 @@ oer_serialize_length(size_t length, asn_app_consume_bytes_f *cb,
         if(*p) break;
     }
 
-    for(sp = scratch + 1; p != pend; p += add, sp++) {
-        *sp = *p;
+    for(sp = scratch + 1; ; p += add) {
+        *sp++ = *p;
+        if(p == pend) break;
     }
     assert((sp - scratch) - 1 <= 0x7f);
     scratch[0] = 0x80 + ((sp - scratch) - 1);
diff --git a/tests/tests-skeletons/Makefile.am b/tests/tests-skeletons/Makefile.am
index 0e3cf755..ce8b7b79 100644
--- a/tests/tests-skeletons/Makefile.am
+++ b/tests/tests-skeletons/Makefile.am
@@ -11,6 +11,7 @@ check_PROGRAMS =            \
     check-INTEGER           \
     check-REAL              \
     check-XER               \
+    check-OER-support       \
     check-OER-INTEGER       \
     check-OER-NativeEnumerated \
     check-PER-UniversalString  \
diff --git a/tests/tests-skeletons/check-OER-support.c b/tests/tests-skeletons/check-OER-support.c
new file mode 100644
index 00000000..11f1bc60
--- /dev/null
+++ b/tests/tests-skeletons/check-OER-support.c
@@ -0,0 +1,57 @@
+#include <assert.h>
+#include <oer_support.c>
+
+static char buffer[128];
+
+static int fill_buffer(const void *data, size_t size, void *app_key) {
+    size_t *offset = (size_t *)app_key;
+    assert(*offset + size < sizeof(buffer));
+    memcpy(&buffer[*offset], data, size);
+    *offset += size;
+    return 0;
+}
+
+static void
+check_round_trip(size_t length) {
+    fprintf(stderr, "Round-trip for %zu\n", length);
+
+    /* Serialize */
+    size_t enc_len = 0;
+    size_t enc_len_len = oer_serialize_length(length, fill_buffer, &enc_len);
+    assert(enc_len == enc_len_len);
+
+    /* Deserialize */
+    size_t recovered_length = 0;
+    for(size_t part = 0; part < enc_len; part++) {
+        size_t ret = oer_fetch_length(buffer, part, &recovered_length);
+        assert(ret == 0);   /* More data expected. */
+    }
+    size_t dec_len = oer_fetch_length(buffer, enc_len, &recovered_length);
+    assert(dec_len == enc_len);
+    if(recovered_length != length) {
+        fprintf(stderr, "Round-trip failed %zu->%zu (encoded %zd, decoded %zd)\n",
+                length, recovered_length, enc_len, dec_len);
+        assert(recovered_length == length);
+    }
+}
+
+int main() {
+
+    check_round_trip(0);
+    check_round_trip(1);
+    check_round_trip(127);
+    check_round_trip(128);
+    check_round_trip(129);
+    check_round_trip(255);
+    check_round_trip(256);
+    check_round_trip(65534);
+    check_round_trip(65535);
+    check_round_trip(65536);
+    check_round_trip(65538);
+    check_round_trip(16000000);
+    check_round_trip(16777216);
+    check_round_trip(2147483648);
+    check_round_trip(4294967296);
+
+}
+
-- 
2.26.2