diff --git a/compiler2/EnumItem.cc b/compiler2/EnumItem.cc index 016ef521244c2de67e8b883640ce10ad2295cf5b..c18147cce866727073a662c8a38370b687178bb9 100644 --- a/compiler2/EnumItem.cc +++ b/compiler2/EnumItem.cc @@ -77,6 +77,41 @@ void EnumItem::set_value(Value *p_value) void EnumItem::set_text(const string& p_text) { text = p_text; + + // De escape special XML characters if any found, into descaped_text + descaped_text = p_text; + size_t pos = 0; + while ((pos = descaped_text.find("'", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 6, "'"); + } + while ((pos = descaped_text.find(""", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 6, "\\\""); + } + while ((pos = descaped_text.find("<", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 4, "<"); + } + while ((pos = descaped_text.find(">", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 4, ">"); + } + while ((pos = descaped_text.find("&", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 5, "&"); + } + while ((pos = descaped_text.find("<", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 5, "<"); + } + while ((pos = descaped_text.find(">", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 5, ">"); + } + while ((pos = descaped_text.find(""", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 5, "\\\""); + } + while ((pos = descaped_text.find("&", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 5, "&"); + pos++; + } + while ((pos = descaped_text.find("'", 0)) != descaped_text.size()) { + descaped_text.replace(pos, 5, "'"); + } } bool EnumItem::calculate_int_value() { diff --git a/compiler2/EnumItem.hh b/compiler2/EnumItem.hh index 929899ca00603c3e4ad72977389ce387eb97a7ab..ab72cb3fb4c64686d7d3753384a9c174a4573db1 100644 --- a/compiler2/EnumItem.hh +++ b/compiler2/EnumItem.hh @@ -32,6 +32,7 @@ private: Identifier *name; Value *value; string text; ///< for TEXT encoding instruction + string descaped_text; ///< made from text variable but replaces all the escaped values int_val_t *int_value; /** Copy constructor not implemented */ EnumItem(const EnumItem&); @@ -46,6 +47,7 @@ public: Value *get_value() const { return value; } void set_value(Value *p_value); const string& get_text() const { return text; } + const string& get_descaped_text() const { return descaped_text; } void set_text(const string& p_text); virtual void set_my_scope(Scope *p_scope); bool calculate_int_value(); diff --git a/compiler2/Type_codegen.cc b/compiler2/Type_codegen.cc index 7b13f387407f9c7a0f66b8a9ff96c078e2c4ac2b..b860d81399cfb1fa5747dd56e4fcdb937e3c262c 100644 --- a/compiler2/Type_codegen.cc +++ b/compiler2/Type_codegen.cc @@ -1147,6 +1147,7 @@ void Type::generate_code_Enum(output_struct *target) else { e_def.xerText = TRUE; e_def.elements[i].text = ei->get_text().c_str(); + e_def.elements[i].descaped_text = ei->get_descaped_text().c_str(); } e_def.elements[i].value = ei->get_int_val()->get_val(); } diff --git a/compiler2/datatypes.h b/compiler2/datatypes.h index 19da16ceef0360b60e7eebb4ded5a89cb1dcffdd..e0ce20527ede575f9041b9b613cbf7c63147bc50 100644 --- a/compiler2/datatypes.h +++ b/compiler2/datatypes.h @@ -159,6 +159,7 @@ typedef struct { const char *name; /* identifier name */ const char *dispname; /* identifier TTCN-3 name */ const char *text; /* modified by TEXT */ + const char *descaped_text; /* text but the escaped characters are descaped */ int value; } enum_field; diff --git a/compiler2/enum.c b/compiler2/enum.c index a861f641727ef5fcc429fccfbff1d8bba396c5a1..162a5fd29bb22c5a8079d481a9dfcaacb5108417 100644 --- a/compiler2/enum.c +++ b/compiler2/enum.c @@ -268,8 +268,8 @@ void defEnumClass(const enum_def *edef, output_struct *output) "{\n", qualified_enum_type, name); for (i = 0; i < edef->nElements; i++) { if (edef->elements[i].text) { - src = mputprintf(src, "if (!strcmp(str_par, \"%s\") || !strcmp(str_par, \"%s\")) return %s;\n" - "else ", edef->elements[i].text, edef->elements[i].dispname, edef->elements[i].name); + src = mputprintf(src, "if (!strcmp(str_par, \"%s\") || !strcmp(str_par, \"%s\") || !strcmp(str_par, \"%s\")) return %s;\n" + "else ", edef->elements[i].text, edef->elements[i].descaped_text, edef->elements[i].dispname, edef->elements[i].name); } else { src = mputprintf(src, "if (!strcmp(str_par, \"%s\")) return %s;\n" diff --git a/regression_test/XML/EXER-whitepaper/Text.ttcnpp b/regression_test/XML/EXER-whitepaper/Text.ttcnpp index f87b000b21424a23e50f96822e19a1552c477e64..874131e8ff93a5d6d2977008d55256ce5878546b 100644 --- a/regression_test/XML/EXER-whitepaper/Text.ttcnpp +++ b/regression_test/XML/EXER-whitepaper/Text.ttcnpp @@ -8,6 +8,7 @@ * Contributors: * Balasko, Jeno * Raduly, Csaba + * Szabo, Bence Janos * ******************************************************************************/ module Text @@ -236,6 +237,36 @@ testcase decode_truth() runs on Plain CHECK_DECODE(exer_dec_x, estr_xdunno, XmlTruth, xdunno); } +/* * * * * * * * * * * * * * * * * * * * * * */ +// Regression test for special escaped characters present in the text as variant + +type record Special +{ + enumerated { + numbers + } expr +} +with { + variant (expr) "text 'numbers' as '<>"&'numbers<>"&''"; +}; + +DECLARE_EXER_ENCODERS(Special, s); + +const Special spec := { expr := numbers }; + +const universal charstring estr_spec := + "<Special>\n\t<expr><>"&'numbers<>"&'</expr>\n</Special>\n\n"; + +testcase encode_special() runs on Plain +{ + CHECK_METHOD(exer_enc_s, spec, estr_spec); +} + +testcase decode_special() runs on Plain +{ + CHECK_DECODE(exer_dec_s, estr_spec, Special, spec); +} + control { execute(encode_txt()); @@ -249,6 +280,9 @@ control execute(encode_truth()); execute(decode_truth()); + + execute(encode_special()); + execute(decode_special()); }