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.
|
||||
(Severity: high, Security impact: medium)
|
||||
* Improved INTEGER type printing.
|
||||
|
||||
0.8.14: 2004-Jun-30
|
||||
|
||||
|
|
|
@ -186,8 +186,8 @@ INTEGER_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
int
|
||||
INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
char scratch[32]; /* Enough for 64-bit integer */
|
||||
const INTEGER_t *st = sptr;
|
||||
char scratch[32];
|
||||
uint8_t *buf = st->buf;
|
||||
uint8_t *buf_end = st->buf + st->size;
|
||||
signed long accum;
|
||||
|
@ -202,9 +202,24 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
if(st->size == 0)
|
||||
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 */
|
||||
if((size_t)st->size < sizeof(accum) || (st->buf[0] & 0x80)) {
|
||||
accum = (st->buf[0] & 0x80) ? -1 : 0;
|
||||
if((size_t)(buf_end - buf) <= sizeof(accum)) {
|
||||
accum = (*buf & 0x80) ? -1 : 0;
|
||||
for(; buf < buf_end; buf++)
|
||||
accum = (accum << 8) | *buf;
|
||||
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 */
|
||||
/* TODO: replace with generic algorithm (Knuth TAOCP Vol 2, 4.3.1) */
|
||||
for(p = scratch; buf < buf_end; buf++) {
|
||||
static char h2c[16] = "0123456789ABCDEF";
|
||||
if((p - scratch) >= (ssize_t)(sizeof(scratch) / 2)) {
|
||||
if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
|
||||
/* Flush buffer */
|
||||
if(cb(scratch, p - scratch, app_key))
|
||||
return -1;
|
||||
|
@ -225,6 +241,8 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
*p++ = h2c[*buf & 0x0F];
|
||||
*p++ = ':';
|
||||
}
|
||||
if(p != scratch)
|
||||
p--; /* Remove the last ':' */
|
||||
|
||||
return cb(scratch, p - scratch, app_key);
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ int
|
|||
NativeInteger_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
const int *Int = sptr;
|
||||
char scratch[32];
|
||||
char scratch[32]; /* Enough for 64-bit int */
|
||||
int ret;
|
||||
|
||||
(void)td; /* Unused argument */
|
||||
|
|
|
@ -5,9 +5,22 @@
|
|||
#include "../der_encoder.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
|
||||
check(uint8_t *buf, int size, long check_long, int check_ret) {
|
||||
char scratch[128];
|
||||
char verify[32];
|
||||
INTEGER_t val;
|
||||
uint8_t *buf_end = buf + size;
|
||||
int ret;
|
||||
long rlong = 123;
|
||||
|
||||
|
@ -17,13 +30,35 @@ check(uint8_t *buf, int size, long check_long, int check_ret) {
|
|||
val.buf = buf;
|
||||
val.size = size;
|
||||
|
||||
printf("Testing: [");
|
||||
for(; buf < buf_end; buf++) {
|
||||
if(buf != val.buf) printf(":");
|
||||
printf("%02x", *buf);
|
||||
}
|
||||
printf("]: ");
|
||||
|
||||
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);
|
||||
assert(ret == check_ret);
|
||||
if(ret == -1) return;
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue