Commit 791d3b77 authored by Lev Walkin's avatar Lev Walkin

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

parent ceae6ed5
...@@ -16,11 +16,11 @@ T ::= VisibleString (SIZE(1..127)) ...@@ -16,11 +16,11 @@ T ::= VisibleString (SIZE(1..127))
T ::= VisibleString (SIZE(1..128)) T ::= VisibleString (SIZE(1..128))
T ::= VisibleString (SIZE(1..129)) T ::= VisibleString (SIZE(1..129))
T ::= VisibleString (SIZE(5) INTERSECTION FROM("A".."Z")) T ::= VisibleString (SIZE(5) INTERSECTION FROM("A".."Z"))
T ::= VisibleString (SIZE(64000)) -- Length is not encoded, #11.9.3.3 RMAX=64000 VisibleString (SIZE(64000)) -- Length is not encoded, #11.9.3.3
T ::= VisibleString (SIZE(32000..32002)) RMAX=33000 T ::= VisibleString (SIZE(32000..32002))
T ::= VisibleString (SIZE(32000..32002)) (FROM("A".."B")) RMAX=33000 T ::= VisibleString (SIZE(32000..32002)) (FROM("A".."B"))
T ::= VisibleString (SIZE(32000..32002,...)) (FROM("A".."B")) RMAX=33000 T ::= VisibleString (SIZE(32000..32002,...)) (FROM("A".."B"))
T ::= VisibleString (SIZE(65530..65535)) RMAX=65536 T ::= VisibleString (SIZE(65530..65535))
T ::= VisibleString (SIZE(65530..65536)) 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")))
T ::= VisibleString (SIZE(4..6,...) INTERSECTION (FROM("A".."B"))) T ::= VisibleString (SIZE(4..6,...) INTERSECTION (FROM("A".."B")))
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))
...@@ -66,7 +66,7 @@ verify_asn_type() { ...@@ -66,7 +66,7 @@ verify_asn_type() {
echo "Testing [$asn] ${where}" echo "Testing [$asn] ${where}"
mkdir -p ${RNDTEMP} 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}" echo "OK [$asn] ${where}"
tests_succeeded=$((tests_succeeded+1)) tests_succeeded=$((tests_succeeded+1))
else else
...@@ -79,7 +79,7 @@ compile_and_test() { ...@@ -79,7 +79,7 @@ compile_and_test() {
local asn="$1" local asn="$1"
shift shift
if ! asn_compile "$asn" "$@"; then if ! asn_compile "$asn" "$*"; then
echo "Cannot compile ASN.1 $asn" echo "Cannot compile ASN.1 $asn"
return 1 return 1
fi fi
...@@ -91,17 +91,21 @@ compile_and_test() { ...@@ -91,17 +91,21 @@ compile_and_test() {
return 2 return 2
fi 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" 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 "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 return 3
fi fi
echo "Generating new random data" echo "Generating new random data"
rm -rf random-data rm -rf random-data
cmd="${ASAN_ENV_FLAGS} UBSAN_OPTIONS=print_stacktrace=1" 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 if ! eval "$cmd" ; then
echo "RETRY:" echo "RETRY:"
echo "(cd ${RNDTEMP} && $cmd)" echo "(cd ${RNDTEMP} && $cmd)"
...@@ -144,14 +148,16 @@ asn_compile() { ...@@ -144,14 +148,16 @@ asn_compile() {
local asn="$1" local asn="$1"
shift shift
# Create "INTEGER (1..2)" from "T ::= INTEGER (1..2) -- Comment" # Create "INTEGER (1..2)" from "RMAX=5 T ::= INTEGER (1..2) -- Comment"
local short_asn=$(echo "$asn" | sed -e 's/ *--.*//') local short_asn=$(echo "$asn" | sed -e 's/ *--.*//;s/RMAX=[^ ]* //;')
if [ $(echo "$short_asn" | grep -c "::=") = 1 ]; then if [ $(echo "$short_asn" | grep -c "::=") = 1 ]; then
short_asn=$(echo "$short_asn" | sed -e 's/.*::= *//') short_asn=$(echo "$short_asn" | sed -e 's/.*::= *//')
fi fi
asn=$(echo "$asn" | sed -e 's/RMAX=[^ ]* //;')
test ! -f Makefile.am # Protection from accidental clobbering test ! -f Makefile.am # Protection from accidental clobbering
echo "Test DEFINITIONS ::= BEGIN $asn" > test.asn1 echo "Test DEFINITIONS ::= BEGIN $asn" > test.asn1
echo "-- $*" >> test.asn1
echo "END" >> test.asn1 echo "END" >> test.asn1
if ! ${abs_top_builddir}/asn1c/asn1c -S ${abs_top_srcdir}/skeletons \ if ! ${abs_top_builddir}/asn1c/asn1c -S ${abs_top_srcdir}/skeletons \
-gen-OER -gen-PER test.asn1 -gen-OER -gen-PER test.asn1
......
...@@ -84,6 +84,7 @@ usage(const char *progname) { ...@@ -84,6 +84,7 @@ usage(const char *progname) {
"OPTIONS:\n" "OPTIONS:\n"
" -c Check encode-decode round-trip on random data\n" " -c Check encode-decode round-trip on random data\n"
" -g <dir> Generate random data for selected encodings\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" " -n <number> Number of iterations for -c and -g\n"
" -e <encoding> Encodings to test or generate random data for\n" " -e <encoding> Encodings to test or generate random data for\n"
"Encodings (ASN.1 Transfer Syntaxes):\n" "Encodings (ASN.1 Transfer Syntaxes):\n"
...@@ -101,7 +102,7 @@ file_write_cb(const void *data, size_t size, void *key) { ...@@ -101,7 +102,7 @@ file_write_cb(const void *data, size_t size, void *key) {
} }
static void 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]; char dirname[PATH_MAX];
size_t dirname_len = 0; size_t dirname_len = 0;
dirname[dirname_len] = '\0'; dirname[dirname_len] = '\0';
...@@ -142,7 +143,9 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i ...@@ -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, snprintf(&dirname[dirname_len], sizeof(dirname) - dirname_len,
"/%03d.bin", i); "/%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); assert(structure == 0);
fprintf(stderr, "Can't generate %d'th value, skipping\n", i); fprintf(stderr, "Can't generate %d'th value, skipping\n", i);
continue; continue;
...@@ -169,11 +172,13 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i ...@@ -169,11 +172,13 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i
exit(EX_SOFTWARE); exit(EX_SOFTWARE);
} }
if(i < 5) { if(debug) {
fprintf(stderr, "[%s] ", &filename[dirname_len+1]); if(i < 5 || debug > 1) {
asn_fprint(stderr, &asn_DEF_T, structure); fprintf(stderr, "[%s] ", &filename[dirname_len+1]);
} else if(i == 5) { asn_fprint(stderr, &asn_DEF_T, structure);
fprintf(stderr, "... and so on\n"); } else if(i == 5) {
fprintf(stderr, "... and so on\n");
}
} }
ASN_STRUCT_FREE(asn_DEF_T, structure); ASN_STRUCT_FREE(asn_DEF_T, structure);
...@@ -189,7 +194,7 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i ...@@ -189,7 +194,7 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i
} }
static void 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; struct encoding_map enc;
for(size_t i = 0; i < sizeof(encodings)/sizeof(encodings[0]); i++) { 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) { ...@@ -208,7 +213,9 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
T_t *structure = 0; T_t *structure = 0;
T_t *decoded_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); assert(structure == 0);
fprintf(stderr, "Can't generate %d'th value, skipping\n", i); fprintf(stderr, "Can't generate %d'th value, skipping\n", i);
continue; continue;
...@@ -228,8 +235,12 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { ...@@ -228,8 +235,12 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
exit(EX_SOFTWARE); exit(EX_SOFTWARE);
} }
if(er.encoded > buffer_size && buffer == tmp_buffer) { if(er.encoded > buffer_size && buffer == tmp_buffer) {
fprintf(stderr, "Reallocate output buffer %zu -> %zu\n", if(debug) {
buffer_size, er.encoded); fprintf(
stderr,
"Reallocate output buffer %zu -> %zu (iteration %d)\n",
buffer_size, er.encoded, i);
}
buffer = malloc(er.encoded + 1); buffer = malloc(er.encoded + 1);
assert(buffer); assert(buffer);
buffer[er.encoded] = '\0'; buffer[er.encoded] = '\0';
...@@ -307,13 +318,18 @@ int main(int argc, char **argv) { ...@@ -307,13 +318,18 @@ int main(int argc, char **argv) {
} mode = MODE_UNKNOWN; } mode = MODE_UNKNOWN;
const char *generate_into_dir = NULL; const char *generate_into_dir = NULL;
int iterations = 100; int iterations = 100;
size_t max_random_value_size = 128;
int debug = 0;
int c; int c;
while((c = getopt(argc, argv, "ce:g:hn:")) != -1) { while((c = getopt(argc, argv, "cde:g:hn:s:")) != -1) {
switch(c) { switch(c) {
case 'c': case 'c':
mode = MODE_CHECK_RANDOM_ROUNDTRIP; mode = MODE_CHECK_RANDOM_ROUNDTRIP;
break; break;
case 'd':
debug = 1;
break;
case 'e': case 'e':
enabled_encodings |= 1 << lookup_syntax(optarg); enabled_encodings |= 1 << lookup_syntax(optarg);
if(enabled_encodings & (1 << ATS_INVALID)) { if(enabled_encodings & (1 << ATS_INVALID)) {
...@@ -336,6 +352,13 @@ int main(int argc, char **argv) { ...@@ -336,6 +352,13 @@ int main(int argc, char **argv) {
exit(EX_DATAERR); exit(EX_DATAERR);
} }
break; 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: default:
usage(argv[0]); usage(argv[0]);
exit(2); exit(2);
...@@ -360,10 +383,12 @@ int main(int argc, char **argv) { ...@@ -360,10 +383,12 @@ int main(int argc, char **argv) {
assert(mode != MODE_UNKNOWN); assert(mode != MODE_UNKNOWN);
break; break;
case MODE_GENERATE_RANDOM_DATA: 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; break;
case MODE_CHECK_RANDOM_ROUNDTRIP: case MODE_CHECK_RANDOM_ROUNDTRIP:
check_random_roundtrip(syntax, iterations); check_random_roundtrip(syntax, max_random_value_size,
iterations, debug);
break; break;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment