Commit ffbaf06a authored by Pauli's avatar Pauli Committed by Andy Polyakov
Browse files

Reformat the output of BIGNUMS where test cases fail.

parent 5ec3210f
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -306,6 +306,9 @@ static int test_bignum(void)
        | !TEST(0, TEST_BN_gt_zero(a))
        | !TEST(1, TEST_BN_even(a))
        | !TEST(0, TEST_BN_odd(a))
        | !TEST(1, TEST_BN_eq(b, c))
        | !TEST(0, TEST_BN_eq(a, b))
        | !TEST(1, TEST_BN_ne(NULL, c))
        | !TEST(1, TEST_int_eq(BN_dec2bn(&b, "1"), 1))
        | !TEST(1, TEST_BN_eq_word(b, 1))
        | !TEST(1, TEST_BN_eq_one(b))
@@ -374,6 +377,46 @@ static int test_long_output(void)
           & TEST(0, TEST_mem_eq(r, strlen(r), s, strlen(s)));
}

static int test_long_bignum(void)
{
    int r;
    BIGNUM *a = NULL, *b = NULL, *c = NULL, *d = NULL;
    const char as[] = "1234567890123456789012345678901234567890123456789012"
                      "1234567890123456789012345678901234567890123456789012"
                      "1234567890123456789012345678901234567890123456789012"
                      "1234567890123456789012345678901234567890123456789012"
                      "1234567890123456789012345678901234567890123456789012"
                      "1234567890123456789012345678901234567890123456789012"
                      "FFFFFF";
    const char bs[] = "1234567890123456789012345678901234567890123456789012"
                      "1234567890123456789012345678901234567890123456789013"
                      "987657";
    const char cs[] = "-"        /* 64 characters plus sign */
                      "123456789012345678901234567890"
                      "123456789012345678901234567890"
                      "ABCD";
    const char ds[] = "-"        /* 63 characters plus sign */
                      "23456789A123456789B123456789C"
                      "123456789D123456789E123456789F"
                      "ABCD";

    r = TEST_true(BN_hex2bn(&a, as))
        && TEST_true(BN_hex2bn(&b, bs))
        && TEST_true(BN_hex2bn(&c, cs))
        && TEST_true(BN_hex2bn(&d, ds))
        && (TEST(0, TEST_BN_eq(a, b))
            & TEST(0, TEST_BN_eq(b, a))
            & TEST(0, TEST_BN_eq(b, NULL))
            & TEST(0, TEST_BN_eq(NULL, a))
            & TEST(1, TEST_BN_ne(a, NULL))
            & TEST(0, TEST_BN_eq(c, d)));
    BN_free(a);
    BN_free(b);
    BN_free(c);
    BN_free(d);
    return r;
}

static int test_messages(void)
{
    TEST_info("This is an %s message.", "info");
@@ -452,6 +495,7 @@ void register_tests(void)
    ADD_TEST(test_memory_overflow);
    ADD_TEST(test_bignum);
    ADD_TEST(test_long_output);
    ADD_TEST(test_long_bignum);
    ADD_TEST(test_messages);
    ADD_TEST(test_single_eval);
}
+200 −48
Original line number Diff line number Diff line
@@ -16,11 +16,9 @@
#include "../../e_os.h"

/* The size of memory buffers to display on failure */
#define MEM_BUFFER_SIZE     (33)
#define MEM_BUFFER_SIZE     (2000)
#define MAX_STRING_WIDTH    (80)

/* Special representation of -0 */
static char BN_minus_zero[] = "-0";
#define BN_OUTPUT_SIZE      (8)

/* Output a failed test first line */
static void test_fail_message_prefix(const char *prefix, const char *file,
@@ -184,67 +182,222 @@ fin:
    test_flush_stderr();
}

static char *convertBN(const BIGNUM *b)
static void hex_convert_memory(const unsigned char *m, size_t n, char *b,
                               size_t width)
{
    if (b == NULL)
        return NULL;
    if (BN_is_zero(b) && BN_is_negative(b))
        return BN_minus_zero;
    return BN_bn2hex(b);
    size_t i;

    for (i = 0; i < n; i++) {
        const unsigned char c = *m++;

        *b++ = "0123456789abcdef"[c >> 4];
        *b++ = "0123456789abcdef"[c & 15];
        if (i % width == width - 1 && i != n - 1)
            *b++ = ' ';
    }
    *b = '\0';
}

static void test_fail_bignum_message(const char *prefix, const char *file,
static const int bn_bytes = (MAX_STRING_WIDTH - 9) / (BN_OUTPUT_SIZE * 2 + 1)
                            * BN_OUTPUT_SIZE;
static const int bn_chars = (MAX_STRING_WIDTH - 9) / (BN_OUTPUT_SIZE * 2 + 1)
                            * (BN_OUTPUT_SIZE * 2 + 1) - 1;

static void test_bignum_header_line(void)
{
    test_printf_stderr("%*s#  %*s\n", subtest_level(), "", bn_chars + 6,
                       "bit position");
}

static void test_bignum_zero_print(const BIGNUM *bn, char sep)
{
    const char *v = "NULL", *suf = "";
    if (bn != NULL) {
        suf = ":    0";
        v = BN_is_negative(bn) ? "-0" : "0";
    }
    test_printf_stderr("%*s# %c%*s%s\n", subtest_level(), "", sep, bn_chars,
                       v, suf);
}

static int convert_bn_memory(const unsigned char *in, size_t bytes,
                             char *out, int *lz, const BIGNUM *bn)
{
    int n = bytes * 2, i;
    char *p = out, *q = NULL;

    if (bn != NULL && !BN_is_zero(bn)) {
        hex_convert_memory(in, bytes, out, BN_OUTPUT_SIZE);
        if (*lz) {
            for (; *p == '0' || *p == ' '; p++)
                if (*p == '0') {
                    q = p;
                    *p = ' ';
                    n--;
                }
            if (*p == '\0') {
                /*
                 * in[bytes] is defined because we're converting a non-zero
                 * number and we've not seen a non-zero yet.
                 */
                if ((in[bytes] & 0xf0) != 0 && BN_is_negative(bn)) {
                    *lz = 0;
                    *q = '-';
                    n++;
                }
            } else {
                *lz = 0;
                if (BN_is_negative(bn)) {
                    /*
                     * This is valid because we always convert more digits than
                     * the number holds.
                     */
                    *q = '-';
                    n++;
                }
            }
        }
       return n;
    }

    for (i = 0; i < n; i++) {
        *p++ = ' ';
        if (i % (2 * BN_OUTPUT_SIZE) == 2 * BN_OUTPUT_SIZE - 1 && i != n - 1)
            *p++ = ' ';
    }
    *p = '\0';
    if (bn == NULL)
        q = "NULL";
    else
        q = BN_is_negative(bn) ? "-0" : "0";
    strcpy(p - strlen(q), q);
    return 0;
}

static void test_fail_bignum_common(const char *prefix, const char *file,
                                    int line, const char *type,
                                    const char *left, const char *right,
                                    const char *op,
                                    const BIGNUM *bn1, const BIGNUM *bn2)
{
    char *s1 = convertBN(bn1), *s2 = convertBN(bn2);
    size_t l1 = s1 != NULL ? strlen(s1) : 0;
    size_t l2 = s2 != NULL ? strlen(s2) : 0;
    const int indent = subtest_level();
    const size_t bytes = bn_bytes;
    char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1];
    char *p, bdiff[MAX_STRING_WIDTH + 1];
    size_t l1, l2, n1, n2, i, len;
    unsigned int cnt, diff, real_diff;
    unsigned char *m1 = NULL, *m2 = NULL;
    int lz1 = 1, lz2 = 1;
    unsigned char buffer[MEM_BUFFER_SIZE * 2], *bufp = buffer;

    l1 = bn1 == NULL ? 0 : (BN_num_bytes(bn1) + (BN_is_negative(bn1) ? 1 : 0));
    l2 = bn2 == NULL ? 0 : (BN_num_bytes(bn2) + (BN_is_negative(bn2) ? 1 : 0));
    if (l1 == 0 && l2 == 0) {
        if ((bn1 == NULL) == (bn2 == NULL)) {
            test_bignum_header_line();
            test_bignum_zero_print(bn1, ' ');
        } else {
            test_diff_header(left, right);
            test_bignum_header_line();
            test_bignum_zero_print(bn1, '-');
            test_bignum_zero_print(bn2, '+');
        }
        goto fin;
    }

    test_fail_string_message(prefix, file, line, type, left, right, op,
                             s1, l1, s2, l2);
    if (s1 != BN_minus_zero)
        OPENSSL_free(s1);
    if (s2 != BN_minus_zero)
        OPENSSL_free(s2);
    if (l1 != l2 || bn1 == NULL || bn2 == NULL || BN_cmp(bn1, bn2) != 0)
        test_diff_header(left, right);
    test_bignum_header_line();

    len = ((l1 > l2 ? l1 : l2) + bytes - 1) / bytes * bytes;

    if (len > MEM_BUFFER_SIZE && (bufp = OPENSSL_malloc(len * 2)) == NULL) {
        bufp = buffer;
        len = MEM_BUFFER_SIZE;
        test_printf_stderr("%*s# WARNING: these BIGNUMs have been truncated",
                           indent, "");
    }

static void test_fail_bignum_mono_message(const char *prefix, const char *file,
    if (bn1 != NULL) {
        m1 = bufp;
        BN_bn2binpad(bn1, m1, len);
    }
    if (bn2 != NULL) {
        m2 = bufp + len;
        BN_bn2binpad(bn2, m2, len);
    }

    while (len > 0) {
        cnt = 8 * (len - bytes);
        n1 = convert_bn_memory(m1, bytes, b1, &lz1, bn1);
        n2 = convert_bn_memory(m2, bytes, b2, &lz2, bn2);

        diff = real_diff = 0;
        i = 0;
        p = bdiff;
        for (i=0; b1[i] != '\0'; i++)
            if (b1[i] == b2[i] || b1[i] == ' ' || b2[i] == ' ') {
                *p++ = ' ';
                diff |= b1[i] != b2[i];
            } else {
                *p++ = '^';
                real_diff = diff = 1;
            }
        *p++ = '\0';
        if (!diff) {
            test_printf_stderr("%*s#  %s:% 5d\n", indent, "",
                               n2 > n1 ? b2 : b1, cnt);
        } else {
            if (cnt == 0 && bn1 == NULL)
                test_printf_stderr("%*s# -%s\n", indent, "", b1);
            else if (cnt == 0 || n1 > 0)
                test_printf_stderr("%*s# -%s:% 5d\n", indent, "", b1, cnt);
            if (cnt == 0 && bn2 == NULL)
                test_printf_stderr("%*s# +%s\n", indent, "", b2);
            else if (cnt == 0 || n2 > 0)
                test_printf_stderr("%*s# +%s:% 5d\n", indent, "", b2, cnt);
            if (real_diff && (cnt == 0 || (n1 > 0 && n2 > 0))
                    && bn1 != NULL && bn2 != NULL)
                test_printf_stderr("%*s#  %s\n", indent, "", bdiff);
        }
        if (m1 != NULL)
            m1 += bytes;
        if (m2 != NULL)
            m2 += bytes;
        len -= bytes;
    }
fin:
    test_printf_stderr("\n");
    test_flush_stderr();
    if (bufp != buffer)
        OPENSSL_free(bufp);
}

static void test_fail_bignum_message(const char *prefix, const char *file,
                                     int line, const char *type,
                                     const char *left, const char *right,
                                          const char *op, const BIGNUM *bn)
                                     const char *op,
                                     const BIGNUM *bn1, const BIGNUM *bn2)
{
    char *s = convertBN(bn);
    size_t l = s != NULL ? strlen(s) : 0;

    test_fail_string_message(prefix, file, line, type, left, right, op,
                             s, l, s, l);
    if (s != BN_minus_zero)
        OPENSSL_free(s);
    test_fail_message_prefix(prefix, file, line, type, left, right, op);
    test_fail_bignum_common(prefix, file, line, type, left, right, op, bn1, bn2);
}

static void hex_convert_memory(const char *m, size_t n, char *b)
static void test_fail_bignum_mono_message(const char *prefix, const char *file,
                                          int line, const char *type,
                                          const char *left, const char *right,
                                          const char *op, const BIGNUM *bn)
{
    size_t i;

    for (i = 0; i < n; i++) {
        const unsigned char c = *m++;

        *b++ = "0123456789abcdef"[c >> 4];
        *b++ = "0123456789abcdef"[c & 15];
        if ((i % 8) == 7 && i != n - 1)
            *b++ = ' ';
    }
    *b = '\0';
    test_fail_message_prefix(prefix, file, line, type, left, right, op);
    test_fail_bignum_common(prefix, file, line, type, left, right, op, bn, bn);
}

static void test_fail_memory_message(const char *prefix, const char *file,
                                     int line, const char *type,
                                     const char *left, const char *right,
                                     const char *op, const char *m1, size_t l1,
                                     const char *m2, size_t l2)
                                     const char *op,
                                     const unsigned char *m1, size_t l1,
                                     const unsigned char *m2, size_t l2)
{
    const int indent = subtest_level();
    const size_t bytes = (MAX_STRING_WIDTH - 9) / 17 * 8;
@@ -279,11 +432,11 @@ static void test_fail_memory_message(const char *prefix, const char *file,
        n1 = n2 = 0;
        if (l1 > 0) {
            n1 = l1 > bytes ? bytes : l1;
            hex_convert_memory(m1, n1, b1);
            hex_convert_memory(m1, n1, b1, 8);
        }
        if (l2 > 0) {
            n2 = l2 > bytes ? bytes : l2;
            hex_convert_memory(m2, n2, b2);
            hex_convert_memory(m2, n2, b2, 8);
        }

        diff = n1 != n2;
@@ -607,8 +760,7 @@ int test_BN_odd(const char *file, int line, const char *s, const BIGNUM *a)
{
    if (a != NULL && BN_is_odd(a))
        return 1;
    test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s,
                                  a);
    test_fail_bignum_mono_message(NULL, file, line, "BIGNUM", "ODD(", ")", s, a);
    return 0;
}