SSPCPP-616 - fix tuple namespaces and string literal errors
[shibboleth/cpp-sp.git] / plugins / TransformAttributeResolver.cpp
index 6925722..5dfcaa1 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <algorithm>
 #include <boost/shared_ptr.hpp>
+#include <boost/algorithm/string/trim.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <shibsp/exceptions.h>
 #include <shibsp/SessionCache.h>
@@ -50,20 +51,17 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL TransformContext : public ResolutionContext
     {
     public:
-        TransformContext(const Session& session) : m_inputAttributes(&session.getAttributes()) {
-        }
-
-        TransformContext(const vector<shibsp::Attribute*>* attributes) : m_inputAttributes(attributes) {
+        TransformContext(const vector<Attribute*>* attributes) : m_inputAttributes(attributes) {
         }
 
         ~TransformContext() {
-            for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<shibsp::Attribute>());
+            for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<Attribute>());
         }
 
-        const vector<shibsp::Attribute*>* getInputAttributes() const {
+        const vector<Attribute*>* getInputAttributes() const {
             return m_inputAttributes;
         }
-        vector<shibsp::Attribute*>& getResolvedAttributes() {
+        vector<Attribute*>& getResolvedAttributes() {
             return m_attributes;
         }
         vector<opensaml::Assertion*>& getResolvedAssertions() {
@@ -71,8 +69,8 @@ namespace shibsp {
         }
 
     private:
-        const vector<shibsp::Attribute*>* m_inputAttributes;
-        vector<shibsp::Attribute*> m_attributes;
+        const vector<Attribute*>* m_inputAttributes;
+        vector<Attribute*> m_attributes;
         static vector<opensaml::Assertion*> m_assertions;   // empty dummy
     };
 
@@ -97,7 +95,7 @@ namespace shibsp {
             const XMLCh* authncontext_class=nullptr,
             const XMLCh* authncontext_decl=nullptr,
             const vector<const opensaml::Assertion*>* tokens=nullptr,
-            const vector<shibsp::Attribute*>* attributes=nullptr
+            const vector<Attribute*>* attributes=nullptr
             ) const {
             // Make sure new method gets run.
             return createResolutionContext(application, nullptr, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens, attributes);
@@ -112,13 +110,13 @@ namespace shibsp {
             const XMLCh* authncontext_class=nullptr,
             const XMLCh* authncontext_decl=nullptr,
             const vector<const opensaml::Assertion*>* tokens=nullptr,
-            const vector<shibsp::Attribute*>* attributes=nullptr
+            const vector<Attribute*>* attributes=nullptr
             ) const {
             return new TransformContext(attributes);
         }
 
         ResolutionContext* createResolutionContext(const Application& application, const Session& session) const {
-            return new TransformContext(session);
+            return new TransformContext(&session.getAttributes());
         }
 
         void resolveAttributes(ResolutionContext& ctx) const;
@@ -134,7 +132,7 @@ namespace shibsp {
         Category& m_log;
         string m_source;
         // dest id, regex to apply, replacement string
-        typedef tuple<string,boost::shared_ptr<RegularExpression>,const XMLCh*> regex_t;
+        typedef boost::tuple<string,boost::shared_ptr<RegularExpression>,const XMLCh*> regex_t;
         vector<regex_t> m_regex;
     };
 
@@ -154,7 +152,7 @@ namespace shibsp {
 vector<opensaml::Assertion*> TransformContext::m_assertions;
 
 TransformAttributeResolver::TransformAttributeResolver(const DOMElement* e)
-    : m_log(Category::getInstance(SHIBSP_LOGCAT".AttributeResolver.Transform")),
+    : m_log(Category::getInstance(SHIBSP_LOGCAT ".AttributeResolver.Transform")),
         m_source(XMLHelper::getAttrString(e, nullptr, source))
 {
     if (m_source.empty())
@@ -170,7 +168,7 @@ TransformAttributeResolver::TransformAttributeResolver(const DOMElement* e)
                 try {
                     static XMLCh options[] = { chLatin_i, chNull };
                     boost::shared_ptr<RegularExpression> re(new RegularExpression(e->getAttributeNS(nullptr, match), (caseflag ? &chNull : options)));
-                    m_regex.push_back(make_tuple(destId, re, repl));
+                    m_regex.push_back(boost::make_tuple(destId, re, repl));
                 }
                 catch (XMLException& ex) {
                     auto_ptr_char msg(ex.getMessage());
@@ -226,21 +224,29 @@ void TransformAttributeResolver::resolveAttributes(ResolutionContext& ctx) const
                 m_log.debug("applying transform from source attribute (%s) to dest attribute (%s)", m_source.c_str(), r->get<0>().c_str());
 
             for (size_t i = 0; i < (*a)->valueCount(); ++i) {
-                auto_arrayptr<XMLCh> srcval(fromUTF8((*a)->getSerializedValues()[i].c_str()));
                 try {
+                    auto_arrayptr<XMLCh> srcval(fromUTF8((*a)->getSerializedValues()[i].c_str()));
                     XMLCh* destval = r->get<1>()->replace(srcval.get(), r->get<2>());
-                    if (destval) {
+                    if (!destval)
+                        continue;
+                    // For some reason, it returns the source string if the match doesn't succeed.
+                    if (!XMLString::equals(destval, srcval.get())) {
                         auto_arrayptr<char> narrow(toUTF8(destval));
                         XMLString::release(&destval);
                         if (dest) {
                             // Modify in place.
                             dest->getValues()[i] = narrow.get();
+                            trim(dest->getValues()[i]);
                         }
                         else {
                             // Add to new object.
                             destwrapper->getValues().push_back(narrow.get());
+                            trim(destwrapper->getValues().back());
                         }
                     }
+                    else {
+                        XMLString::release(&destval);
+                    }
                 }
                 catch (XMLException& ex) {
                     auto_ptr_char msg(ex.getMessage());