aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2012-01-07 17:00:29 -0800
committerLev Walkin <vlm@lionet.info>2012-01-07 17:00:29 -0800
commit5fe72e9d6ce7c0a9512046b30ae244a772b56fa8 (patch)
treeff03af9639146786bfeb4e898e8f803aa8686362
parent833d27521dfa4425d9adbae4f6472d68c1f68f72 (diff)
test encoding of special values
-rw-r--r--skeletons/REAL.c10
-rw-r--r--skeletons/tests/check-REAL.c223
2 files changed, 166 insertions, 67 deletions
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index e5cced8e..b8585e02 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -577,14 +577,14 @@ asn_double2REAL(REAL_t *st, double dbl_value) {
st->buf[1] = 0;
st->size = 1;
} else {
- if(copysign(1.0, dbl_value) < 0.0) {
- st->buf[0] = 0x80 | 0x40;
- st->buf[1] = 0;
- st->size = 2;
- } else {
+ if(copysign(1.0, dbl_value) >= 0.0) {
/* no content octets: positive zero */
st->buf[0] = 0; /* JIC */
st->size = 0;
+ } else {
+ /* Negative zero. #8.5.3, 8.5.9 */
+ st->buf[0] = 0x43;
+ st->size = 1;
}
}
return 0;
diff --git a/skeletons/tests/check-REAL.c b/skeletons/tests/check-REAL.c
index 46b1a95b..07918ef2 100644
--- a/skeletons/tests/check-REAL.c
+++ b/skeletons/tests/check-REAL.c
@@ -39,26 +39,29 @@ d2s(double d, int canonical, const char *str) {
* is as given in the (sample) and (canonical_sample) arguments.
*/
static void
-check_str_repr(double d, const char *sample, const char *canonical_sample) {
+check_str_representation(double d, const char *sample, const char *canonical_sample) {
char *s0, *s1;
s0 = d2s(d, 0, sample);
s1 = d2s(d, 1, canonical_sample);
if(sample) {
- printf("Checking %f->[%s] against [%s]%s\n",
+ printf("Checking %f->[\"%s\"] against [\"%s\"]%s\n",
d, s0, sample,
canonical_sample ? " (canonical follows...)" : ""
);
assert(!strcmp(s0, sample));
}
if(canonical_sample) {
- printf("Checking %f->[%s] against [%s] (canonical)\n",
+ printf("Checking %f->[\"%s\"] against [\"%s\"] (canonical)\n",
d, s1, canonical_sample);
assert(!strcmp(s1, canonical_sample));
}
}
+#define check(rn, d, str1, str2) \
+ check_impl(rn, d, str1, str2, __LINE__)
+
static void
check_impl(REAL_t *rn, double orig_dbl, const char *sample, const char *canonical_sample, int line) {
double val;
@@ -96,57 +99,8 @@ check_impl(REAL_t *rn, double orig_dbl, const char *sample, const char *canonica
assert((isnan(orig_dbl) && isnan(val)) || val == orig_dbl);
printf("OK\n");
- check_str_repr(val, sample, canonical_sample);
+ check_str_representation(val, sample, canonical_sample);
}
-
-uint8_t buf_1_0[] = { 0x80, 0xcc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-uint8_t buf_1_1[] = { 0x80, 0xcc, 0x11, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a };
-uint8_t buf_3_14[] = { 0x80, 0xcd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f };
-/* These ones are very interesting! They check mantissa overflow! */
-uint8_t buf_mo1[] = { 0xC0, 0xc5, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3};
-uint8_t buf_mo2[] = { 0x80, 0xbd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3,2};
-
-static void
-check_buf(uint8_t *buf, size_t bufsize, double verify, const char *sample, const char *canonical_sample) {
- REAL_t rn;
- double val;
- uint8_t *p, *end;
- int ret;
-
- printf("verify double value %.12f [", verify);
- for(p = (uint8_t *)&verify, end = p + sizeof(double); p < end ; p++)
- printf("%02x", *p);
- printf("] (ilogb %d)\n", ilogb(verify));
-
- rn.buf = 0;
- rn.size = 0;
-
- ret = asn_double2REAL(&rn, verify);
- assert(ret == 0);
-
- printf("canonical DER: [");
- for(p = rn.buf, end = p + rn.size; p < end; p++)
- printf("%02x", *p);
- printf("]\n");
-
- rn.buf = buf;
- rn.size = bufsize;
-
- printf("received as: [");
- for(p = rn.buf, end = p + rn.size; p < end; p++)
- printf("%02x", *p);
- printf("]\n");
-
- ret = asn_REAL2double(&rn, &val);
- assert(ret == 0);
-
- printf("%.12f vs %.12f\n", verify, val);
-
- assert(val == verify);
-
- check_str_repr(val, sample, canonical_sample);
-}
-
static void
check_xer(int fuzzy, double orig_value) {
asn_enc_rval_t er;
@@ -207,16 +161,167 @@ check_xer(int fuzzy, double orig_value) {
assert(memcmp(newst1->buf, st.buf, st.size) == 0);
}
-#define check(rn, d, str1, str2) \
- check_impl(rn, d, str1, str2, __LINE__)
+static void
+check_ber_buffer_twoway(double d, const char *sample, const char *canonical_sample, uint8_t *inbuf, size_t insize, uint8_t *outbuf, size_t outsize) {
+ REAL_t rn;
+ double val;
+ int ret;
+
+ /*
+ * Decode our expected buffer and check that it matches the given (d).
+ */
+ rn.buf = inbuf;
+ rn.size = insize;
+ asn_REAL2double(&rn, &val);
+ if(isnan(val)) assert(isnan(d));
+ if(isnan(d)) assert(isnan(val));
+ if(!isnan(val) && !isnan(d)) {
+ assert(copysign(1.0, d) == copysign(1.0, val));
+ assert(d == val);
+ }
+
+ /*
+ * Encode value and check that it matches our expected buffer.
+ */
+ memset(&rn, 0, sizeof(rn));
+ ret = asn_double2REAL(&rn, d);
+ assert(ret == 0);
+ uint8_t *p, *end;
+ printf("received as: [");
+ for(p = rn.buf, end = p + rn.size; p < end; p++)
+ printf("%02x", *p);
+ printf("]\n");
+ printf("received as: [");
+ for(p = outbuf, end = p + outsize; p < end; p++)
+ printf("%02x", *p);
+ printf("]\n");
+ if(rn.size != outsize) {
+ printf("Encoded %f into %d expected %ld\n",
+ d, (int)rn.size, outsize);
+ assert(rn.size == outsize);
+ }
+ assert(memcmp(rn.buf, outbuf, rn.size) == 0);
+
+ check_str_representation(d, sample, canonical_sample);
+}
+
+static void
+check_ber_buffer_oneway(double d, const char *sample, const char *canonical_sample, uint8_t *buf, size_t bufsize) {
+ REAL_t rn;
+ double val;
+ uint8_t *p, *end;
+ int ret;
+
+ memset(&rn, 0, sizeof(rn));
+
+ printf("verify double value %.12f [", d);
+ for(p = (uint8_t *)&d, end = p + sizeof(double); p < end ; p++)
+ printf("%02x", *p);
+ printf("] (ilogb %d)\n", ilogb(d));
+
+
+ ret = asn_double2REAL(&rn, d);
+ assert(ret == 0);
+
+ printf("canonical DER: [");
+ for(p = rn.buf, end = p + rn.size; p < end; p++)
+ printf("%02x", *p);
+ printf("]\n");
+
+ rn.buf = buf;
+ rn.size = bufsize;
+
+ printf("received as: [");
+ for(p = rn.buf, end = p + rn.size; p < end; p++)
+ printf("%02x", *p);
+ printf("]\n");
+
+ ret = asn_REAL2double(&rn, &val);
+ assert(ret == 0);
+
+ printf("%.12f vs %.12f\n", d, val);
+
+ assert(val == d);
+
+ check_str_representation(val, sample, canonical_sample);
+}
+
+
+static void
+check_ber_encoding() {
+ static const double zero = 0.0;
+
+#define CHECK_BER_STRICT(v, nocan, can, inbuf, outbuf) \
+ check_ber_buffer_twoway(v, nocan, can, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf))
+
+#define CHECK_BER_NONSTRICT(v, nocan, can, buf) \
+ check_ber_buffer_oneway(v, nocan, can, buf, sizeof(buf))
+
+ /*
+ * X.690 8.4 Encoding of an enumerated value.
+ */
+
+ /* 8.5.2 If the real value is the value plus zero,
+ * there shall be no contents octet in the encoding */
+ { uint8_t b_0[] = {};
+ CHECK_BER_STRICT(0, "0", "0", b_0, b_0);
+ }
+
+ /* 8.5.3 When -0 is to be encoded, there shall be only one contents octet */
+ { uint8_t b_m0[] = { 0x43 };
+ CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0, b_m0);
+ }
+
+ /* Old way of encoding -0.0: 8.5.6 a) */
+ { uint8_t b_m0[] = { 0x43 };
+ uint8_t b_m0_856a[] = { 0xC0, 0x00 }; /* #8.5.6 a) */
+ uint8_t b_m0_856a_1[] = { 0xC0, 0x00, 0x00 };
+ uint8_t b_m0_856a_2[] = { 0xC0, 0x00, 0x00, 0x00 };
+ uint8_t b_m0_856a_3[] = { 0xC0, 0x00, 0x00, 0x00, 0x00 };
+ CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a, b_m0);
+ CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a_1, b_m0);
+ CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a_2, b_m0);
+ CHECK_BER_STRICT(-0.0, "-0", "-0", b_m0_856a_3, b_m0);
+ }
+
+ /* 8.5.6 c) => 8.5.9 SpecialRealValue */
+ { uint8_t b_pinf[] = { 0x40 };
+ uint8_t b_minf[] = { 0x41 };
+ uint8_t b_nan[] = { 0x42 };
+ CHECK_BER_STRICT(1.0/zero, "<PLUS-INFINITY/>", "<PLUS-INFINITY/>", b_pinf, b_pinf);
+ CHECK_BER_STRICT(-1.0/zero, "<MINUS-INFINITY/>", "<MINUS-INFINITY/>", b_minf, b_minf);
+ CHECK_BER_STRICT(zero/zero, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>", b_nan, b_nan);
+ }
+
+ {
+ uint8_t b_1_0[] =
+ { 0x80, 0xcc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ uint8_t b_1_1[] =
+ { 0x80, 0xcc, 0x11, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a };
+ uint8_t b_3_14[] =
+ { 0x80, 0xcd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f };
+ uint8_t b_3_14_mo1[] =
+ { 0xC0, 0xc5, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3};
+ uint8_t b_3_14_mo2[] =
+ { 0x80, 0xbd, 0x19, 0x1e, 0xb8, 0x51, 0xeb, 0x85, 0x1f,3,2};
+
+ CHECK_BER_NONSTRICT(1.0, "1.0", "1.0E0", b_1_0);
+ CHECK_BER_NONSTRICT(1.1, "1.1", "1.1E0", b_1_1);
+ CHECK_BER_NONSTRICT(3.14, "3.14", "3.14E0", b_3_14);
+ /* These two are very interesting! They check mantissa overflow! */
+ CHECK_BER_NONSTRICT(-3.14, "-3.14", "-3.14E0", b_3_14_mo1);
+ CHECK_BER_NONSTRICT(3.14, "3.14", "3.14E0", b_3_14_mo2);
+ }
+}
int
main() {
REAL_t rn;
static const double zero = 0.0;
-
memset(&rn, 0, sizeof(rn));
+ check_ber_encoding();
+
check(&rn, 0.0, "0", "0");
check(&rn, -0.0, "-0", "-0"); /* minus-zero */
check(&rn, zero/zero, "<NOT-A-NUMBER/>", "<NOT-A-NUMBER/>");
@@ -260,12 +365,6 @@ main() {
check(&rn, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0);
check(&rn, -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
- check_buf(buf_1_0, sizeof(buf_1_0), 1.0, "1.0", "1.0E0");
- check_buf(buf_1_1, sizeof(buf_1_1), 1.1, "1.1", "1.1E0");
- check_buf(buf_3_14, sizeof(buf_3_14), 3.14, "3.14", "3.14E0");
- check_buf(buf_mo1, sizeof(buf_mo1), -3.14, "-3.14", "-3.14E0");
- check_buf(buf_mo2, sizeof(buf_mo2), 3.14, "3.14", "3.14E0");
-
#ifdef NAN
check_xer(0, NAN); /* "<NOT-A-NUMBER/>" */