Commit 0959ffb2 authored by Lev Walkin's avatar Lev Walkin

Fix decoding of REAL values in NR3.

The NR3 form of values is used by Erlang to communicate REAL data.
parent cf6c1e23
......@@ -9,6 +9,7 @@
* PER encoding correctness fix. (Severity: high; Security impact: low)
Reported by Grzegorz Aksamit.
* ENUMERATED extension values check relaxed. Reported by Gabriel Burca.
* Fixed decimal decoding of REAL values in -fnative-types mode (Severity: medium; Security impact: medium)
0.9.22: 2008-Nov-19
......
......@@ -107,10 +107,39 @@ NativeReal_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
tmp.size = length;
if(asn_REAL2double(&tmp, &d)) {
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
if(length < (ber_tlv_len_t)size) {
int ret;
uint8_t saved_byte = tmp.buf[tmp.size];
tmp.buf[tmp.size] = '\0';
ret = asn_REAL2double(&tmp, &d);
tmp.buf[tmp.size] = saved_byte;
if(ret) {
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
} else if(length < 48 /* Enough for longish %f value. */) {
tmp.buf = alloca(length + 1);
tmp.size = length;
memcpy(tmp.buf, buf_ptr, length);
tmp.buf[tmp.size] = '\0';
if(asn_REAL2double(&tmp, &d)) {
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
} else {
/* This should probably never happen: impractically long value */
tmp.buf = CALLOC(1, length + 1);
tmp.size = length;
if(tmp.buf) memcpy(tmp.buf, buf_ptr, length);
if(!tmp.buf || asn_REAL2double(&tmp, &d)) {
FREEMEM(tmp.buf);
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
FREEMEM(tmp.buf);
}
*Dbl = d;
......
......@@ -403,21 +403,31 @@ asn_REAL2double(const REAL_t *st, double *dbl_value) {
errno = EINVAL;
return -1;
case 0x00: { /* X.690: 8.5.6 */
case 0x00: { /* X.690: 8.5.7 */
/*
* Decimal. NR{1,2,3} format.
*/
double d;
assert(st->buf[st->size - 1] == 0); /* Security, vashu mat' */
if(octv == 0 || octv & 0x3C == 0) {
/* Remaining values of bits 6 to 1 are Reserved. */
errno = EINVAL;
return -1;
}
d = strtod((char *)st->buf, 0);
if(st->buf[st->size]) {
/* By contract, an input buffer should be null-terminated */
errno = EINVAL;
return -1;
}
d = strtod((char *)&st->buf[1], 0);
if(finite(d)) {
*dbl_value = d;
return 0;
} else {
errno = ERANGE;
return 0;
return -1;
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment