Skip to content
Snippets Groups Projects
Commit db13f518 authored by Lev Walkin's avatar Lev Walkin
Browse files

improved INTEGER printing

parent 29a62261
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,7 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 ...@@ -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 @@ ...@@ -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) { ...@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment