Commit 0331e0b9 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Making 'isvalue' a safe operation (bug 544855)



Change-Id: I338ec4e9e7078ec392433aa1b6f57d74e7eb1e7c
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 490a8723
......@@ -48,7 +48,7 @@ enum namedbool { INCOMPLETE_NOT_ALLOWED = 0, INCOMPLETE_ALLOWED = 1, WARNING_FOR
ANY_OR_OMIT_NOT_ALLOWED = 0, ANY_OR_OMIT_ALLOWED = 5,
NOT_IMPLICIT_OMIT = 0, IMPLICIT_OMIT = 6,
NOT_STR_ELEM = 0, IS_STR_ELEM = 7,
ISBOUND = 8, ISPRESENT = 9, ISCHOSEN = 10
ISBOUND = 8, ISPRESENT = 9, ISCHOSEN = 10, ISVALUE = 11
};
namespace Asn {
......
......@@ -2934,7 +2934,7 @@ void Type::generate_code_ispresentboundchosen(expression_struct *expr,
bool anyval_ret_val = TRUE;
if (optype == ISPRESENT) {
anyval_ret_val = ispresent_anyvalue_embedded_field(t, subrefs, i);
} else if (optype == ISCHOSEN) {
} else if (optype == ISCHOSEN || optype == ISVALUE) {
anyval_ret_val = FALSE;
}
expr->expr = mputprintf(expr->expr, "if(%s) {\n",global_id.c_str());
......@@ -3033,14 +3033,26 @@ void Type::generate_code_ispresentboundchosen(expression_struct *expr,
next_t->get_genname_value(module).c_str(),
is_template?"_template":"", tmp_id_str);
if (optype != ISCHOSEN) {
expr->expr = mputprintf(expr->expr,
"%s = %s.%s(%s);\n", global_id.c_str(),
tmp_id2_str, optype == ISBOUND ? "is_bound" : "is_present",
(optype != ISBOUND && is_template && omit_in_value_list) ? "TRUE" : "");
} else {
expr->expr = mputprintf(expr->expr,
"%s = %s.ischosen(%s);\n", global_id.c_str(), tmp_id2_str, field);
switch (optype) {
case ISBOUND:
expr->expr = mputprintf(expr->expr, "%s = %s.is_bound();\n",
global_id.c_str(), tmp_id2_str);
break;
case ISPRESENT:
expr->expr = mputprintf(expr->expr, "%s = %s.is_present(%s);\n",
global_id.c_str(), tmp_id2_str,
(is_template && omit_in_value_list) ? "TRUE" : "");
break;
case ISCHOSEN:
expr->expr = mputprintf(expr->expr, "%s = %s.ischosen(%s);\n",
global_id.c_str(), tmp_id2_str, field);
break;
case ISVALUE:
expr->expr = mputprintf(expr->expr, "%s = %s.is_value();\n",
global_id.c_str(), tmp_id2_str);
break;
default:
FATAL_ERROR("Type::generate_code_ispresentboundchosen");
}
Free(tmp_generalid_str);
tmp_generalid_str = mcopystr(tmp_id2_str);
......@@ -3109,19 +3121,33 @@ void Type::generate_code_ispresentboundchosen(expression_struct *expr,
tmp_id2_str, tmp_id_str,
t->typetype == T_ANYTYPE ? "AT_" : "", id.get_name().c_str());
if (optype != ISCHOSEN) {
expr->expr = mputprintf(expr->expr,
"%s = %s.%s(%s);\n", global_id.c_str(),
tmp_id2_str, optype == ISBOUND||(i!=(nof_refs-1)) ? "is_bound" : "is_present",
(!(optype == ISBOUND||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : "");
} else {
expr->expr = mputprintf(expr->expr,
"%s = %s.is_bound();\n", global_id.c_str(), tmp_id2_str);
if (i == nof_refs-1) {
if (i != nof_refs - 1 || optype == ISCHOSEN) {
expr->expr = mputprintf(expr->expr, "%s = %s.is_bound();\n",
global_id.c_str(), tmp_id2_str);
}
if (i == nof_refs - 1) {
switch (optype) {
case ISBOUND:
expr->expr = mputprintf(expr->expr, "%s = %s.is_bound();\n",
global_id.c_str(), tmp_id2_str);
break;
case ISPRESENT:
expr->expr = mputprintf(expr->expr, "%s = %s.is_present(%s);\n",
global_id.c_str(), tmp_id2_str,
(is_template && omit_in_value_list) ? "TRUE" : "");
break;
case ISCHOSEN:
expr->expr = mputprintf(expr->expr,
"if(%s) {\n"
"if (%s) {\n"
"%s = %s.ischosen(%s);\n"
"}\n", global_id.c_str(), global_id.c_str(), tmp_id2_str, field);
break;
case ISVALUE:
expr->expr = mputprintf(expr->expr, "%s = %s.is_value();\n",
global_id.c_str(), tmp_id2_str);
break;
default:
FATAL_ERROR("Type::generate_code_ispresentboundchosen");
}
}
Free(tmp_generalid_str);
......@@ -3212,8 +3238,8 @@ void Type::generate_code_ispresentboundchosen(expression_struct *expr,
expr->expr = mputprintf(expr->expr,
"%s = %s[%s].%s(%s);\n", global_id.c_str(),
tmp_generalid_str, tmp_index_id_str,
optype==ISBOUND||(i!=(nof_refs-1)) ? "is_bound" : "is_present",
(!(optype==ISBOUND||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : "");
optype==ISBOUND||(i!=(nof_refs-1)) ? "is_bound" : optype == ISVALUE ? "is_value" : "is_present",
((optype==ISPRESENT&&(i==(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : "");
}
} else {
if (is_template) {
......@@ -3230,20 +3256,33 @@ void Type::generate_code_ispresentboundchosen(expression_struct *expr,
tmp_index_id_str);
}
if (optype != ISCHOSEN) {
expr->expr = mputprintf(expr->expr,
"%s = %s.%s(%s);\n", global_id.c_str(), tmp_id_str,
optype==ISBOUND||(i!=(nof_refs-1)) ? "is_bound" : "is_present",
(!(optype==ISBOUND||(i!=(nof_refs-1))) && is_template && omit_in_value_list) ? "TRUE" : "");
} else {
expr->expr = mputprintf(expr->expr,
"%s = %s.is_bound();\n", global_id.c_str(),
tmp_id_str);
if (i == nof_refs-1) {
if (i != nof_refs - 1 || optype == ISCHOSEN) {
expr->expr = mputprintf(expr->expr, "%s = %s.is_bound();\n",
global_id.c_str(), tmp_id_str);
}
if (i == nof_refs - 1) {
switch (optype) {
case ISBOUND:
expr->expr = mputprintf(expr->expr, "%s = %s.is_bound();\n",
global_id.c_str(), tmp_id_str);
break;
case ISPRESENT:
expr->expr = mputprintf(expr->expr, "%s = %s.is_present(%s);\n",
global_id.c_str(), tmp_id_str,
(is_template && omit_in_value_list) ? "TRUE" : "");
break;
case ISCHOSEN:
expr->expr = mputprintf(expr->expr,
"if(%s) {\n"
"if (%s) {\n"
"%s = %s.ischosen(%s);\n"
"}\n", global_id.c_str(), global_id.c_str(), tmp_id_str, field);
break;
case ISVALUE:
expr->expr = mputprintf(expr->expr, "%s = %s.is_value();\n",
global_id.c_str(), tmp_id_str);
break;
default:
FATAL_ERROR("Type::generate_code_ispresentboundchosen");
}
}
}
......
......@@ -13067,6 +13067,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
}
break; }
case OPTYPE_ISCHOSEN_T:
case OPTYPE_ISVALUE:
str = u.expr.t1->rearrange_init_code(str, usage_mod);
break;
case OPTYPE_MATCH:
......@@ -13490,6 +13491,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
}
Free(field);
break; }
case OPTYPE_ISVALUE: // ti1
case OPTYPE_ISPRESENT:
case OPTYPE_ISBOUND: {
Template::templatetype_t temp = u.expr.ti1->get_Template()
......@@ -13520,9 +13522,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
// no break
case OPTYPE_LENGTHOF: // ti1
// fall through, separated later
case OPTYPE_SIZEOF: // ti1
// fall through, separated later
case OPTYPE_ISVALUE: { // ti1
case OPTYPE_SIZEOF: { // ti1
if (u.expr.ti1->is_only_specific_value()) {
Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
bool cast_needed = t_val->explicit_cast_needed(
......@@ -15412,6 +15412,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_ISPRESENT:
case OPTYPE_ISCHOSEN_T:
case OPTYPE_ISCHOSEN_V: // v1 i2
case OPTYPE_ISVALUE: // ti1
case OPTYPE_TTCN2STRING:
case OPTYPE_ENCVALUE_UNICHAR:
case OPTYPE_DECVALUE_UNICHAR:
......@@ -15526,7 +15527,6 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
}
}
// fall through
case OPTYPE_ISVALUE: // ti1
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
return u.expr.ti1->has_single_expr();
......
......@@ -883,6 +883,8 @@ namespace Ttcn {
p_optype = ISPRESENT;
} else if (optype == Value::OPTYPE_ISCHOSEN_T || optype == Value::OPTYPE_ISCHOSEN_V) {
p_optype = ISCHOSEN;
} else if (optype == Value::OPTYPE_ISVALUE) {
p_optype = ISVALUE;
} else {
FATAL_ERROR("AST_ttcn3.cc::generate_code_ispresentboundchosen()");
}
......@@ -908,6 +910,9 @@ namespace Ttcn {
case Value::OPTYPE_ISCHOSEN_V:
expr->expr = mputprintf(expr->expr, "ischosen(%s)", field);
break;
case Value::OPTYPE_ISVALUE:
expr->expr = mputprintf(expr->expr, "is_value()");
break;
default:
FATAL_ERROR("AST_ttcn3.cc::generate_code_ispresentboundchosen()");
}
......
......@@ -16519,7 +16519,8 @@ module ModuleA {
type component dummy_CT {}
testcase tc_temp () runs on dummy_CT{
var universal charstring cstr;
log(isvalue(cstr[0]));
if (isvalue(cstr[0])) { setverdict(fail); }
else { setverdict(pass); }
}
control {
execute(tc_temp());
......@@ -16540,7 +16541,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS
ModuleA
<END_MODULE>
<RESULT IF_PASS COUNT 1>
(?im)Dynamic test case error: Accessing an element of an unbound universal charstring value.
(?im)Overall verdict: pass
<END_RESULT>
<END_TC>
:exmp.
......@@ -16562,7 +16563,8 @@ module ModuleA {
type component dummy_CT {}
testcase tc_temp () runs on dummy_CT{
var tunion temp := {x1 := 1};
log(isvalue(temp.x2));
if (isvalue(temp.x2)) { setverdict(fail); }
else { setverdict(pass); }
}
control {
execute(tc_temp());
......@@ -16583,7 +16585,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS
ModuleA
<END_MODULE>
<RESULT IF_PASS COUNT 1>
(?im)Dynamic test case error: Using non-selected field x2 in a value of union type @ModuleA.tunion.
(?im)Overall verdict: pass
<END_RESULT>
<END_TC>
:exmp.
......@@ -16602,7 +16604,8 @@ module ModuleA {
type component dummy_CT {}
testcase tc_temp () runs on dummy_CT{
var t_recof temp;
log(isvalue(temp[0]));
if (isvalue(temp[0])) { setverdict(fail); }
else { setverdict(pass); }
}
control {
execute(tc_temp());
......@@ -16623,7 +16626,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS
ModuleA
<END_MODULE>
<RESULT IF_PASS COUNT 1>
(?im)Dynamic test case error: Accessing an element in an unbound value of type @PreGenRecordOf.PREGEN_RECORD_OF_INTEGER.
(?im)Overall verdict: pass
<END_RESULT>
<END_TC>
:exmp.
......@@ -16642,7 +16645,8 @@ module ModuleA {
type component dummy_CT {}
testcase tc_temp () runs on dummy_CT{
var t_recof temp := {[1] := 1};
log(isvalue(temp[10]));
if (isvalue(temp[10])) { setverdict(fail); }
else { setverdict(pass); }
}
control {
execute(tc_temp());
......@@ -16663,7 +16667,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS
ModuleA
<END_MODULE>
<RESULT IF_PASS COUNT 1>
(?im)Dynamic test case error: Index overflow in a value of type @PreGenRecordOf.PREGEN_RECORD_OF_INTEGER: The index is 10, but the value has only 2 elements.
(?im)Overall verdict: pass
<END_RESULT>
<END_TC>
:exmp.
......@@ -16682,7 +16686,8 @@ module ModuleA {
type component dummy_CT {}
testcase tc_temp () runs on dummy_CT{
var t_setof temp;
log(isvalue(temp[0]));
if (isvalue(temp[0])) { setverdict(fail); }
else { setverdict(pass); }
}
control {
execute(tc_temp());
......@@ -16703,7 +16708,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS
ModuleA
<END_MODULE>
<RESULT IF_PASS COUNT 1>
(?im)Dynamic test case error: Accessing an element in an unbound value of type @PreGenRecordOf.PREGEN_SET_OF_INTEGER.
(?im)Overall verdict: pass
<END_RESULT>
<END_TC>
:exmp.
......@@ -16722,7 +16727,8 @@ module ModuleA {
type component dummy_CT {}
testcase tc_temp () runs on dummy_CT{
var t_setof temp := {[1] := 1};
log(isvalue(temp[10]));
if (isvalue(temp[10])) { setverdict(fail); }
else { setverdict(pass); }
}
control {
execute(tc_temp());
......@@ -16743,7 +16749,7 @@ ConsoleMask := WARNING | ERROR | TESTCASE | STATISTICS
ModuleA
<END_MODULE>
<RESULT IF_PASS COUNT 1>
(?im)Dynamic test case error: Index overflow in a value of type @PreGenRecordOf.PREGEN_SET_OF_INTEGER: The index is 10, but the value has only 2 elements.
(?im)Overall verdict: pass
<END_RESULT>
<END_TC>
:exmp.
......
......@@ -888,14 +888,14 @@ testcase recofIsvalue() runs on recofOper_mycomp{
{ {-,1,-},{-,1,-},{-,1,-} }
}
if ( isvalue(nowhere) ) { setverdict(fail); } else { setverdict(pass); };
if ( isvalue(nowhere[1]) ) { setverdict(fail); } else { setverdict(pass); };
if ( isvalue(nowhere[1][1]) ) { setverdict(fail); } else { setverdict(pass); };
if ( isvalue(nowhere[1][1][1]) ) { setverdict(fail); } else { setverdict(pass); };
if ( isvalue(d3) ) { setverdict(pass); } else { setverdict(fail); };
if ( isvalue(d3[0]) ) { setverdict(pass); } else { setverdict(fail); };
if ( isvalue(d3[0][1]) ) { setverdict(pass); } else { setverdict(fail); };
if ( isvalue(d3[0][1][2]) ) { setverdict(pass); } else { setverdict(fail); };
if ( isvalue(nowhere) ) { setverdict(fail, 1); } else { setverdict(pass); };
if ( isvalue(nowhere[1]) ) { setverdict(fail, 2); } else { setverdict(pass); };
if ( isvalue(nowhere[1][1]) ) { setverdict(fail, 3); } else { setverdict(pass); };
if ( isvalue(nowhere[1][1][1]) ) { setverdict(fail, 4); } else { setverdict(pass); };
if ( isvalue(d3) ) { setverdict(pass); } else { setverdict(fail, 5); };
if ( isvalue(d3[0]) ) { setverdict(pass); } else { setverdict(fail, 6); };
if ( isvalue(d3[0][1]) ) { setverdict(pass); } else { setverdict(fail, 7); };
if ( isvalue(d3[0][1][2]) ) { setverdict(pass); } else { setverdict(fail, 8); };
}
testcase recofIsvalue2() runs on recofOper_mycomp{
......
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