format integer value as INTEGER_t
diff --git a/.gitignore b/.gitignore
index da6ad78..e8d6665 100644
--- a/.gitignore
+++ b/.gitignore
@@ -89,7 +89,7 @@
/libasn1fix/check_*
# /libasn1parser/
-/libasn1parser/check_parser
+/libasn1parser/check_*
#code coverage
*.gcno
diff --git a/asn1c/Makefile.am b/asn1c/Makefile.am
index b3a1009..40f000f 100644
--- a/asn1c/Makefile.am
+++ b/asn1c/Makefile.am
@@ -17,6 +17,9 @@
$(top_builddir)/libasn1fix/libasn1fix.la \
$(top_builddir)/libasn1compiler/libasn1compiler.la
+unber_LDADD = \
+ $(top_builddir)/libasn1common/libasn1common.la
+
bin_PROGRAMS = asn1c unber enber
noinst_HEADERS = sys-common.h
diff --git a/libasn1parser/Makefile.am b/libasn1parser/Makefile.am
index 9b53233..ed106eb 100644
--- a/libasn1parser/Makefile.am
+++ b/libasn1parser/Makefile.am
@@ -23,6 +23,12 @@
asn1p_integer.c asn1p_integer.h \
asn1p_list.h
+check_PROGRAMS = check_asn1p_integer
+
+LDADD = ../libasn1common/libasn1common.la libasn1parser.la
+
+TESTS = $(check_PROGRAMS)
+
asn1parser.h: asn1p_expr_str.h
asn1p_expr_str.h: expr-h.pl asn1p_expr.h
diff --git a/libasn1parser/asn1p_integer.c b/libasn1parser/asn1p_integer.c
index 97e6465..64d39db 100644
--- a/libasn1parser/asn1p_integer.c
+++ b/libasn1parser/asn1p_integer.c
@@ -164,3 +164,25 @@
return ret;
}
+abuf *
+asn1p_integer_as_INTEGER(asn1c_integer_t value) {
+ abuf *ab = abuf_new();
+ uint8_t buf[sizeof(value) + 1];
+ uint8_t *bp = buf;
+
+ do {
+ *bp++ = value;
+ value >>= 8;
+ } while(!((value == 0 && !(bp[-1] & 0x80))
+ || (value == -1 && (bp[-1] & 0x80))));
+
+ abuf_printf(ab, "{ (uint8_t *)\"");
+
+ for(const uint8_t *p = bp-1; p >= buf; p--) {
+ abuf_printf(ab, "\\x%02x", *p);
+ }
+
+ abuf_printf(ab, "\\0\", %zu }", bp - buf);
+
+ return ab;
+}
diff --git a/libasn1parser/asn1p_integer.h b/libasn1parser/asn1p_integer.h
index 7cd6058..346c025 100644
--- a/libasn1parser/asn1p_integer.h
+++ b/libasn1parser/asn1p_integer.h
@@ -5,6 +5,8 @@
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#include <asn1_buffer.h>
+
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif /* HAVE_SYS_TYPES_H */
@@ -42,4 +44,9 @@
int asn1p_itoa_s(char *buf, size_t size,
asn1c_integer_t value); /* Return -1 on error, or length. */
+/*
+ * Convert asn1c_integer_t into INTEGER_t structure.
+ */
+abuf *asn1p_integer_as_INTEGER(asn1c_integer_t value);
+
#endif /* ASN1P_INTEGER_H */
diff --git a/libasn1parser/check_asn1p_integer.c b/libasn1parser/check_asn1p_integer.c
new file mode 100644
index 0000000..cb479ff
--- /dev/null
+++ b/libasn1parser/check_asn1p_integer.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "asn1p_integer.h"
+
+static void check(int lineno, asn1c_integer_t value, const char *expected);
+
+struct {
+ uint8_t *buf; size_t size;
+} ff = {
+ (uint8_t *)"sdf", 3
+};
+
+int main() {
+
+ check(__LINE__, 0, "{ (uint8_t *)\"\\x00\\0\", 1 }");
+ check(__LINE__, 1, "{ (uint8_t *)\"\\x01\\0\", 1 }");
+ check(__LINE__, 127, "{ (uint8_t *)\"\\x7f\\0\", 1 }");
+ check(__LINE__, 128, "{ (uint8_t *)\"\\x00\\x80\\0\", 2 }");
+ check(__LINE__, 129, "{ (uint8_t *)\"\\x00\\x81\\0\", 2 }");
+
+ check(__LINE__, -1, "{ (uint8_t *)\"\\xff\\0\", 1 }");
+ check(__LINE__, -2, "{ (uint8_t *)\"\\xfe\\0\", 1 }");
+ check(__LINE__, -127, "{ (uint8_t *)\"\\x81\\0\", 1 }");
+ check(__LINE__, -128, "{ (uint8_t *)\"\\x80\\0\", 1 }");
+ check(__LINE__, -129, "{ (uint8_t *)\"\\xff\\x7f\\0\", 2 }");
+ check(__LINE__, -254, "{ (uint8_t *)\"\\xff\\x02\\0\", 2 }");
+ check(__LINE__, -255, "{ (uint8_t *)\"\\xff\\x01\\0\", 2 }");
+ check(__LINE__, -256, "{ (uint8_t *)\"\\xff\\x00\\0\", 2 }");
+ check(__LINE__, -257, "{ (uint8_t *)\"\\xfe\\xff\\0\", 2 }");
+
+ check(__LINE__, ~(asn1c_integer_t)0, "{ (uint8_t *)\"\\xff\\0\", 1 }");
+
+ switch(sizeof(asn1c_integer_t)) {
+ case 4:
+ check(__LINE__,
+ ~(asn1c_integer_t)0
+ & ~((asn1c_integer_t)1 << (8 * sizeof(asn1c_integer_t) - 1)),
+ "{ (uint8_t *)\""
+ "\\x7f\\xff\\xff\\xff"
+ "\\0\", 4 }");
+ break;
+ case 8:
+ check(__LINE__,
+ ~(asn1c_integer_t)0
+ & ~((asn1c_integer_t)1 << (8 * sizeof(asn1c_integer_t) - 1)),
+ "{ (uint8_t *)\""
+ "\\x7f\\xff\\xff\\xff\\xff\\xff\\xff\\xff"
+ "\\0\", 8 }");
+ break;
+ case 16:
+ check(__LINE__,
+ ~(asn1c_integer_t)0
+ & ~((asn1c_integer_t)1 << (8 * sizeof(asn1c_integer_t) - 1)),
+ "{ (uint8_t *)\""
+ "\\x7f\\xff\\xff\\xff\\xff\\xff\\xff\\xff"
+ "\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff"
+ "\\0\", 16 }");
+
+ break;
+ default:
+ assert(!"Unreachable");
+ }
+
+ return 0;
+}
+
+static void check(int lineno, asn1c_integer_t value, const char *expected) {
+ abuf *ab;
+ ab = asn1p_integer_as_INTEGER(value);
+ assert(ab);
+ if(strcmp(ab->buffer, expected)) {
+ fprintf(stderr, "%02d: %s -> [%s], expected [%s]\n", lineno,
+ asn1p_itoa(value), ab->buffer, expected);
+ assert(strcmp(ab->buffer, expected) == 0);
+ }
+ printf("%02d: %s -> %s\n", lineno, asn1p_itoa(value), ab->buffer);
+ abuf_free(ab);
+}