From adbfed7fbf5008cbbd8479f33ccf0d351e8cf6c8 Mon Sep 17 00:00:00 2001
From: Botond Baranyi <botond.baranyi@ericsson.com>
Date: Wed, 9 Sep 2020 16:04:41 +0200
Subject: [PATCH] Fixed issues with predefined function 'regexp' (bug 565852)

Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com>
Change-Id: I77f08130f7187b16a82b2ea87c78d5b955d09a7c
---
 common/Quadruple.cc                          |  2 +-
 common/pattern_p.y                           |  4 +++
 common/pattern_uni.y                         | 14 ++++++----
 core/Addfunc.cc                              | 12 ++++++++
 core/Addfunc.hh                              |  4 +++
 regression_test/predefFunction/regex_OK.ttcn | 29 ++++++++++++++++++++
 6 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/common/Quadruple.cc b/common/Quadruple.cc
index f26c3e51d..c215a60b7 100644
--- a/common/Quadruple.cc
+++ b/common/Quadruple.cc
@@ -571,7 +571,7 @@ void QuadSet::do_negate() {
     case QSET_QUAD:
       q2 = it->u.p_quad->get_value() - 1;
       qs->add_negate_interval(q1, q2);
-      q1 = q2.get_value() + 1;
+      q1 = it->u.p_quad->get_value() + 1;
       break;
     case QSET_INTERVAL:
       q2 = it->u.p_interval->get_lower().get_value() - 1;
diff --git a/common/pattern_p.y b/common/pattern_p.y
index 37a6673d7..ef0b6fdbc 100644
--- a/common/pattern_p.y
+++ b/common/pattern_p.y
@@ -317,6 +317,10 @@ RE_Multiply_Statement:
   {
     $$ = mcopystr("+");
   }
+| '#' '(' ')'
+  {
+    $$ = mcopystr("*");
+  }
 | '#' '(' ',' ')'
   {
     $$ = mcopystr("*");
diff --git a/common/pattern_uni.y b/common/pattern_uni.y
index a7929b7ac..929309083 100644
--- a/common/pattern_uni.y
+++ b/common/pattern_uni.y
@@ -236,13 +236,13 @@ RE_Concat_Elem:
 | RE_Multiply_Elem RE_Multiply_Statement
   {
     if ($1 != NULL && $2 != NULL) {
-      $$ = mputstr($1, $2);
-      Free($2);
-    } else {
-      Free($1);
-      Free($2);
+      $$ = mprintf("(%s)%s", $1, $2);
+    }
+    else {
       $$ = NULL;
     }
+    Free($1);
+    Free($2);
   }
 | '*' {$$=mcopystr("(........)*");}
 ;
@@ -275,6 +275,10 @@ RE_Multiply_Statement:
   {
     $$ = mcopystr("+");
   }
+| '#' '(' ')'
+  {
+    $$ = mcopystr("*");
+  }
 | '#' '(' ',' ')'
   {
     $$ = mcopystr("*");
diff --git a/core/Addfunc.cc b/core/Addfunc.cc
index 7ddd2ae23..913f22d04 100644
--- a/core/Addfunc.cc
+++ b/core/Addfunc.cc
@@ -1682,6 +1682,18 @@ UNIVERSAL_CHARSTRING regexp(const UNIVERSAL_CHARSTRING& instr,
   return regexp(instr, expression, (int)groupno, nocase);
 }
 
+CHARSTRING regexp(const CHARSTRING& instr, const UNIVERSAL_CHARSTRING& expression,
+                  int groupno, boolean nocase)
+{
+  return regexp((UNIVERSAL_CHARSTRING)instr, expression, groupno, nocase);
+}
+
+CHARSTRING regexp(const CHARSTRING& instr, const UNIVERSAL_CHARSTRING& expression,
+                  const INTEGER& groupno, boolean nocase)
+{
+  return regexp((UNIVERSAL_CHARSTRING)instr, expression, groupno, nocase);
+}
+
 // regexp() on templates
 
 CHARSTRING regexp(const CHARSTRING_template& instr,
diff --git a/core/Addfunc.hh b/core/Addfunc.hh
index 8a92b13b2..f98915038 100644
--- a/core/Addfunc.hh
+++ b/core/Addfunc.hh
@@ -193,6 +193,10 @@ extern UNIVERSAL_CHARSTRING regexp(const UNIVERSAL_CHARSTRING& instr,
 extern UNIVERSAL_CHARSTRING regexp(const UNIVERSAL_CHARSTRING& instr,
     const CHARSTRING& expression, const INTEGER& groupno,
     boolean nocase);
+extern CHARSTRING regexp(const CHARSTRING& instr,
+    const UNIVERSAL_CHARSTRING& expression, int groupno, boolean nocase);
+extern CHARSTRING regexp(const CHARSTRING& instr,
+    const UNIVERSAL_CHARSTRING& expression, const INTEGER& groupno, boolean nocase);
 // regexp on templates
 extern CHARSTRING regexp(const CHARSTRING_template& instr,
     const CHARSTRING_template& expression, int groupno, boolean nocase);
diff --git a/regression_test/predefFunction/regex_OK.ttcn b/regression_test/predefFunction/regex_OK.ttcn
index 323b3b59b..2ce0ca957 100644
--- a/regression_test/predefFunction/regex_OK.ttcn
+++ b/regression_test/predefFunction/regex_OK.ttcn
@@ -174,10 +174,39 @@ testcase regexp_nocase() runs on PDTestComponent {
   setverdict(pass);
 }
 
+testcase Bug_565852() runs on PDTestComponent {
+  // issue #1: Titan does not support the notation '#()'
+  var charstring cs_input := "xxxxaaaxxxx";
+  var charstring cs_pattern := "x#()(a#(1,))x#()";
+  var charstring cs_result := regexp(cs_input, cs_pattern, 0);
+  var charstring cs_expected := "aaa";
+  if (cs_result != cs_expected) {
+    setverdict(fail, "Test #1 failed. Expected: ", cs_expected, ", got: ", cs_result);
+  }
+  
+  // issue #2: '[^a]' and 'a#(...)' do not work for unversal charstrings
+  var universal charstring us_input := "xxxxaaaxxxx";
+  var universal charstring us_pattern := "*[^a](a#(1,))[^a]*";
+  var universal charstring us_result := regexp(us_input, us_pattern, 0);
+  var universal charstring us_expected := "aaa";
+  if (us_result != us_expected) {
+    setverdict(fail, "Test #2 failed. Expected: ", us_expected, ", got: ", us_result);
+  }
+  
+  // extra issue: regexp(<charstring>, <universal charstring>, ...) generates incorrect code
+  var universal charstring mixed_result := regexp(cs_input, us_pattern, 0);
+  var universal charstring mixed_expected := "aaa";
+  if (mixed_result != mixed_expected) {
+    setverdict(fail, "Test #3 failed. Expected: ", mixed_expected, ", got: ", mixed_result);
+  }
+  setverdict(pass);
+}
+
 control {
 	execute (regexp_char());
 	execute (regexp_degen());
 	execute (regexp_nocase());
+	execute (Bug_565852());
 }
 
 }
-- 
GitLab