use RMAX= in test-random/bundles to test larger randomized values (default max limit is 128 bytes)

This commit is contained in:
Lev Walkin 2017-10-02 16:24:28 -07:00
parent ceae6ed514
commit 791d3b7725
4 changed files with 80 additions and 27 deletions

View File

@ -16,11 +16,11 @@ T ::= VisibleString (SIZE(1..127))
T ::= VisibleString (SIZE(1..128))
T ::= VisibleString (SIZE(1..129))
T ::= VisibleString (SIZE(5) INTERSECTION FROM("A".."Z"))
T ::= VisibleString (SIZE(64000)) -- Length is not encoded, #11.9.3.3
T ::= VisibleString (SIZE(32000..32002))
T ::= VisibleString (SIZE(32000..32002)) (FROM("A".."B"))
T ::= VisibleString (SIZE(32000..32002,...)) (FROM("A".."B"))
T ::= VisibleString (SIZE(65530..65535))
T ::= VisibleString (SIZE(65530..65536))
RMAX=64000 VisibleString (SIZE(64000)) -- Length is not encoded, #11.9.3.3
RMAX=33000 T ::= VisibleString (SIZE(32000..32002))
RMAX=33000 T ::= VisibleString (SIZE(32000..32002)) (FROM("A".."B"))
RMAX=33000 T ::= VisibleString (SIZE(32000..32002,...)) (FROM("A".."B"))
RMAX=65536 T ::= VisibleString (SIZE(65530..65535))
RMAX=65536 T ::= VisibleString (SIZE(65530..65536))
T ::= VisibleString (SIZE(4..6) INTERSECTION (FROM("A".."B")))
T ::= VisibleString (SIZE(4..6,...) INTERSECTION (FROM("A".."B")))

View File

@ -0,0 +1,22 @@
This directory contains test bundles for randomized testing.
Each file contains a number of related ASN.1 types with variations in
contstraints that are intended to affect encoding and parsing.
* Lines consisting of comments only are ignored.
* The ASN.1 type can be written with "T ::=" prefix or without it, in which
case it will be added automatically. It is done to simplify manual
testing with ./check-bundles.sh -t <type>. For example,
./check-bundles.sh -t INTEGER
is equivalent to
./check-bundles.sh -t "T ::= INTEGER"
* By default, the random value generator attempts to generate values
limited to very roughly to around 128 bytes. If huge values are desired
(perhaps due to large constraints), the RMAX=<size> prefix can be specified
on a line:
RMAX=64000 T ::= VisibleString (SIZE(64000))

View File

@ -66,7 +66,7 @@ verify_asn_type() {
echo "Testing [$asn] ${where}"
mkdir -p ${RNDTEMP}
if (set -e && cd ${RNDTEMP} && compile_and_test "$asn" "$@"); then
if (set -e && cd ${RNDTEMP} && compile_and_test "$asn" "${where}"); then
echo "OK [$asn] ${where}"
tests_succeeded=$((tests_succeeded+1))
else
@ -79,7 +79,7 @@ compile_and_test() {
local asn="$1"
shift
if ! asn_compile "$asn" "$@"; then
if ! asn_compile "$asn" "$*"; then
echo "Cannot compile ASN.1 $asn"
return 1
fi
@ -91,17 +91,21 @@ compile_and_test() {
return 2
fi
# Maximum size of the random data
local rmax=$(echo "$asn" | sed -Ee '/RMAX/!d;s/.*RMAX=([0-9]+).*/\1/')
if [ "0${rmax}" -lt 1 ]; then rmax=128; fi
echo "Checking random data encode-decode"
if ! eval ${ASAN_ENV_FLAGS} ./random-test-driver -c; then
if ! eval ${ASAN_ENV_FLAGS} ./random-test-driver -s ${rmax} -c; then
echo "RETRY:"
echo "(cd ${RNDTEMP} && CC=${CC} CFLAGS=\"${LIBFUZZER_CFLAGS} ${CFLAGS}\" make && ${ASAN_ENV_FLAGS} ./random-test-driver -c)"
echo "(cd ${RNDTEMP} && CC=${CC} CFLAGS=\"${LIBFUZZER_CFLAGS} ${CFLAGS}\" make && ${ASAN_ENV_FLAGS} ./random-test-driver -s ${rmax} -c)"
return 3
fi
echo "Generating new random data"
rm -rf random-data
cmd="${ASAN_ENV_FLAGS} UBSAN_OPTIONS=print_stacktrace=1"
cmd+=" ./random-test-driver -g random-data"
cmd+=" ./random-test-driver -s ${rmax} -g random-data"
if ! eval "$cmd" ; then
echo "RETRY:"
echo "(cd ${RNDTEMP} && $cmd)"
@ -144,14 +148,16 @@ asn_compile() {
local asn="$1"
shift
# Create "INTEGER (1..2)" from "T ::= INTEGER (1..2) -- Comment"
local short_asn=$(echo "$asn" | sed -e 's/ *--.*//')
# Create "INTEGER (1..2)" from "RMAX=5 T ::= INTEGER (1..2) -- Comment"
local short_asn=$(echo "$asn" | sed -e 's/ *--.*//;s/RMAX=[^ ]* //;')
if [ $(echo "$short_asn" | grep -c "::=") = 1 ]; then
short_asn=$(echo "$short_asn" | sed -e 's/.*::= *//')
fi
asn=$(echo "$asn" | sed -e 's/RMAX=[^ ]* //;')
test ! -f Makefile.am # Protection from accidental clobbering
echo "Test DEFINITIONS ::= BEGIN $asn" > test.asn1
echo "-- $*" >> test.asn1
echo "END" >> test.asn1
if ! ${abs_top_builddir}/asn1c/asn1c -S ${abs_top_srcdir}/skeletons \
-gen-OER -gen-PER test.asn1

View File

@ -84,6 +84,7 @@ usage(const char *progname) {
"OPTIONS:\n"
" -c Check encode-decode round-trip on random data\n"
" -g <dir> Generate random data for selected encodings\n"
" -s <size> Approximate max random value size for -c and -g\n"
" -n <number> Number of iterations for -c and -g\n"
" -e <encoding> Encodings to test or generate random data for\n"
"Encodings (ASN.1 Transfer Syntaxes):\n"
@ -101,7 +102,7 @@ file_write_cb(const void *data, size_t size, void *key) {
}
static void
generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, int iterations) {
generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, size_t max_random_value_size, int iterations, int debug) {
char dirname[PATH_MAX];
size_t dirname_len = 0;
dirname[dirname_len] = '\0';
@ -142,7 +143,9 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i
snprintf(&dirname[dirname_len], sizeof(dirname) - dirname_len,
"/%03d.bin", i);
if(asn_random_fill(&asn_DEF_T, (void **)&structure, 128) == -1) {
if(asn_random_fill(&asn_DEF_T, (void **)&structure,
max_random_value_size)
== -1) {
assert(structure == 0);
fprintf(stderr, "Can't generate %d'th value, skipping\n", i);
continue;
@ -169,11 +172,13 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i
exit(EX_SOFTWARE);
}
if(i < 5) {
fprintf(stderr, "[%s] ", &filename[dirname_len+1]);
asn_fprint(stderr, &asn_DEF_T, structure);
} else if(i == 5) {
fprintf(stderr, "... and so on\n");
if(debug) {
if(i < 5 || debug > 1) {
fprintf(stderr, "[%s] ", &filename[dirname_len+1]);
asn_fprint(stderr, &asn_DEF_T, structure);
} else if(i == 5) {
fprintf(stderr, "... and so on\n");
}
}
ASN_STRUCT_FREE(asn_DEF_T, structure);
@ -189,7 +194,7 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i
}
static void
check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
check_random_roundtrip(enum asn_transfer_syntax syntax, size_t max_random_value_size, int iterations, int debug) {
struct encoding_map enc;
for(size_t i = 0; i < sizeof(encodings)/sizeof(encodings[0]); i++) {
@ -208,7 +213,9 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
T_t *structure = 0;
T_t *decoded_structure = 0;
if(asn_random_fill(&asn_DEF_T, (void **)&structure, 128) == -1) {
if(asn_random_fill(&asn_DEF_T, (void **)&structure,
max_random_value_size)
== -1) {
assert(structure == 0);
fprintf(stderr, "Can't generate %d'th value, skipping\n", i);
continue;
@ -228,8 +235,12 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
exit(EX_SOFTWARE);
}
if(er.encoded > buffer_size && buffer == tmp_buffer) {
fprintf(stderr, "Reallocate output buffer %zu -> %zu\n",
buffer_size, er.encoded);
if(debug) {
fprintf(
stderr,
"Reallocate output buffer %zu -> %zu (iteration %d)\n",
buffer_size, er.encoded, i);
}
buffer = malloc(er.encoded + 1);
assert(buffer);
buffer[er.encoded] = '\0';
@ -307,13 +318,18 @@ int main(int argc, char **argv) {
} mode = MODE_UNKNOWN;
const char *generate_into_dir = NULL;
int iterations = 100;
size_t max_random_value_size = 128;
int debug = 0;
int c;
while((c = getopt(argc, argv, "ce:g:hn:")) != -1) {
while((c = getopt(argc, argv, "cde:g:hn:s:")) != -1) {
switch(c) {
case 'c':
mode = MODE_CHECK_RANDOM_ROUNDTRIP;
break;
case 'd':
debug = 1;
break;
case 'e':
enabled_encodings |= 1 << lookup_syntax(optarg);
if(enabled_encodings & (1 << ATS_INVALID)) {
@ -336,6 +352,13 @@ int main(int argc, char **argv) {
exit(EX_DATAERR);
}
break;
case 's':
if(atoi(optarg) <= 0) {
fprintf(stderr, "-s %s: positive value expected\n", optarg);
exit(EX_DATAERR);
}
max_random_value_size = atoi(optarg);
break;
default:
usage(argv[0]);
exit(2);
@ -360,10 +383,12 @@ int main(int argc, char **argv) {
assert(mode != MODE_UNKNOWN);
break;
case MODE_GENERATE_RANDOM_DATA:
generate_random_data(syntax, generate_into_dir, iterations);
generate_random_data(syntax, generate_into_dir,
max_random_value_size, iterations, debug);
break;
case MODE_CHECK_RANDOM_ROUNDTRIP:
check_random_roundtrip(syntax, iterations);
check_random_roundtrip(syntax, max_random_value_size,
iterations, debug);
break;
}
}