From 5698b7a0d72ac79ef5b71d8477f323c27de6f27f Mon Sep 17 00:00:00 2001
From: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
Date: Wed, 2 Nov 2016 15:04:16 +0100
Subject: [PATCH] XER: anyelement xmlns attribute added if it is surely known
 (Bug 506877)

Change-Id: I2bf5f6f9bc9e05bd0f0ea56dcd08637b736ed768
Signed-off-by: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
---
 core/Universal_charstring.cc                  | 25 ++++++++-
 .../XML/EXER-whitepaper/AnyElement.ttcnpp     | 56 +++++++++++++++++++
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/core/Universal_charstring.cc b/core/Universal_charstring.cc
index df2e416de..ae789fbbe 100644
--- a/core/Universal_charstring.cc
+++ b/core/Universal_charstring.cc
@@ -1878,7 +1878,30 @@ int UNIVERSAL_CHARSTRING::XER_encode(const XERdescriptor_t& p_td,
           if (checker.NodeType() == XML_READER_TYPE_ELEMENT &&
               (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT))) {
             const char* xmlns = (const char*)checker.NamespaceUri();
-            check_namespace_restrictions(p_td, xmlns);
+            // If no xmlns attribute found, and only one namespace is allowed then
+            // append the xmlns attribute with the namespace.
+            if (xmlns == NULL && (p_td.xer_bits & ANY_FROM) && p_td.nof_ns_uris == 1 &&
+                p_td.ns_uris[0] != NULL && strlen(p_td.ns_uris[0]) != 0) {
+              // Find the position of the '>' character
+              const char * pos = strchr((const char*)(other_buf.get_data()), '>');
+              int index = (int)(pos - (const char*)other_buf.get_data());
+              
+              // Create a new TTCN_Buffer which will contain the anyelement with
+              // the xmlns attribute.
+              TTCN_Buffer new_buf;
+              new_buf.put_s(index, other_buf.get_data());
+              new_buf.put_s(8, (const unsigned char*)" xmlns='");
+              size_t len = strlen(p_td.ns_uris[0]);
+              new_buf.put_s(len, (const unsigned char*)p_td.ns_uris[0]);
+              new_buf.put_c('\'');
+              
+              other_buf.set_pos(index);
+              len = strlen((const char*)other_buf.get_read_data());
+              new_buf.put_s(len, other_buf.get_read_data());
+              other_buf = new_buf;
+            } else {
+              check_namespace_restrictions(p_td, xmlns);
+            }
           }
         }
           
diff --git a/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp b/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp
index 31b4e3559..6752ac5a6 100644
--- a/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp
+++ b/regression_test/XML/EXER-whitepaper/AnyElement.ttcnpp
@@ -351,6 +351,59 @@ testcase decode_only() runs on AE
   CHECK_DECODE(exer_dec_aaoa, estr_marx, anys_and_only_anys, marx_dec);
 }
 
+/* * * * * * * * * * * * */
+// ANY-ELEMENT with only one allowed namespace.
+
+type record AEProductSingle {
+  charstring name,
+  integer    price,
+  universal charstring info
+}
+with {
+  variant (info) "anyElement from 'http://www.example.com/A'"
+}
+
+DECLARE_XER_ENCODERS(AEProductSingle, aes);
+DECLARE_EXER_ENCODERS(AEProductSingle, aes);
+
+const AEProductSingle aesp := {
+  name  := "Trousers",
+  price := 20,
+  info  := "<color available=""true"">red</color>"
+}
+
+const AEProductSingle aesp_e := {
+  name  := "Trousers",
+  price := 20,
+  info  := "<color xmlns=\"http://www.example.com/A\" available=\"true\">red</color>"
+}
+
+const universal charstring str_aes_e :=
+"<AEProductSingle>\n" &
+"\t<name>Trousers</name>\n" &
+"\t<price>20</price>\n" &
+"\t<color available=\"true\" xmlns='http://www.example.com/A'>red</color>\n" &
+"</AEProductSingle>\n\n";
+
+const universal charstring str_aes_b :=
+"<AEProductSingle>\n" &
+"\t<name>Trousers</name>\n" &
+"\t<price>20</price>\n" &
+"\t<info>&lt;color available=&quot;true&quot;&gt;red&lt;/color&gt;</info>\n" &
+"</AEProductSingle>\n\n";
+
+testcase encode_aes() runs on AE
+{
+  CHECK_METHOD(bxer_enc_aes, aesp, str_aes_b);
+  CHECK_METHOD(exer_enc_aes, aesp, str_aes_e);
+}
+
+testcase decode_aes() runs on AE
+{
+  CHECK_DECODE(bxer_dec_aes, str_aes_b, AEProductSingle, aesp);
+  CHECK_DECODE(exer_dec_aes, str_aes_e, AEProductSingle, aesp_e);
+}
+
 control
 {
   execute(encode_ae())
@@ -367,6 +420,9 @@ control
   
   execute(encode_only())
   execute(decode_only())
+
+  execute(encode_aes())
+  execute(decode_aes())
 }
 
 }
-- 
GitLab