mirror of https://gerrit.osmocom.org/asn1c
improved INTEGER printing
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@55 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
parent
f0769b419e
commit
7d278c491d
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
* Fixed parser: memory leak in free_struct code for SET OF/SEQUENCE OF.
|
* Fixed parser: memory leak in free_struct code for SET OF/SEQUENCE OF.
|
||||||
(Severity: high, Security impact: medium)
|
(Severity: high, Security impact: medium)
|
||||||
|
* Improved INTEGER type printing.
|
||||||
|
|
||||||
0.8.14: 2004-Jun-30
|
0.8.14: 2004-Jun-30
|
||||||
|
|
||||||
|
|
|
@ -186,8 +186,8 @@ INTEGER_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
||||||
int
|
int
|
||||||
INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||||
|
char scratch[32]; /* Enough for 64-bit integer */
|
||||||
const INTEGER_t *st = sptr;
|
const INTEGER_t *st = sptr;
|
||||||
char scratch[32];
|
|
||||||
uint8_t *buf = st->buf;
|
uint8_t *buf = st->buf;
|
||||||
uint8_t *buf_end = st->buf + st->size;
|
uint8_t *buf_end = st->buf + st->size;
|
||||||
signed long accum;
|
signed long accum;
|
||||||
|
@ -202,9 +202,24 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
if(st->size == 0)
|
if(st->size == 0)
|
||||||
return cb("0", 1, app_key);
|
return cb("0", 1, app_key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Advance buf pointer until the start of the value's body.
|
||||||
|
* This will make us able to process large integers using simple case,
|
||||||
|
* when the actual value is small
|
||||||
|
* (0x0000000000abcdef would yield a fine 0x00abcdef)
|
||||||
|
*/
|
||||||
|
/* Skip the insignificant leading bytes */
|
||||||
|
for(; buf < buf_end-1; buf++) {
|
||||||
|
switch(*buf) {
|
||||||
|
case 0x00: if((buf[1] & 0x80) == 0) continue; break;
|
||||||
|
case 0xff: if((buf[1] & 0x80) != 0) continue; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Simple case: the integer size is small */
|
/* Simple case: the integer size is small */
|
||||||
if((size_t)st->size < sizeof(accum) || (st->buf[0] & 0x80)) {
|
if((size_t)(buf_end - buf) <= sizeof(accum)) {
|
||||||
accum = (st->buf[0] & 0x80) ? -1 : 0;
|
accum = (*buf & 0x80) ? -1 : 0;
|
||||||
for(; buf < buf_end; buf++)
|
for(; buf < buf_end; buf++)
|
||||||
accum = (accum << 8) | *buf;
|
accum = (accum << 8) | *buf;
|
||||||
ret = snprintf(scratch, sizeof(scratch), "%ld", accum);
|
ret = snprintf(scratch, sizeof(scratch), "%ld", accum);
|
||||||
|
@ -213,9 +228,10 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output in the long xx:yy:zz... format */
|
/* Output in the long xx:yy:zz... format */
|
||||||
|
/* TODO: replace with generic algorithm (Knuth TAOCP Vol 2, 4.3.1) */
|
||||||
for(p = scratch; buf < buf_end; buf++) {
|
for(p = scratch; buf < buf_end; buf++) {
|
||||||
static char h2c[16] = "0123456789ABCDEF";
|
static char h2c[16] = "0123456789ABCDEF";
|
||||||
if((p - scratch) >= (ssize_t)(sizeof(scratch) / 2)) {
|
if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
|
||||||
/* Flush buffer */
|
/* Flush buffer */
|
||||||
if(cb(scratch, p - scratch, app_key))
|
if(cb(scratch, p - scratch, app_key))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -225,6 +241,8 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
*p++ = h2c[*buf & 0x0F];
|
*p++ = h2c[*buf & 0x0F];
|
||||||
*p++ = ':';
|
*p++ = ':';
|
||||||
}
|
}
|
||||||
|
if(p != scratch)
|
||||||
|
p--; /* Remove the last ':' */
|
||||||
|
|
||||||
return cb(scratch, p - scratch, app_key);
|
return cb(scratch, p - scratch, app_key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ int
|
||||||
NativeInteger_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
NativeInteger_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||||
const int *Int = sptr;
|
const int *Int = sptr;
|
||||||
char scratch[32];
|
char scratch[32]; /* Enough for 64-bit int */
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
(void)td; /* Unused argument */
|
(void)td; /* Unused argument */
|
||||||
|
|
|
@ -5,9 +5,22 @@
|
||||||
#include "../der_encoder.c"
|
#include "../der_encoder.c"
|
||||||
#include "../constraints.c"
|
#include "../constraints.c"
|
||||||
|
|
||||||
|
static char *shared_scratch_start;
|
||||||
|
|
||||||
|
static int _print2buf(const void *buf, size_t size, void *key) {
|
||||||
|
(void)key;
|
||||||
|
memcpy(shared_scratch_start, buf, size);
|
||||||
|
shared_scratch_start += size;
|
||||||
|
*shared_scratch_start = '\0'; /* 0-termination */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check(uint8_t *buf, int size, long check_long, int check_ret) {
|
check(uint8_t *buf, int size, long check_long, int check_ret) {
|
||||||
|
char scratch[128];
|
||||||
|
char verify[32];
|
||||||
INTEGER_t val;
|
INTEGER_t val;
|
||||||
|
uint8_t *buf_end = buf + size;
|
||||||
int ret;
|
int ret;
|
||||||
long rlong = 123;
|
long rlong = 123;
|
||||||
|
|
||||||
|
@ -17,13 +30,35 @@ check(uint8_t *buf, int size, long check_long, int check_ret) {
|
||||||
val.buf = buf;
|
val.buf = buf;
|
||||||
val.size = size;
|
val.size = size;
|
||||||
|
|
||||||
|
printf("Testing: [");
|
||||||
|
for(; buf < buf_end; buf++) {
|
||||||
|
if(buf != val.buf) printf(":");
|
||||||
|
printf("%02x", *buf);
|
||||||
|
}
|
||||||
|
printf("]: ");
|
||||||
|
|
||||||
ret = asn1_INTEGER2long(&val, &rlong);
|
ret = asn1_INTEGER2long(&val, &rlong);
|
||||||
printf("Testing (%ld, %d) vs (%ld, %d)\n",
|
printf(" (%ld, %d) vs (%ld, %d)\n",
|
||||||
rlong, ret, check_long, check_ret);
|
rlong, ret, check_long, check_ret);
|
||||||
assert(ret == check_ret);
|
assert(ret == check_ret);
|
||||||
if(ret == -1) return;
|
|
||||||
assert(rlong == check_long);
|
assert(rlong == check_long);
|
||||||
|
|
||||||
|
shared_scratch_start = scratch;
|
||||||
|
ret = INTEGER_print(&asn1_DEF_INTEGER, &val, 0, _print2buf, scratch);
|
||||||
|
assert(shared_scratch_start < scratch + sizeof(scratch));
|
||||||
|
assert(ret == 0);
|
||||||
|
ret = snprintf(verify, sizeof(verify), "%ld", check_long);
|
||||||
|
assert(ret < sizeof(verify));
|
||||||
|
ret = strcmp(scratch, verify);
|
||||||
|
printf(" [%s] vs [%s]: %d%s\n",
|
||||||
|
scratch, verify, ret,
|
||||||
|
(check_ret == -1)?" (expected to fail)":""
|
||||||
|
);
|
||||||
|
if(check_ret == -1) {
|
||||||
|
assert(strcmp(scratch, verify));
|
||||||
|
} else {
|
||||||
|
assert(strcmp(scratch, verify) == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue