[Cryptech-Commits] [sw/libhal] 02/03: Beef up XDR unit tests.

git at cryptech.is git at cryptech.is
Tue Dec 3 16:38:16 UTC 2019


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch import_export_raw
in repository sw/libhal.

commit 271a1f830acb229c380ae95c6c2e4c4df367fa82
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Mon Dec 2 15:39:30 2019 -0500

    Beef up XDR unit tests.
---
 tests/test-xdr.c | 426 +++++++++++++++++++++++++++++++++++++++++++++++--------
 xdr.c            |  22 ++-
 2 files changed, 391 insertions(+), 57 deletions(-)

diff --git a/tests/test-xdr.c b/tests/test-xdr.c
index f084e01..6f4eadc 100644
--- a/tests/test-xdr.c
+++ b/tests/test-xdr.c
@@ -42,70 +42,384 @@
 #include "hal_internal.h"	/* htonl/ntohl */
 #include "xdr_internal.h"
 
-static void hexdump(uint8_t *buf, uint32_t len)
+static int verbose = 0;
+
+/* suppress assert() error messages */
+void hal_log(const hal_log_level_t level, const char *format, ...)
 {
-    for (uint32_t i = 0; i < len; ++i)
-        printf("%02x%c", buf[i], ((i & 0x07) == 0x07) ? '\n' : ' ');
-    if ((len & 0x07) != 0)
-        printf("\n");
 }
 
-int main(int argc, char *argv[])
+#define DEFINE_HAL_ERROR(_code_,_text_)  #_code_,
+static char *err_name[] = { HAL_ERROR_LIST };
+#undef  DEFINE_HAL_ERROR
+
+static void hexdump(uint8_t *buf, uint32_t len)
 {
-    uint32_t i;
-    uint8_t buf[256] = {0};
-    uint8_t *bufptr = buf;
-    const uint8_t *readptr;
-    uint8_t *limit = buf + sizeof(buf);
-    hal_error_t ret;
-    uint8_t alphabet[] = "abcdefghijklmnopqrstuvwxyz";
-    uint8_t readbuf[256] = {0};
-
-    printf("hal_xdr_encode_int: work to failure\n");
-    for (i = 1; i < 100; ++i) {
-        if ((ret = hal_xdr_encode_int(&bufptr, limit, i)) != HAL_OK) {
-            printf("%d: %s\n", i, hal_error_string(ret));
-            break;
-        }
+    for (uint32_t i = 0; i < len; ++i) {
+        printf("%02x", buf[i]);
+        if (i < len - 1)
+            printf(" ");
     }
-    hexdump(buf, ((uint8_t *)bufptr - buf));
-
-    printf("\nhal_xdr_decode_int:\n");
-    readptr = buf;
-    while (readptr < bufptr) {
-        if ((ret = hal_xdr_decode_int(&readptr, limit, &i)) != HAL_OK) {
-            printf("%s\n", hal_error_string(ret));
-            break;
-        }
-        printf("%u ", i);
+}
+
+#define test(name, result, expected)                            \
+    if ((err = result) != expected) {                           \
+        if (!verbose) printf("%s: ", func);                     \
+        printf("%s test returned %s, expected %s\n",            \
+               name, err_name[err], err_name[expected]);        \
+        ++nerr;                                                 \
     }
-    printf("\n");
 
-    printf("\nhal_xdr_encode_variable_opaque: work to failure\n");
-    memset(buf, 0, sizeof(buf));
-    bufptr = buf;
-     for (i = 1; ; ++i) {
-        if ((ret = hal_xdr_encode_variable_opaque(&bufptr, limit, alphabet, i)) != HAL_OK) {
-            printf("%d: %s\n", i, hal_error_string(ret));
-            break;
-        }
+#define test_value(val, exp)                            \
+    if (val != exp) {                                   \
+        if (!verbose) printf("%s: ", func);             \
+        printf("value = %u, expected %u\n", val, exp);  \
+        ++nerr;                                         \
+    }
+
+#define test_len(len, exp)                              \
+    if (len != exp) {                                   \
+        if (!verbose) printf("%s: ", func);             \
+        printf("len = %lu, expected %u\n", len, exp);   \
+        ++nerr;                                         \
+    }
+
+#define test_memcmp(buf, exp, len)              \
+    if (memcmp(buf, exp, len) != 0) {           \
+        if (!verbose) printf("%s: ", func);     \
+        printf("buffer = [");                   \
+        hexdump(buf, len);                      \
+        printf("], expected [");                \
+        hexdump(exp, len);                      \
+        printf("]\n");                          \
+        ++nerr;                                 \
     }
-    hexdump(buf, ((uint8_t *)bufptr - buf));
-
-    printf("\nhal_xdr_decode_variable_opaque:\n");
-    readptr = buf;
-    while (readptr < bufptr) {
-        size_t len;
-        if ((ret = hal_xdr_decode_variable_opaque(&readptr, limit, readbuf, &len, bufptr - readptr)) != HAL_OK) {
-            printf("%s\n", hal_error_string(ret));
-            break;
-        }
-        printf("%lu: ", len);
-        for (size_t j = 0; j < len; ++j)
-            putchar(readbuf[j]);
-        putchar('\n');
-        memset(readbuf, 0, sizeof(readbuf));
+
+#define test_bufptr(bfp, exp)                                   \
+    if (bfp != exp) {                                           \
+        if (!verbose) printf("%s: ", func);                     \
+        printf("buf ptr = %p, expected %p\n", bfp, exp);        \
+        ++nerr;                                                 \
     }
 
-    return 0;
+static int test_hal_xdr_encode_int(void)
+{
+    hal_error_t err = HAL_OK;
+    int nerr = 0;
+    uint8_t *null = NULL;
+    uint8_t buf[4] = {0};
+    uint8_t *bufptr = buf;
+    uint8_t *limit = buf + sizeof(buf);
+    uint8_t exp[4] = { 0x00, 0x11, 0x22, 0x33 };
+    uint32_t value = 0x00112233;
+    const char *func = "hal_xdr_encode_int";
+
+    if (verbose)
+        printf("%s... ", func);
+
+    test("null outbuf", hal_xdr_encode_int(NULL, limit, value), HAL_ERROR_ASSERTION_FAILED);
+    test("null outbuf", hal_xdr_encode_int(&null, limit, value), HAL_ERROR_ASSERTION_FAILED);
+    test("null limit", hal_xdr_encode_int(&bufptr, NULL, value), HAL_ERROR_ASSERTION_FAILED);
+    test("outbuf overflow", hal_xdr_encode_int(&bufptr, buf, value), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+    test("outbuf overflow", hal_xdr_encode_int(&bufptr, buf + 3, value), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+
+    test("valid write", hal_xdr_encode_int(&bufptr, limit, value), HAL_OK);
+    test_memcmp(buf, exp, sizeof(exp));
+    test_bufptr(bufptr, buf + 4);
+
+    if (verbose && nerr == 0)
+        printf("PASS\n");
+
+    return nerr;
+}
+
+static int test_hal_xdr_decode_int(void)
+{
+    hal_error_t err = HAL_OK;
+    int nerr = 0;
+    const uint8_t *null = NULL;
+    const uint8_t buf[4] = { 0x00, 0x11, 0x22, 0x33 };
+    const uint8_t *bufptr = buf;
+    const uint8_t * const limit = buf + sizeof(buf);
+    uint32_t value = 0;
+    const uint32_t exp = 0x00112233;
+    const char *func = "hal_xdr_decode_int"; 
+
+    if (verbose)
+        printf("%s... ", func);
+
+    test("null inbuf", hal_xdr_decode_int(NULL, limit, &value), HAL_ERROR_ASSERTION_FAILED);
+    test("null inbuf", hal_xdr_decode_int(&null, limit, &value), HAL_ERROR_ASSERTION_FAILED);
+    test("null limit", hal_xdr_decode_int(&bufptr, NULL, &value), HAL_ERROR_ASSERTION_FAILED);
+    test("null value", hal_xdr_decode_int(&bufptr, limit, NULL), HAL_ERROR_ASSERTION_FAILED);
+
+    test("inbuf overflow", hal_xdr_decode_int(&bufptr, buf, &value), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+    test("inbuf overflow", hal_xdr_decode_int(&bufptr, buf + 3, &value), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+
+    test("valid read", hal_xdr_decode_int(&bufptr, limit, &value), HAL_OK);
+    test_value(value, exp);
+    test_bufptr(bufptr, buf + 4);
+
+    if (verbose && nerr == 0)
+        printf("PASS\n");
+
+    return nerr;
+}
+
+static int test_hal_xdr_decode_int_peek(void)
+{
+    hal_error_t err = HAL_OK;
+    int nerr = 0;
+    const uint8_t buf[4] = { 0x00, 0x11, 0x22, 0x33 };
+    const uint8_t *bufptr = buf;
+    const uint8_t * const limit = buf + sizeof(buf);
+    uint32_t value = 0;
+    const uint32_t exp = 0x00112233;
+    const char *func = "hal_xdr_decode_int_peek";
+
+    if (verbose)
+        printf("%s... ", func);
+
+    test("valid read", hal_xdr_decode_int_peek(&bufptr, limit, &value), HAL_OK);
+    test_value(value, exp);
+    test_bufptr(bufptr, buf);
+
+    if (verbose && nerr == 0)
+        printf("PASS\n");
+
+    return nerr;
+}
+
+static int test_hal_xdr_encode_fixed_opaque(void)
+{
+    hal_error_t err = HAL_OK;
+    int nerr = 0;
+    uint8_t *null = NULL;
+    uint8_t buf[8];
+    uint8_t *bufptr = buf;
+    uint8_t *limit = buf + sizeof(buf);
+    uint8_t src[8]  = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+    uint8_t exp3[4] = { 0x00, 0x11, 0x22, 0x00 };
+    uint8_t exp4[4] = { 0x00, 0x11, 0x22, 0x33 };
+    uint8_t exp5[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00 };
+    const char *func = "hal_xdr_encode_fixed_opaque";
+
+    if (verbose)
+        printf("%s... ", func);
+
+    test("null outbuf", hal_xdr_encode_fixed_opaque(NULL, limit, src, sizeof(src)), HAL_ERROR_ASSERTION_FAILED);
+    test("null outbuf", hal_xdr_encode_fixed_opaque(&null, limit, src, sizeof(src)), HAL_ERROR_ASSERTION_FAILED); 
+    test("null limit", hal_xdr_encode_fixed_opaque(&bufptr, NULL, src, sizeof(src)), HAL_ERROR_ASSERTION_FAILED);
+   test("null value", hal_xdr_encode_fixed_opaque(&bufptr, limit, NULL, sizeof(src)), HAL_ERROR_ASSERTION_FAILED);
+    test("outbuf overflow", hal_xdr_encode_fixed_opaque(&bufptr, buf, src, sizeof(src)), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+
+    memset(buf, 0xff, sizeof(buf));
+    test("write 3", hal_xdr_encode_fixed_opaque(&bufptr, limit, src, 3), HAL_OK);
+    test_memcmp(buf, exp3, sizeof(exp3));
+    test_bufptr(bufptr, buf + 4);
+
+    bufptr = buf;
+    memset(buf, 0xff, sizeof(buf));
+    test("write 4", hal_xdr_encode_fixed_opaque(&bufptr, limit, src, 4), HAL_OK);
+    test_memcmp(buf, exp4, sizeof(exp4));
+    test_bufptr(bufptr, buf + 4)
+    
+    bufptr = buf;
+    memset(buf, 0xff, sizeof(buf));
+    test("write 5", hal_xdr_encode_fixed_opaque(&bufptr, limit, src, 5), HAL_OK);
+    test_memcmp(buf, exp5, sizeof(exp5));
+    test_bufptr(bufptr, buf + 8);
+
+    bufptr = buf;
+    memset(buf, 0xff, sizeof(buf));
+    test("write 8", hal_xdr_encode_fixed_opaque(&bufptr, limit, src, 8), HAL_OK);
+    test_memcmp(buf, src, sizeof(src));
+    test_bufptr(bufptr, buf + 8)
+
+    if (verbose && nerr == 0)
+        printf("PASS\n");
+
+    return nerr;
+}
+
+static int test_hal_xdr_decode_fixed_opaque(void)
+{
+    hal_error_t err = HAL_OK;
+    int nerr = 0;
+    const uint8_t *null = NULL;
+    const uint8_t buf[8]  = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+    const uint8_t *bufptr = buf;
+    const uint8_t *limit = buf + sizeof(buf);
+    uint8_t value[8];
+    uint8_t exp3[4] = { 0x00, 0x11, 0x22, 0x00 };
+    uint8_t exp4[4] = { 0x00, 0x11, 0x22, 0x33 };
+    uint8_t exp5[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00 };
+    const char *func = "hal_xdr_decode_fixed_opaque";
+
+    if (verbose)
+        printf("%s... ", func);
+
+    test("null inbuf", hal_xdr_decode_fixed_opaque(NULL, limit, value, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("null inbuf", hal_xdr_decode_fixed_opaque(&null, limit, value, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("null limit", hal_xdr_decode_fixed_opaque(&bufptr, NULL, value, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("null value", hal_xdr_decode_fixed_opaque(&bufptr, limit, NULL, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("inbuf overflow", hal_xdr_decode_fixed_opaque(&bufptr, buf, value, sizeof(value)), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+
+    memset(value, 0xff, sizeof(value));
+    test("read 3", hal_xdr_decode_fixed_opaque(&bufptr, limit, value, 3), HAL_OK);
+    test_memcmp(value, exp3, sizeof(exp3));
+    test_bufptr(bufptr, buf + 4);
+
+    bufptr = buf;
+    memset(value, 0xff, sizeof(value));
+    test("read 4", hal_xdr_decode_fixed_opaque(&bufptr, limit, value, 4), HAL_OK);
+    test_memcmp(value, exp4, sizeof(exp4));
+    test_bufptr(bufptr, buf + 4);
+
+    bufptr = buf;
+    memset(value, 0xff, sizeof(value));
+    test("read 5", hal_xdr_decode_fixed_opaque(&bufptr, limit, value, 5), HAL_OK);
+    test_memcmp(value, exp5, sizeof(exp5));
+    test_bufptr(bufptr, buf + 8);
+
+    if (verbose && nerr == 0)
+        printf("PASS\n");
+
+    return nerr;
+}
+
+static int test_hal_xdr_encode_variable_opaque(void)
+{
+    hal_error_t err = HAL_OK;
+    int nerr = 0;
+    uint8_t *null = NULL;
+    uint8_t buf[12];
+    uint8_t *bufptr = buf;
+    uint8_t *limit = buf + sizeof(buf);
+    uint8_t src[8]  = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+    uint8_t exp3[8] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x11, 0x22, 0x00 };
+    uint8_t exp4[8] = { 0x00, 0x00, 0x00, 0x04, 0x00, 0x11, 0x22, 0x33 };
+    uint8_t exp5[12] = { 0x00, 0x00, 0x00, 0x05, 0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00 };
+    uint8_t exp8[12] = { 0x00, 0x00, 0x00, 0x08, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+    const char *func = "hal_xdr_encode_variable_opaque";
+
+    if (verbose)
+        printf("%s... ", func);
+
+    test("null outbuf", hal_xdr_encode_variable_opaque(NULL, limit, src, sizeof(src)), HAL_ERROR_ASSERTION_FAILED);
+    test("null outbuf", hal_xdr_encode_variable_opaque(&null, limit, src, sizeof(src)), HAL_ERROR_ASSERTION_FAILED); 
+    test("null limit", hal_xdr_encode_variable_opaque(&bufptr, NULL, src, sizeof(src)), HAL_ERROR_ASSERTION_FAILED);
+   test("null value", hal_xdr_encode_variable_opaque(&bufptr, limit, NULL, sizeof(src)), HAL_ERROR_ASSERTION_FAILED);
+    test("outbuf overflow", hal_xdr_encode_variable_opaque(&bufptr, buf, src, sizeof(src)), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+
+    memset(buf, 0xff, sizeof(buf));
+    test("write 3", hal_xdr_encode_variable_opaque(&bufptr, limit, src, 3), HAL_OK);
+    test_memcmp(buf, exp3, sizeof(exp3));
+    test_bufptr(bufptr, buf + 8);
+
+    bufptr = buf;
+    memset(buf, 0xff, sizeof(buf));
+    test("write 4", hal_xdr_encode_variable_opaque(&bufptr, limit, src, 4), HAL_OK);
+    test_memcmp(buf, exp4, sizeof(exp4));
+    test_bufptr(bufptr, buf + 8)
+    
+    bufptr = buf;
+    memset(buf, 0xff, sizeof(buf));
+    test("write 5", hal_xdr_encode_variable_opaque(&bufptr, limit, src, 5), HAL_OK);
+    test_memcmp(buf, exp5, sizeof(exp5));
+    test_bufptr(bufptr, buf + 12);
+
+    bufptr = buf;
+    memset(buf, 0xff, sizeof(buf));
+    test("write 8", hal_xdr_encode_variable_opaque(&bufptr, limit, src, 8), HAL_OK);
+    test_memcmp(buf, exp8, sizeof(exp8));
+    test_bufptr(bufptr, buf + 12)
+
+    if (verbose && nerr == 0)
+        printf("PASS\n");
+
+    return nerr;
+}
+
+static int test_hal_xdr_decode_variable_opaque(void)
+{
+    hal_error_t err = HAL_OK;
+    int nerr = 0;
+    const uint8_t *null = NULL;
+    uint8_t buf[12]  = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+    const uint8_t *bufptr = buf;
+    const uint8_t *limit = buf + sizeof(buf);
+    uint8_t value[12];
+    size_t len;
+    uint8_t exp3[4] = { 0x00, 0x11, 0x22, 0x00 };
+    uint8_t exp4[4] = { 0x00, 0x11, 0x22, 0x33 };
+    uint8_t exp5[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00 };
+    uint8_t exp8[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+    const char *func = "hal_xdr_decode_variable_opaque";
+
+    if (verbose)
+        printf("%s... ", func);
+
+    test("null inbuf", hal_xdr_decode_variable_opaque(NULL, limit, value, &len, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("null inbuf", hal_xdr_decode_variable_opaque(&null, limit, value, &len, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("null limit", hal_xdr_decode_variable_opaque(&bufptr, NULL, value, &len, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("null value", hal_xdr_decode_variable_opaque(&bufptr, limit, NULL, &len, sizeof(value)), HAL_ERROR_ASSERTION_FAILED);
+    test("inbuf overflow", hal_xdr_decode_variable_opaque(&bufptr, buf, value, &len, sizeof(value)), HAL_ERROR_XDR_BUFFER_OVERFLOW);
+
+    buf[3] = 0x03;
+    memset(value, 0xff, sizeof(value));
+    test("read 3", hal_xdr_decode_variable_opaque(&bufptr, limit, value, &len, sizeof(value)), HAL_OK);
+    test_len(len, 3);
+    test_memcmp(value, exp3, sizeof(exp3));
+    test_bufptr(bufptr, buf + 8);
+
+    bufptr = buf;
+    buf[3] = 0x04;
+    memset(value, 0xff, sizeof(value));
+    test("read 4", hal_xdr_decode_variable_opaque(&bufptr, limit, value, &len, sizeof(value)), HAL_OK);
+    test_len(len, 4);
+    test_memcmp(value, exp4, sizeof(exp4));
+    test_bufptr(bufptr, buf + 8);
+
+    bufptr = buf;
+    buf[3] = 0x05;
+    memset(value, 0xff, sizeof(value));
+    test("read 5", hal_xdr_decode_variable_opaque(&bufptr, limit, value, &len, sizeof(value)), HAL_OK);
+    test_len(len, 5);
+    test_memcmp(value, exp5, sizeof(exp5));
+    test_bufptr(bufptr, buf + 12);
+
+    bufptr = buf;
+    buf[3] = 0x08;
+    memset(value, 0xff, sizeof(value));
+    test("read 8", hal_xdr_decode_variable_opaque(&bufptr, limit, value, &len, sizeof(value)), HAL_OK);
+    test_len(len, 8);
+    test_memcmp(value, exp8, sizeof(exp8));
+    test_bufptr(bufptr, buf + 12);
+
+    if (verbose && nerr == 0)
+        printf("PASS\n");
+
+    return nerr;
+}
+
+
+int main(int argc, char *argv[])
+{
+    if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'v')
+        verbose = 1;
+
+    int nerr = 0;
+    nerr += test_hal_xdr_encode_int();
+    nerr += test_hal_xdr_decode_int();
+    nerr += test_hal_xdr_decode_int_peek();
+    nerr += test_hal_xdr_encode_fixed_opaque();
+    nerr += test_hal_xdr_decode_fixed_opaque();
+    nerr += test_hal_xdr_encode_variable_opaque();
+    nerr += test_hal_xdr_decode_variable_opaque();
+
+    if (nerr)
+        printf("%d failures\n", nerr);
+
+    return nerr;
 }
diff --git a/xdr.c b/xdr.c
index 92c2b64..3c02635 100644
--- a/xdr.c
+++ b/xdr.c
@@ -94,6 +94,9 @@ hal_error_t hal_xdr_encode_fixed_opaque(uint8_t ** const outbuf, const uint8_t *
     /* arg checks */
     hal_assert(outbuf != NULL && *outbuf != NULL && limit != NULL && limit >= *outbuf && (value != NULL || len == 0));
 
+    if (len == 0)
+        return HAL_OK;
+
     /* buffer overflow check */
     /* We need to explicitly check (len > 0xfffffffc) because padding will
      * round it up to 0.
@@ -135,11 +138,22 @@ hal_error_t hal_xdr_decode_fixed_opaque(const uint8_t ** const inbuf, const uint
     const uint8_t *p;
     hal_error_t err;
 
+    /* arg checks */
+    hal_assert(value != NULL || len == 0);
+
+    if (len == 0)
+        return HAL_OK;
+
     /* get and advance the input data pointer */
-    if ((err = hal_xdr_decode_fixed_opaque_ptr(inbuf, limit, &p, len)) == HAL_OK)
+    if ((err = hal_xdr_decode_fixed_opaque_ptr(inbuf, limit, &p, len)) == HAL_OK) {
         /* read the data */
         memcpy(value, p, len);
 
+        /* pad if necessary */
+        for (size_t i = len; (i & 3) != 0; ++i)
+            value[i] = 0;
+    }
+
     return err;
 }
 
@@ -204,8 +218,14 @@ hal_error_t hal_xdr_decode_variable_opaque(const uint8_t ** const inbuf, const u
         /* user buffer overflow check */
         if (len_max < xdr_len)
             return HAL_ERROR_XDR_BUFFER_OVERFLOW;
+
         /* read the data */
         memcpy(value, p, xdr_len);
+
+        /* pad if necessary */
+        for (size_t i = xdr_len; (i & 3) != 0; ++i)
+            value[i] = 0;
+
         *len = xdr_len;
     }
 



More information about the Commits mailing list