From d272fdff613918e029f5ec370957e0c5302e31b1 Mon Sep 17 00:00:00 2001
From: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
Date: Mon, 11 Sep 2017 15:43:49 +0200
Subject: [PATCH] XER: text variant encodes and decodes escaped xml characters
 (Bug 522143)

Change-Id: Ic01f2e49902efe729fea97a1a0c2f1bbc09136d2
Signed-off-by: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
---
 compiler2/EnumItem.cc                         | 35 +++++++++++++++++++
 compiler2/EnumItem.hh                         |  2 ++
 compiler2/Type_codegen.cc                     |  1 +
 compiler2/datatypes.h                         |  1 +
 compiler2/enum.c                              |  4 +--
 .../XML/EXER-whitepaper/Text.ttcnpp           | 34 ++++++++++++++++++
 6 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/compiler2/EnumItem.cc b/compiler2/EnumItem.cc
index 016ef5212..c18147cce 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("&apos;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 6, "'");
+  }
+  while ((pos = descaped_text.find("&quot;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 6, "\\\"");
+  }
+  while ((pos = descaped_text.find("&lt;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 4, "<");
+  }
+  while ((pos = descaped_text.find("&gt;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 4, ">");
+  }
+  while ((pos = descaped_text.find("&amp;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 5, "&");
+  }
+  while ((pos = descaped_text.find("&#60;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 5, "<");
+  }
+  while ((pos = descaped_text.find("&#62;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 5, ">");
+  }
+  while ((pos = descaped_text.find("&#34;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 5, "\\\"");
+  }
+  while ((pos = descaped_text.find("&#38;", 0)) != descaped_text.size()) {
+    descaped_text.replace(pos, 5, "&");
+    pos++;
+  }
+  while ((pos = descaped_text.find("&#39;", 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 929899ca0..ab72cb3fb 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 7b13f3874..b860d8139 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 19da16cee..e0ce20527 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 a861f6417..162a5fd29 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 f87b000b2..874131e8f 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 '&lt;&gt;&quot;&amp;&apos;numbers&#60;&#62;&#34;&#38;&#39;'";
+};
+
+DECLARE_EXER_ENCODERS(Special, s);
+
+const Special spec  := { expr := numbers };
+
+const universal charstring estr_spec :=
+  "<Special>\n\t<expr>&lt;&gt;&quot;&amp;&apos;numbers&#60;&#62;&#34;&#38;&#39;</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());
 }
 
 
-- 
GitLab