work in 128-bit integer values while compiling

This commit is contained in:
Lev Walkin 2017-08-04 01:38:41 -07:00
parent 2b290bef16
commit da997b1ea1
14 changed files with 292 additions and 125 deletions

View File

@ -40,6 +40,7 @@
#include <OBJECT_IDENTIFIER.c>
#include <RELATIVE-OID.c>
#include <asn_codecs_prim.c>
#include <asn1p_integer.c>
#undef COPYRIGHT
#define COPYRIGHT "Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>\n"
@ -164,10 +165,10 @@ typedef enum pd_code {
PD_EOF = 1,
} pd_code_e;
static pd_code_e process_deeper(const char *fname, FILE *fp,
asn1c_integer_t *offset, int level,
size_t *offset, int level,
ssize_t limit, ber_tlv_len_t *frame_size,
ber_tlv_len_t effective_size, int expect_eoc);
static void print_TL(int fin, asn1c_integer_t offset, int level, int constr,
static void print_TL(int fin, size_t offset, int level, int constr,
ssize_t tlen, ber_tlv_tag_t, ber_tlv_len_t,
ber_tlv_len_t effective_frame_size);
static int print_V(const char *fname, FILE *fp, ber_tlv_tag_t, ber_tlv_len_t);
@ -179,7 +180,7 @@ static int
process(const char *fname) {
FILE *fp;
pd_code_e pdc;
asn1c_integer_t offset = 0; /* Stream decoding position */
size_t offset = 0; /* Stream decoding position */
ber_tlv_len_t frame_size = 0; /* Single frame size */
if(strcmp(fname, "-")) {
@ -197,8 +198,7 @@ process(const char *fname) {
*/
for(; offset < skip_bytes; offset++) {
if(fgetc(fp) == -1) {
fprintf(stderr, "%s: input source (%" PRIdASN
" bytes) "
fprintf(stderr, "%s: input source (%zu bytes) "
"has less data than \"-s %d\" switch "
"wants to skip\n",
fname, offset, skip_bytes);
@ -224,7 +224,7 @@ process(const char *fname) {
* Process the TLV recursively.
*/
static pd_code_e
process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level,
process_deeper(const char *fname, FILE *fp, size_t *offset, int level,
ssize_t limit, ber_tlv_len_t *frame_size,
ber_tlv_len_t effective_size, int expect_eoc) {
unsigned char tagbuf[32];
@ -245,8 +245,7 @@ process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level,
if(limit >= 0 && tblen >= limit) {
fprintf(stderr,
"%s: Too long TL sequence (%ld >= %ld)"
" at %" PRIdASN
". "
" at %zu. "
"Broken or maliciously constructed file\n",
fname, (long)tblen, (long)limit, *offset);
return PD_FAILED;
@ -258,7 +257,7 @@ process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level,
if(limit > 0 || expect_eoc) {
fprintf(stderr,
"%s: Unexpected end of file (TL)"
" at %" PRIdASN "\n",
" at %zu\n",
fname, *offset);
return PD_FAILED;
} else {
@ -276,7 +275,7 @@ process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level,
case -1:
fprintf(stderr,
"%s: Fatal error decoding tag"
" at %" PRIdASN "+%ld\n",
" at %zu+%ld\n",
fname, *offset, (long)tblen);
return PD_FAILED;
case 0:
@ -294,7 +293,7 @@ process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level,
case -1:
fprintf(stderr,
"%s: Fatal error decoding value length"
" at %" PRIdASN "\n",
" at %zu\n",
fname, *offset + t_len);
return PD_FAILED;
case 0:
@ -386,7 +385,7 @@ process_deeper(const char *fname, FILE *fp, asn1c_integer_t *offset, int level,
}
static void
print_TL(int fin, asn1c_integer_t offset, int level, int constr, ssize_t tlen,
print_TL(int fin, size_t offset, int level, int constr, ssize_t tlen,
ber_tlv_tag_t tlv_tag, ber_tlv_len_t tlv_len,
ber_tlv_len_t effective_size) {
if(fin && !constr) {
@ -400,7 +399,7 @@ print_TL(int fin, asn1c_integer_t offset, int level, int constr, ssize_t tlen,
printf(constr ? ((tlv_len == -1) ? "I" : "C") : "P");
/* Print out the offset of this boundary, even if closing tag */
if(!minimalistic) printf(" O=\"%" PRIdASN "\"", offset);
if(!minimalistic) printf(" O=\"%zu\"", offset);
printf(" T=\"");
ber_tlv_tag_fwrite(tlv_tag, stdout);
@ -573,7 +572,7 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag,
switch(etype) {
case ASN_BASIC_INTEGER:
case ASN_BASIC_ENUMERATED:
printf("%" PRIdASN, collector);
printf("%s", asn1p_itoa(collector));
break;
case ASN_BASIC_OBJECT_IDENTIFIER:
if(vbuf) {
@ -590,7 +589,7 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag,
printf(" F>");
for(i = 0; i < arcno; i++) {
if(i) printf(".");
printf("%" PRIuASN, arcs[i]);
printf("%s", asn1p_itoa(arcs[i]));
}
FREEMEM(vbuf);
vbuf = 0;
@ -611,7 +610,7 @@ print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag,
printf(" F>");
for(i = 0; i < arcno; i++) {
if(i) printf(".");
printf("%" PRIuASN, arcs[i]);
printf("%s", asn1p_itoa(arcs[i]));
}
FREEMEM(vbuf);
vbuf = 0;

View File

@ -123,6 +123,8 @@ AC_C_BIGENDIAN
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_STRUCT_TM
AC_CHECK_TYPE([__int128],
[AC_DEFINE(HAVE_128_BIT_INT, 1, [Have 128-bit integer])])
AC_CHECK_TYPE(intmax_t, int64_t)
dnl Test if we should test features that depend on 64-bitness.

View File

@ -9,6 +9,7 @@
#include "asn1c_misc.h"
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
#include <asn1fix_export.h> /* other exportables from libasn1fix */
#include <asn1parser.h>
typedef struct tag2el_s {
struct asn1p_type_tag_s el_tag;
@ -143,8 +144,8 @@ asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
OUT("\t");
out_name_chain(arg, ONC_noflags);
OUT("_%s", MKID(v));
OUT("\t= %" PRIdASN "%s\n",
v->value->value.v_integer,
OUT("\t= %s%s\n",
asn1p_itoa(v->value->value.v_integer),
(eidx+1 < el_count) ? "," : "");
v2e[eidx].name = v->Identifier;
v2e[eidx].value = v->value->value.v_integer;
@ -184,8 +185,8 @@ asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byValue);
for(eidx = 0; eidx < el_count; eidx++) {
v2e[eidx].idx = eidx;
OUT("\t{ %" PRIdASN ",\t%ld,\t\"%s\" }%s\n",
v2e[eidx].value,
OUT("\t{ %s,\t%ld,\t\"%s\" }%s\n",
asn1p_itoa(v2e[eidx].value),
(long)strlen(v2e[eidx].name), v2e[eidx].name,
(eidx + 1 < el_count) ? "," : "");
}
@ -197,10 +198,10 @@ asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
MKID(expr), expr->_type_unique_index);
qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byName);
for(eidx = 0; eidx < el_count; eidx++) {
OUT("\t%d%s\t/* %s(%" PRIdASN ") */\n",
OUT("\t%d%s\t/* %s(%s) */\n",
v2e[eidx].idx,
(eidx + 1 < el_count) ? "," : "",
v2e[eidx].name, v2e[eidx].value);
v2e[eidx].name, asn1p_itoa(v2e[eidx].value));
}
if(map_extensions)
OUT("\t/* This list is extensible */\n");
@ -282,8 +283,8 @@ asn1c_lang_C_type_BIT_STRING(arg_t *arg) {
OUT("\t");
out_name_chain(arg, ONC_noflags);
OUT("_%s", MKID(v));
OUT("\t= %" PRIdASN "%s\n",
v->value->value.v_integer,
OUT("\t= %s%s\n",
asn1p_itoa(v->value->value.v_integer),
(eidx < el_count) ? "," : "");
}
OUT("} e_");
@ -1628,7 +1629,7 @@ _print_tag(arg_t *arg, struct asn1p_type_tag_s *tag) {
case TC_NOCLASS:
break;
}
OUT(" | (%" PRIdASN " << 2))", tag->tag_value);
OUT(" | (%s << 2))", asn1p_itoa(tag->tag_value));
return 0;
}
@ -1993,12 +1994,12 @@ emit_single_member_OER_constraint_comment(arg_t *arg, asn1cnst_range_t *range, c
if(type) OUT("(%s", type);
OUT("(");
if(range->left.type == ARE_VALUE)
OUT("%" PRIdASN, range->left.value);
OUT("%s", asn1p_itoa(range->left.value));
else
OUT("MIN");
OUT("..");
if(range->right.type == ARE_VALUE)
OUT("%" PRIdASN, range->right.value);
OUT("%s", asn1p_itoa(range->right.value));
else
OUT("MAX");
if(range->extensible) OUT(",...");
@ -2073,7 +2074,7 @@ emit_single_member_OER_constraint_size(arg_t *arg, asn1cnst_range_t *range) {
if(range->left.type == ARE_VALUE && range->right.type == ARE_VALUE
&& range->left.value == range->right.value
&& range->left.value >= 0) {
OUT("%" PRIdASN "", range->left.value);
OUT("%s", asn1p_itoa(range->left.value));
} else {
OUT("-1");
}
@ -2183,12 +2184,12 @@ emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alpha
if(type) OUT("(%s", type);
OUT("(");
if(range->left.type == ARE_VALUE)
OUT("%" PRIdASN, range->left.value);
OUT("%s", asn1p_itoa(range->left.value));
else
OUT("MIN");
OUT("..");
if(range->right.type == ARE_VALUE)
OUT("%" PRIdASN, range->right.value);
OUT("%s", asn1p_itoa(range->right.value));
else
OUT("MAX");
if(range->extensible) OUT(",...");
@ -2462,17 +2463,17 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
if(fits_long && !expr->marker.default_value->value.v_integer)
expr->marker.flags &= ~EM_INDIRECT;
if(!out) {
OUT("asn_DFL_%d_set_%" PRIdASN
",\t/* DEFAULT %" PRIdASN " */\n",
OUT("asn_DFL_%d_set_%s,",
expr->_type_unique_index,
expr->marker.default_value->value.v_integer,
expr->marker.default_value->value.v_integer);
asn1p_itoa(expr->marker.default_value->value.v_integer));
OUT("\t/* DEFAULT %s */\n",
asn1p_itoa(expr->marker.default_value->value.v_integer));
return 1;
}
REDIR(OT_STAT_DEFS);
OUT("static int asn_DFL_%d_set_%" PRIdASN "(int set_value, void **sptr) {\n",
OUT("static int asn_DFL_%d_set_%s(int set_value, void **sptr) {\n",
expr->_type_unique_index,
expr->marker.default_value->value.v_integer);
asn1p_itoa(expr->marker.default_value->value.v_integer));
INDENT(+1);
OUT("%s *st = *sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
OUT("\n");
@ -2484,8 +2485,8 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
OUT("\n");
OUT("if(set_value) {\n");
INDENT(+1);
OUT("/* Install default value %" PRIdASN " */\n",
expr->marker.default_value->value.v_integer);
OUT("/* Install default value %s */\n",
asn1p_itoa(expr->marker.default_value->value.v_integer));
if(fits_long) {
OUT("*st = ");
OINT(expr->marker.default_value->value.v_integer);
@ -2499,17 +2500,17 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
INDENT(-1);
OUT("} else {\n");
INDENT(+1);
OUT("/* Test default value %" PRIdASN " */\n",
expr->marker.default_value->value.v_integer);
OUT("/* Test default value %s */\n",
asn1p_itoa(expr->marker.default_value->value.v_integer));
if(fits_long) {
OUT("return (*st == %" PRIdASN ");\n",
expr->marker.default_value->value.v_integer);
OUT("return (*st == %s);\n",
asn1p_itoa(expr->marker.default_value->value.v_integer));
} else {
OUT("long value;\n");
OUT("if(asn_INTEGER2long(st, &value))\n");
OUT("\treturn -1;\n");
OUT("return (value == %" PRIdASN ");\n",
expr->marker.default_value->value.v_integer);
OUT("return (value == %s);\n",
asn1p_itoa(expr->marker.default_value->value.v_integer));
}
INDENT(-1);
OUT("}\n");

View File

@ -125,18 +125,20 @@ int asn1c_compiled_output(arg_t *arg, const char *fmt, ...);
/*
* Format LONG_MIN according to C90 rules.
*/
#define OINT(iv) do { \
if(iv == (-2147483647L - 1)) \
OUT("(-2147483647L - 1)"); \
else \
OUT("%" PRIdASN, iv); \
} while(0)
#define OINT(iv) \
do { \
if(iv == (-2147483647L - 1)) \
OUT("(-2147483647L - 1)"); \
else \
OUT("%s", asn1p_itoa(iv)); \
} while(0)
#define OINTS(iv) do { \
if(iv == (-2147483647L - 1)) \
OUT("(-2147483647L - 1)"); \
else \
OUT("% " PRIdASN, iv); \
} while(0)
#define OINTS(iv) \
do { \
if(iv == (-2147483647L - 1)) \
OUT("(-2147483647L - 1)"); \
else \
OUT("%s%s", (iv >= 0) ? " " : "", asn1p_itoa(iv)); \
} while(0)
#endif /* ASN1_COMPILED_OUTPUT_H */

View File

@ -157,7 +157,7 @@ _edge_value(const asn1cnst_edge_t *edge) {
case ARE_MIN: strcpy(buf, "MIN"); break;
case ARE_MAX: strcpy(buf, "MAX"); break;
case ARE_VALUE:
snprintf(buf, sizeof(buf), "%" PRIdASN, edge->value);
snprintf(buf, sizeof(buf), "%s", asn1p_itoa(edge->value));
break;
default:
assert(!"edge->type");
@ -258,9 +258,9 @@ static int _range_fill(asn1p_value_t *val, const asn1cnst_range_t *minmax, asn1c
switch(val->type) {
case ATV_INTEGER:
if(type != ACT_EL_RANGE && type != ACT_CT_SIZE) {
FATAL("Integer %" PRIdASN " value invalid "
FATAL("Integer %s value invalid "
"for %s constraint at line %d",
val->value.v_integer,
asn1p_itoa(val->value.v_integer),
asn1p_constraint_type2str(type), lineno);
return -1;
}

View File

@ -115,16 +115,19 @@ asn1f_fix_enum(arg_t *arg) {
if (eval > max_value_ext) {
max_value_ext = eval;
} else {
FATAL(
char max_value_buf[128];
asn1p_itoa_s(max_value_buf, sizeof(max_value_buf),
max_value_ext);
FATAL(
"Enumeration %s at line %d: "
"Explicit value \"%s(%" PRIdASN ")\" "
"Explicit value \"%s(%s)\" "
"is not greater "
"than previous values (max %" PRIdASN ")",
"than previous values (max %s)",
expr->Identifier,
ev->_lineno,
ev->Identifier,
eval,
max_value_ext);
asn1p_itoa(eval),
max_value_buf);
rvalue = -1;
}
}
@ -143,12 +146,12 @@ asn1f_fix_enum(arg_t *arg) {
if (used_vals[uv_idx] == eval) {
FATAL(
"Enumeration %s at line %d: "
"Explicit value \"%s(%" PRIdASN ")\" "
"Explicit value \"%s(%s)\" "
"collides with previous values",
expr->Identifier,
ev->_lineno,
ev->Identifier,
eval);
asn1p_itoa(eval));
rvalue = -1;
unique = 0;
}

View File

@ -50,8 +50,7 @@ asn1f_printable_value(asn1p_value_t *v) {
memcpy(buf + sizeof(buf) - 4, "...", 4);
return buf;
case ATV_INTEGER:
ret = snprintf(buf, sizeof(buf), "%" PRIdASN,
v->value.v_integer);
ret = snprintf(buf, sizeof(buf), "%s", asn1p_itoa(v->value.v_integer));
if(ret >= (ssize_t)sizeof(buf))
memcpy(buf + sizeof(buf) - 4, "...", 4);
return buf;

View File

@ -19,6 +19,7 @@ libasn1parser_la_SOURCES = \
asn1p_param.c asn1p_param.h \
asn1p_class.c asn1p_class.h \
asn1p_ref.c asn1p_ref.h \
asn1p_integer.c asn1p_integer.h \
asn1p_list.h
asn1parser.h: asn1p_expr_str.h

View File

@ -312,7 +312,7 @@ char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *buf) {
break;
}
buf += snprintf(buf + strlen(buf), end - buf,
"%" PRIdASN "]", tag->tag_value);
"%s]", asn1p_itoa(tag->tag_value));
assert((unsigned int)(buf - end) > sizeof(" IMPLICIT "));
switch(tag->tag_mode) {

View File

@ -0,0 +1,165 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <assert.h>
#include <errno.h>
#include "asn1p_integer.h"
#define ASN_INTEGER_MAX \
(~((asn1c_integer_t)0) \
& ~((asn1c_integer_t)1 << (8 * sizeof(asn1c_integer_t) - 1)))
#define ASN_INTEGER_MIN (-(ASN_INTEGER_MAX)-1)
/*
* Parse the number in the given string until the given *end position,
* returning the position after the last parsed character back using the
* same (*end) pointer.
* WARNING: This behavior is different from the standard strtol/strtoimax(3).
*/
enum strtox_result_e {
STRTOX_ERROR_RANGE = -3, /* Input outside of supported numeric range */
STRTOX_ERROR_INVAL = -2, /* Invalid data encountered (e.g., "+-") */
STRTOX_EXPECT_MORE = -1, /* More data expected (e.g. "+") */
STRTOX_OK = 0, /* Conversion succeded, number ends at (*end) */
STRTOX_EXTRA_DATA =
1 /* Conversion succeded, but the string has extra stuff */
};
static enum strtox_result_e
strtoaint_lim(const char *str, const char **end, asn1c_integer_t *intp) {
const asn1c_integer_t upper_boundary = ASN_INTEGER_MAX / 10;
int last_digit_max = ASN_INTEGER_MAX % 10;
int sign = 1;
asn1c_integer_t value;
if(str >= *end) return STRTOX_ERROR_INVAL;
switch(*str) {
case '-':
last_digit_max++;
sign = -1;
/* FALL THROUGH */
case '+':
str++;
if(str >= *end) {
*end = str;
return STRTOX_EXPECT_MORE;
}
}
for(value = 0; str < (*end); str++) {
switch(*str) {
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: {
int d = *str - '0';
if(value < upper_boundary) {
value = value * 10 + d;
} else if(value == upper_boundary) {
if(d <= last_digit_max) {
if(sign > 0) {
value = value * 10 + d;
} else {
sign = 1;
value = -value * 10 - d;
}
} else {
*end = str;
return STRTOX_ERROR_RANGE;
}
} else {
*end = str;
return STRTOX_ERROR_RANGE;
}
}
continue;
default:
*end = str;
*intp = sign * value;
return STRTOX_EXTRA_DATA;
}
}
*end = str;
*intp = sign * value;
return STRTOX_OK;
}
int
asn1p_atoi(const char *ptr, asn1c_integer_t *value) {
const char *end = ptr + strlen(ptr);
if(strtoaint_lim(ptr, &end, value) == STRTOX_OK) {
return 0;
} else {
return -1;
}
}
const char *asn1p_itoa(asn1c_integer_t v) {
static char static_buf[128];
int ret = asn1p_itoa_s(static_buf, sizeof(static_buf), v);
if(ret > 0) {
assert(ret < sizeof(static_buf));
return static_buf;
} else {
return NULL;
}
}
int asn1p_itoa_s(char *buf, size_t size, asn1c_integer_t v) {
char tmp_buf[128];
if(v >= LONG_MIN && v < LONG_MAX) {
int ret = snprintf(buf, size, "%ld", (long)v);
if(ret < 0 || ret >= size) {
return -1;
}
return ret;
}
int sign = 0;
if(v < 0) {
if(v == ASN_INTEGER_MIN) {
switch(sizeof(v)) {
case 16:
if(size < 41)
return -1;
memcpy(buf, "-170141183460469231731687303715884105729", 41);
return 41;
case 8:
if(size < 21)
return -1;
memcpy(buf, "-9223372036854775809", 21);
return 21;
default:
assert(!"unreachable");
}
}
sign = -1;
v = -v; /* Ditch the sign */
}
assert(v > 1000000000L);
char restbuf[10] = "000000000\0";
const char *rest = asn1p_itoa((long)(v % 1000000000L));
size_t restlen = strlen(rest);
assert(restlen <= 9);
memcpy(restbuf + (9 - restlen), rest, restlen);
rest = restbuf;
const char *head = asn1p_itoa(v / 1000000000L);
assert(head);
int ret = snprintf(tmp_buf, sizeof(tmp_buf), "%s%s%s", sign ? "-" : "",
head, rest);
assert(ret > 0 && ret < sizeof(tmp_buf));
if(size <= ret)
return -1;
memcpy(buf, tmp_buf, ret);
buf[ret] = '\0';
return ret;
}

View File

@ -0,0 +1,45 @@
#ifndef ASN1P_INTEGER_H
#define ASN1P_INTEGER_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif /* HAVE_SYS_TYPES_H */
#ifdef HAVE_INTTYPES_H
#include <inttypes.h> /* POSIX 1003.1-2001, C99 */
#else /* HAVE_INTTYPES_H */
#ifdef HAVE_STDINT_H
#include <stdint.h> /* SUSv2+ */
#endif /* HAVE_STDINT_H */
#endif /* HAVE_INTTYPES_H */
/*
* Basic integer type used in numerous places.
* ASN.1 does not define any limits on this number, so it must be sufficiently
* large to accomodate typical inputs. It does not have to be a dynamically
* allocated type with potentially unlimited width: consider the width of
* an integer defined here as one of the "compiler limitations".
* NOTE: this is NOT a type for ASN.1 "INTEGER" type representation, this
* type is used by the compiler itself to handle large integer values
* specified inside ASN.1 grammar.
*/
#ifdef HAVE_128_BIT_INT
typedef __int128 asn1c_integer_t;
#else
typedef intmax_t asn1c_integer_t;
#endif
int asn1p_atoi(const char *ptr, asn1c_integer_t *r_value);
const char *asn1p_itoa(asn1c_integer_t value); /* Ptr to a static buf */
/*
* Return values:
* -1: The value did not fit in the buffer.
* >0: The length in bytes of the stringified numeric value.
*/
int asn1p_itoa_s(char *buf, size_t size,
asn1c_integer_t value); /* Return -1 on error, or length. */
#endif /* ASN1P_INTEGER_H */

View File

@ -165,23 +165,3 @@ _asn1p_fix_modules(asn1p_t *a, const char *fname) {
}
return 0;
}
int
asn1p_atoi(const char *ptr, asn1c_integer_t *value) {
errno = 0; /* Clear the error code */
if(sizeof(*value) <= sizeof(int)) {
*value = strtol(ptr, 0, 10);
} else {
#ifdef HAVE_STRTOIMAX
*value = strtoimax(ptr, 0, 10);
#elif HAVE_STRTOLL
*value = strtoll(ptr, 0, 10);
#else
*value = strtol(ptr, 0, 10);
#endif
}
return errno == 0 ? 0 : -1;
}

View File

@ -8,36 +8,7 @@
#include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif /* HAVE_SYS_TYPES_H */
#ifdef HAVE_INTTYPES_H
#include <inttypes.h> /* POSIX 1003.1-2001, C99 */
#else /* HAVE_INTTYPES_H */
#ifdef HAVE_STDINT_H
#include <stdint.h> /* SUSv2+ */
#endif /* HAVE_STDINT_H */
#endif /* HAVE_INTTYPES_H */
/*
* Basic integer type used in numerous places.
* ASN.1 does not define any limits on this number, so it must be sufficiently
* large to accomodate typical inputs. It does not have to be a dynamically
* allocated type with potentially unlimited width: consider the width of
* an integer defined here as one of the "compiler limitations".
* NOTE: this is NOT a type for ASN.1 "INTEGER" type representation, this
* type is used by the compiler itself to handle large integer values
* specified inside ASN.1 grammar.
*/
typedef intmax_t asn1c_integer_t;
#ifdef PRIdMAX
#define PRIdASN PRIdMAX
#define PRIuASN PRIuMAX
#else
#define PRIdASN "lld" /* Or j? */
#define PRIuASN "llu" /* Or j? */
#endif
#include "asn1p_integer.h"
#include "asn1p_list.h"
#include "asn1p_oid.h" /* Object identifiers (OIDs) */
#include "asn1p_module.h" /* ASN.1 definition module */
@ -69,7 +40,6 @@ asn1p_t *asn1p_parse_file(const char *filename,
asn1p_t *asn1p_parse_buffer(const char *buffer, int size /* = -1 */,
enum asn1p_flags);
int asn1p_atoi(const char *ptr, asn1c_integer_t *r_value);
int asn1p_lex_destroy();
#endif /* ASN1PARSER_H */

View File

@ -156,11 +156,11 @@ asn1print_oid(int prior_len, asn1p_oid_t *oid, enum asn1print_flags flags) {
if(arcname) {
accum += safe_printf("%s", arcname);
if(oid->arcs[ac].number >= 0) {
accum += safe_printf("(%" PRIdASN ")",
oid->arcs[ac].number);
accum += safe_printf("(%s)",
asn1p_itoa(oid->arcs[ac].number));
}
} else {
accum += safe_printf("%" PRIdASN, oid->arcs[ac].number);
accum += safe_printf("%s", asn1p_itoa(oid->arcs[ac].number));
}
}
safe_printf(" }");
@ -214,7 +214,7 @@ asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
val->value.v_type, flags, 0);
return 0;
case ATV_INTEGER:
safe_printf("%" PRIdASN, val->value.v_integer);
safe_printf("%s", asn1p_itoa(val->value.v_integer));
return 0;
case ATV_MIN: safe_printf("MIN"); return 0;
case ATV_MAX: safe_printf("MAX"); return 0;
@ -476,7 +476,7 @@ asn1print_crange_value(asn1cnst_edge_t *edge, int as_char) {
if(as_char) {
safe_printf("\"%c\"", (unsigned char)edge->value);
} else {
safe_printf("%" PRIdASN, edge->value);
safe_printf("%s", asn1p_itoa(edge->value));
}
}
return 0;