Work around Solaris issue
[shibboleth/cpp-sp.git] / shibsp / attribute / resolver / impl / XMLAttributeExtractor.cpp
index 3f12eb8..37e77dd 100644 (file)
@@ -124,7 +124,7 @@ namespace shibsp {
         typedef map< pair<xstring,xstring>,pair< boost::shared_ptr<AttributeDecoder>,vector<string> > > attrmap_t;
         attrmap_t m_attrMap;
         vector<string> m_attributeIds;
-        vector< tuple<xstring,xstring,bool> > m_requestedAttrs;
+        vector< boost::tuple<xstring,xstring,bool> > m_requestedAttrs;
 
         // settings for embedded assertions in metadata
         string m_policyId;
@@ -142,7 +142,7 @@ namespace shibsp {
     class XMLExtractor : public AttributeExtractor, public ReloadableXMLFile
     {
     public:
-        XMLExtractor(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.XML")) {
+        XMLExtractor(const DOMElement* e) : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT ".AttributeExtractor.XML")) {
             if (m_local && m_lock)
                 m_log.warn("attribute mappings are reloadable; be sure to restart web server when adding new attribute IDs");
             background_load();
@@ -320,7 +320,17 @@ XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log)
             format = &chNull;  // ignore default Format/Namespace values
 
         // Fetch/create the map entry and see if it's a duplicate rule.
-        pair< boost::shared_ptr<AttributeDecoder>,vector<string> >& decl = m_attrMap[pair<xstring,xstring>(name,format)];
+        // Trim the format, or the name only if the format is the default (URI).
+        pair<xstring,xstring> entryKey;
+        if (*format == chNull) {
+            auto_ptr_XMLCh copyName(name);
+            entryKey.first = copyName.get();
+        } else {
+            entryKey.first = name;
+            auto_ptr_XMLCh copyFormat(format);
+            entryKey.second = copyFormat.get();
+        }
+        pair< boost::shared_ptr<AttributeDecoder>,vector<string> >& decl = m_attrMap[entryKey];
         if (decl.first) {
             m_log.warn("skipping duplicate Attribute mapping (same name and nameFormat)");
             child = XMLHelper::getNextSiblingElement(child, shibspconstants::SHIB2ATTRIBUTEMAP_NS, saml1::Attribute::LOCAL_NAME);
@@ -328,8 +338,8 @@ XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log)
         }
 
         if (m_log.isInfoEnabled()) {
-            auto_ptr_char n(name);
-            auto_ptr_char f(format);
+            auto_ptr_char n(entryKey.first.c_str());
+            auto_ptr_char f(entryKey.second.c_str());
             m_log.info("creating mapping for Attribute %s%s%s", n.get(), *f.get() ? ", Format/Namespace:" : "", f.get());
         }
 
@@ -340,15 +350,15 @@ XMLExtractorImpl::XMLExtractorImpl(const DOMElement* e, Category& log)
         // Check for isRequired/isRequested.
         bool requested = XMLHelper::getAttrBool(child, false, isRequested);
         bool required = XMLHelper::getAttrBool(child, false, RequestedAttribute::ISREQUIRED_ATTRIB_NAME);
-        if (required || requested)
-            m_requestedAttrs.push_back(tuple<xstring,xstring,bool>(name,format,required));
+        if (required || requested) {
+            m_requestedAttrs.push_back(boost::tuple<xstring,xstring,bool>(entryKey.first, entryKey.second, required));
+        }
 
         name = child->getAttributeNS(nullptr, _aliases);
         if (name && *name) {
             m_log.warn("attribute mapping rule (%s) uses deprecated aliases feature, consider revising", id.get());
             auto_ptr_char aliases(name);
             string dup(aliases.get());
-            trim(dup);
             set<string> new_aliases;
             split(new_aliases, dup, is_space(), algorithm::token_compress_on);
             set<string>::iterator ru = new_aliases.find("REMOTE_USER");
@@ -387,7 +397,7 @@ void XMLExtractorImpl::generateMetadata(SPSSODescriptor& role) const
     static const XMLCh english[] = UNICODE_LITERAL_2(e,n);
     sn->setLang(english);
 
-    for (vector< tuple<xstring,xstring,bool> >::const_iterator i = m_requestedAttrs.begin(); i != m_requestedAttrs.end(); ++i) {
+    for (vector< boost::tuple<xstring,xstring,bool> >::const_iterator i = m_requestedAttrs.begin(); i != m_requestedAttrs.end(); ++i) {
         RequestedAttribute* req = RequestedAttributeBuilder::buildRequestedAttribute();
         svc->getRequestedAttributes().push_back(req);
         req->setName(i->get<0>().c_str());