generate constraints differently to avoid warnings

This commit is contained in:
Lev Walkin 2017-10-19 02:16:35 -07:00
parent 4bd9eaf7e1
commit bc09dd4845
14 changed files with 223 additions and 205 deletions

View File

@ -132,7 +132,7 @@ AC_ARG_ENABLE([test-32bit],
[Enable tests for 32-bit compatibility])],
[enable_test_32bit=$enableval], [enable_test_32bit=no])
AS_IF([test "x$enable_test_32bit" != xno], [
AX_CHECK_COMPILE_FLAG([-m32], [CFLAGS_M32=-m32],
AX_CHECK_COMPILE_FLAG([-m32], [CFLAGS_M32="-m32 -DEXPLICIT_32BIT"],
[
CFLAGS_M32=""
AC_MSG_FAILURE([--enable-test-32bit=$enable_test_32bit is requested but not supported by the _AC_LANG compiler])

View File

@ -12,7 +12,10 @@ static int emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range);
static int emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_range_t *r_value);
static int emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype);
static asn1p_expr_type_e _find_terminal_type(arg_t *arg);
static int emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1c_integer_t natural_start, asn1c_integer_t natural_stop);
static abuf *emit_range_comparison_code(asn1cnst_range_t *range,
const char *varname,
asn1c_integer_t natural_start,
asn1c_integer_t natural_stop);
static int native_long_sign(arg_t *arg, asn1cnst_range_t *r); /* -1, 0, 1 */
static int
@ -32,10 +35,10 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_type_e etype;
asn1p_constraint_t *ct;
int got_something = 0;
int alphabet_table_compiled;
int produce_st = 0;
int ulong_optimize = 0;
int value_unsigned = 0;
int ret = 0;
ct = expr->combined_constraints;
@ -109,6 +112,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
if(native_long_sign(arg, r_value) >= 0) {
ulong_optimize = ulong_optimization(arg, etype, r_size, r_value);
if(!ulong_optimize) {
value_unsigned = 1;
OUT("unsigned long value;\n");
}
} else {
@ -167,32 +171,42 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
/*
* Here is an if() {} else {} consrtaint checking code.
*/
int got_something = 0;
int value_unused = 0;
OUT("\n");
OUT("if(");
INDENT(+1);
if(r_size) {
if(got_something++) { OUT("\n"); OUT(" && "); }
OUT("(");
emit_range_comparison_code(arg, r_size, "size", 0, -1);
OUT(")");
abuf *ab = emit_range_comparison_code(r_size, "size", 0, -1);
if(ab->length) {
OUT("(%s)", ab->buffer);
got_something++;
}
abuf_free(ab);
}
if(r_value) {
if(got_something++) { OUT("\n"); OUT(" && "); }
OUT("(");
if(etype == ASN_BASIC_BOOLEAN)
emit_range_comparison_code(arg, r_value,
"value", 0, 1);
else
emit_range_comparison_code(arg, r_value,
"value", -1, -1);
OUT(")");
if(got_something) { OUT("\n"); OUT(" && "); }
abuf *ab;
if(etype == ASN_BASIC_BOOLEAN)
ab = emit_range_comparison_code(r_value, "value", 0, 1);
else
ab = emit_range_comparison_code(r_value, "value",
value_unsigned ? 0 : -1, -1);
if(ab->length) {
OUT("(%s)", ab->buffer);
got_something++;
} else {
value_unused = 1;
}
abuf_free(ab);
}
if(alphabet_table_compiled) {
if(got_something++) { OUT("\n"); OUT(" && "); }
if(got_something) { OUT("\n"); OUT(" && "); }
OUT("!check_permitted_alphabet_%d(%s)",
arg->expr->_type_unique_index,
produce_st ? "st" : "sptr");
}
got_something++;
}
if(!got_something) {
OUT("1 /* No applicable constraints whatsoever */");
OUT(") {\n");
@ -200,6 +214,9 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
if(produce_st) {
INDENTED(OUT("(void)st; /* Unused variable */\n"));
}
if(value_unused) {
INDENTED(OUT("(void)value; /* Unused variable */\n"));
}
INDENTED(OUT("/* Nothing is here. See below */\n"));
OUT("}\n");
OUT("\n");
@ -491,16 +508,11 @@ emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range) {
}
if(range) {
OUT("if(!(");
int produced_something =
emit_range_comparison_code(arg, range, "cv", 0, natural_stop);
if(produced_something) {
OUT(")) return -1;\n");
abuf *ab = emit_range_comparison_code(range, "cv", 0, natural_stop);
if(ab->length) {
OUT("if(!(%s)) return -1;\n", ab->buffer);
} else {
OUT(")) {\n");
OUT("\t(void)cv; /* Unused variable */\n");
OUT("\treturn -1;\n");
OUT("}\n");
OUT("(void)cv; /* Unused variable */\n");
}
} else {
OUT("if(!table[cv]) return -1;\n");
@ -512,58 +524,68 @@ emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range) {
return 0;
}
static int
emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1c_integer_t natural_start, asn1c_integer_t natural_stop) {
int ignore_left;
int ignore_right;
int generated_something = 0;
int i;
static void
abuf_oint(abuf *ab, asn1c_integer_t v) {
if(v == (-2147483647L - 1)) {
abuf_printf(ab, "(-2147483647L - 1)");
} else {
abuf_printf(ab, "%s", asn1p_itoa(v));
}
}
for(i = -1; i < range->el_count; i++) {
asn1cnst_range_t *r;
if(i == -1) {
if(range->el_count) continue;
r = range;
} else {
if(i) OUT(" || ");
r = range->elements[i];
}
static abuf *
emit_range_comparison_code(asn1cnst_range_t *range, const char *varname,
asn1c_integer_t natural_start,
asn1c_integer_t natural_stop) {
abuf *ab = abuf_new();
if(r != range) OUT("(");
if(range->el_count == 0) {
int ignore_left =
(range->left.type == ARE_MIN)
|| (natural_start != -1 && range->left.value <= natural_start);
int ignore_right =
(range->right.type == ARE_MAX)
|| (natural_stop != -1 && range->right.value >= natural_stop);
ignore_left = (r->left.type == ARE_MIN)
|| (natural_start != -1
&& r->left.value <= natural_start);
ignore_right = (r->right.type == ARE_MAX)
|| (natural_stop != -1
&& r->right.value >= natural_stop);
if(ignore_left && ignore_right) {
OUT("1 /* Constraint matches natural range of %s */",
varname);
continue;
}
if(ignore_left && ignore_right) {
/* Empty constraint comparison */
} else if(ignore_left) {
abuf_printf(ab, "%s <= ", varname);
abuf_oint(ab, range->right.value);
} else if(ignore_right) {
abuf_printf(ab, "%s >= ", varname);
abuf_oint(ab, range->left.value);
} else if(range->left.value == range->right.value) {
abuf_printf(ab, "%s == ", varname);
abuf_oint(ab, range->right.value);
} else {
abuf_printf(ab, "%s >= ", varname);
abuf_oint(ab, range->left.value);
abuf_printf(ab, " && ");
abuf_printf(ab, "%s <= ", varname);
abuf_oint(ab, range->right.value);
}
} else {
for(int i = 0; i < range->el_count; i++) {
asn1cnst_range_t *r = range->elements[i];
if(ignore_left) {
OUT("%s <= ", varname);
OINT(r->right.value);
} else if(ignore_right) {
OUT("%s >= ", varname);
OINT(r->left.value);
} else if(r->left.value == r->right.value) {
OUT("%s == ", varname);
OINT(r->right.value);
} else {
OUT("%s >= ", varname);
OINT(r->left.value);
OUT(" && ");
OUT("%s <= ", varname);
OINT(r->right.value);
}
if(r != range) OUT(")");
generated_something = 1;
}
abuf *rec = emit_range_comparison_code(r, varname, natural_start,
natural_stop);
if(rec->length) {
if(ab->length) {
abuf_str(ab, " || ");
}
abuf_str(ab, "(");
abuf_buf(ab, rec);
abuf_str(ab, ")");
} else {
/* Ignore this part */
}
abuf_free(rec);
}
}
return generated_something;
return ab;
}
static int

View File

@ -83,8 +83,6 @@ static double NativeReal__get_double(const asn_TYPE_descriptor_t *td,
const void *ptr);
static ssize_t NativeReal__set(const asn_TYPE_descriptor_t *td, void **sptr,
double d);
static void NativeReal__network_swap(size_t float_size, const void *srcp,
uint8_t *dst);
/*
* Decode REAL type.
@ -268,6 +266,62 @@ NativeReal_encode_uper(const asn_TYPE_descriptor_t *td,
#ifndef ASN_DISABLE_OER_SUPPORT
/*
* Swap bytes from/to network, if local is little-endian.
* Unused endianness sections are likely removed at compile phase.
*/
static void
NativeReal__network_swap(size_t float_size, const void *srcp, uint8_t *dst) {
const uint8_t *src = srcp;
double test = -0.0;
int float_big_endian = *(const char *)&test != 0;
/* In lieu of static_assert(sizeof(double) == 8) */
static const char sizeof_double_is_8_a[sizeof(double)-7] CC_NOTUSED;
static const char sizeof_double_is_8_b[9-sizeof(double)] CC_NOTUSED;
/* In lieu of static_assert(sizeof(sizeof) == 4) */
static const char sizeof_float_is_4_a[sizeof(float)-3] CC_NOTUSED;
static const char sizeof_float_is_4_b[5-sizeof(float)] CC_NOTUSED;
switch(float_size) {
case sizeof(double):
assert(sizeof(double) == 8);
if(float_big_endian) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
} else {
dst[0] = src[7];
dst[1] = src[6];
dst[2] = src[5];
dst[3] = src[4];
dst[4] = src[3];
dst[5] = src[2];
dst[6] = src[1];
dst[7] = src[0];
}
return;
case sizeof(float):
assert(sizeof(float) == 4);
if(float_big_endian) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
} else {
dst[0] = src[3];
dst[1] = src[2];
dst[2] = src[1];
dst[3] = src[0];
}
return;
}
}
/*
* Encode as Canonical OER.
*/
@ -655,58 +709,3 @@ NativeReal__set(const asn_TYPE_descriptor_t *td, void **sptr, double d) {
return float_size;
}
/*
* Swap bytes from/to network, if local is little-endian.
* Unused endianness sections are likely removed at compile phase.
*/
static void
NativeReal__network_swap(size_t float_size, const void *srcp, uint8_t *dst) {
const uint8_t *src = srcp;
double test = -0.0;
int float_big_endian = *(const char *)&test != 0;
/* In lieu of static_assert(sizeof(double) == 8) */
static const char sizeof_double_is_8_a[sizeof(double)-7] CC_NOTUSED;
static const char sizeof_double_is_8_b[9-sizeof(double)] CC_NOTUSED;
/* In lieu of static_assert(sizeof(sizeof) == 4) */
static const char sizeof_float_is_4_a[sizeof(float)-3] CC_NOTUSED;
static const char sizeof_float_is_4_b[5-sizeof(float)] CC_NOTUSED;
switch(float_size) {
case sizeof(double):
assert(sizeof(double) == 8);
if(float_big_endian) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
dst[4] = src[4];
dst[5] = src[5];
dst[6] = src[6];
dst[7] = src[7];
} else {
dst[0] = src[7];
dst[1] = src[6];
dst[2] = src[5];
dst[3] = src[4];
dst[4] = src[3];
dst[5] = src[2];
dst[6] = src[1];
dst[7] = src[0];
}
return;
case sizeof(float):
assert(sizeof(float) == 4);
if(float_big_endian) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = src[3];
} else {
dst[0] = src[3];
dst[1] = src[2];
dst[2] = src[1];
dst[3] = src[0];
}
return;
}
}

View File

@ -394,7 +394,7 @@ static int check_permitted_alphabet_29(const void *sptr) {
| (ch[1] << 16)
| (ch[2] << 8)
| ch[3];
if(!(1 /* Constraint matches natural range of cv */)) return -1;
(void)cv; /* Unused variable */
}
return 0;
}

View File

@ -61,7 +61,7 @@ static int check_permitted_alphabet_9(const void *sptr) {
| (ch[1] << 16)
| (ch[2] << 8)
| ch[3];
if(!(1 /* Constraint matches natural range of cv */)) return -1;
(void)cv; /* Unused variable */
}
return 0;
}

View File

@ -86,15 +86,12 @@ Int2_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
value = *(const long *)sptr;
if((value >= 0)) {
/* Constraint check succeeded */
return 0;
} else {
ASN__CTFAIL(app_key, td, sptr,
"%s: constraint failed (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
if(1 /* No applicable constraints whatsoever */) {
(void)value; /* Unused variable */
/* Nothing is here. See below */
}
return td->encoding_constraints.general_constraints(td, sptr, ctfailcb, app_key);
}
/*

View File

@ -27,9 +27,9 @@ int main() {
oer_decode(0, &asn_DEF_T, (void **)&decoded, tmpbuf, er.encoded);
assert(dr.code == RC_OK);
if(dr.consumed != er.encoded) {
if((ssize_t)dr.consumed != er.encoded) {
ASN_DEBUG("Consumed %zu, expected %zu", dr.consumed, er.encoded);
assert(dr.consumed == er.encoded);
assert((ssize_t)dr.consumed == er.encoded);
}
if(XEQ_SUCCESS != xer_equivalent(&asn_DEF_T, &source, decoded, stderr)) {

View File

@ -100,24 +100,20 @@ buf2_fill(const void *buffer, size_t size, void *app_key) {
static void
compare_encoding(asn_enc_rval_t *erval, uint8_t *expected, size_t expected_size,
uint8_t *actual) {
int i;
assert(erval->encoded != -1);
if(erval->encoded != expected_size) {
if((size_t)erval->encoded != expected_size) {
printf("%d != %d\n", (int)erval->encoded, (int)expected_size);
assert((size_t)erval->encoded == expected_size);
}
for(size_t i = 0; i < expected_size; i++) {
if(expected[i] != actual[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %zu, %x != %x (%d != %d)\n", i, expected[i],
actual[i], expected[i], actual[i]);
}
assert(expected[i] == actual[i]);
}
assert(erval->encoded == (ssize_t)expected_size);
for(i = 0; i < expected_size; i++) {
if(expected[i] != actual[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
expected[i], actual[i],
expected[i], actual[i]
);
}
assert(expected[i] == actual[i]);
}
}
static void

View File

@ -90,9 +90,8 @@ buf_fill(const void *buffer, size_t size, void *app_key) {
}
static void
compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) {
compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) {
asn_enc_rval_t erval;
int i;
buf_size = cmp_buf_size + 100;
uint8_t scratch[buf_size];
@ -104,14 +103,14 @@ compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) {
*/
erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != cmp_buf_size) {
if((size_t)erval.encoded != cmp_buf_size) {
printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
}
assert(erval.encoded == cmp_buf_size);
for(i = 0; i < cmp_buf_size; i++) {
assert((size_t)erval.encoded == cmp_buf_size);
}
for(size_t i = 0; i < cmp_buf_size; i++) {
if(buf[i] != cmp_buf[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
fprintf(stderr, "Byte %zd, %x != %x (%d != %d)\n",
i,
buf[i], cmp_buf[i],
buf[i], cmp_buf[i]

View File

@ -7,6 +7,18 @@
#include <LogLine.h>
#ifdef ENABLE_LIBFUZZER
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
LogLine_t *lp = 0;
(void)ber_decode(0, &asn_DEF_LogLine, (void **)&lp, Data, Size);
ASN_STRUCT_FREE(asn_DEF_LogLine, lp);
return 0;
}
#else
uint8_t buf0[] = {
48, /* LogLine SEQUENCE */
24, /* L */
@ -126,17 +138,6 @@ check_serialize() {
return;
}
#ifdef ENABLE_LIBFUZZER
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
LogLine_t *lp = 0;
(void)ber_decode(0, &asn_DEF_LogLine, (void **)&lp, Data, Size);
ASN_STRUCT_FREE(asn_DEF_LogLine, lp);
return 0;
}
#else
int
main(int ac, char **av) {
LogLine_t t;

View File

@ -25,6 +25,20 @@
#define SRCDIR_S STRINGIFY_MACRO(SRCDIR)
#endif
#ifdef ENABLE_LIBFUZZER
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
PDU_t *st = 0;
asn_dec_rval_t rval;
rval = asn_decode(0, ATS_BASIC_XER, &asn_DEF_PDU, (void **)&st, Data, Size);
assert(rval.consumed <= Size);
ASN_STRUCT_FREE(asn_DEF_PDU, st);
return 0;
}
#else
enum expectation {
EXP_OK, /* Encoding/decoding must succeed */
EXP_CXER_EXACT, /* Encoding/decoding using CXER must be exact */
@ -278,19 +292,6 @@ process(const char *fname) {
return 1;
}
#ifdef ENABLE_LIBFUZZER
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
PDU_t *st = 0;
asn_dec_rval_t rval;
rval = asn_decode(0, ATS_BASIC_XER, &asn_DEF_PDU, (void **)&st, Data, Size);
assert(rval.consumed <= Size);
ASN_STRUCT_FREE(asn_DEF_PDU, st);
return 0;
}
#else
int
main() {
DIR *dir;

View File

@ -25,6 +25,20 @@
#define SRCDIR_S STRINGIFY_MACRO(SRCDIR)
#endif
#ifdef ENABLE_LIBFUZZER
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
PDU_t *st = 0;
asn_dec_rval_t rval;
rval = asn_decode(0, ATS_BASIC_XER, &asn_DEF_PDU, (void **)&st, Data, Size);
assert(rval.consumed <= Size);
ASN_STRUCT_FREE(asn_DEF_PDU, st);
return 0;
}
#else
enum expectation {
EXP_OK, /* Encoding/decoding must succeed */
EXP_BROKEN, /* Decoding must fail */
@ -257,19 +271,6 @@ process(const char *fname) {
return 1;
}
#ifdef ENABLE_LIBFUZZER
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
PDU_t *st = 0;
asn_dec_rval_t rval;
rval = asn_decode(0, ATS_BASIC_XER, &asn_DEF_PDU, (void **)&st, Data, Size);
assert(rval.consumed <= Size);
ASN_STRUCT_FREE(asn_DEF_PDU, st);
return 0;
}
#else
int
main() {
DIR *dir;

View File

@ -30,9 +30,9 @@ int main() {
oer_decode(0, &asn_DEF_T, (void **)&decoded, tmpbuf, er.encoded);
assert(dr.code == RC_OK);
if(dr.consumed != er.encoded) {
ASN_DEBUG("Consumed %zu, expected %zu", dr.consumed, er.encoded);
assert(dr.consumed == er.encoded);
if((ssize_t)dr.consumed != er.encoded) {
ASN_DEBUG("Consumed %zd, expected %zu", dr.consumed, er.encoded);
assert((ssize_t)dr.consumed == er.encoded);
}
if(XEQ_SUCCESS != xer_equivalent(&asn_DEF_T, &source, decoded, stderr)) {

View File

@ -229,10 +229,11 @@ check_range_rebase() {
OK_REBASE_ROUNDTRIP(LONG_MIN, LONG_MIN, LONG_MAX);
OK_REBASE_ROUNDTRIP(LONG_MAX, LONG_MIN, LONG_MAX);
#ifndef EXPLICIT_32BIT
if(sizeof(long) == 8) {
OK_REBASE_ROUNDTRIP(0, LONG_MIN, LONG_MAX);
/* Too wide range, not fit uint32_t */
/* Too wide range, would not fit uint32_t */
OK_REBASE_ROUNDTRIP(INT32_MIN, (long)INT32_MIN - 1,
(long)INT32_MAX + 1);
OK_REBASE_ROUNDTRIP(INT32_MAX, (long)INT32_MIN - 1,
@ -251,6 +252,7 @@ check_range_rebase() {
NO_REBASE_ROUNDTRIP(LONG_MIN, INT32_MIN, INT32_MAX);
NO_REBASE_ROUNDTRIP(LONG_MAX, INT32_MIN, INT32_MAX);
}
#endif
OK_REBASE_ROUNDTRIP(-1, LONG_MIN + 1, LONG_MAX - 1);
OK_REBASE_ROUNDTRIP(0, LONG_MIN + 1, LONG_MAX - 1);