From 9b0941e96b4c1112e37791e1395ce492bec3872a Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Sat, 6 Nov 2010 19:20:00 +0000 Subject: [PATCH] Collapse feeds to a single array, sanitize JSON strings. --- saml/saml2/metadata/DiscoverableMetadataProvider.h | 8 +-- .../metadata/impl/ChainingMetadataProvider.cpp | 13 +++-- .../metadata/impl/DiscoverableMetadataProvider.cpp | 61 ++++++++++++++++++---- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/saml/saml2/metadata/DiscoverableMetadataProvider.h b/saml/saml2/metadata/DiscoverableMetadataProvider.h index daa78fe..d86513a 100644 --- a/saml/saml2/metadata/DiscoverableMetadataProvider.h +++ b/saml/saml2/metadata/DiscoverableMetadataProvider.h @@ -75,10 +75,12 @@ namespace opensaml { * Outputs the cached feed. *

The provider MUST be locked. * - * @param os stream to output feed into - * @return a reference to the output stream + * @param os stream to output feed into + * @param first on input, indicates if the feed is first in position, + * on output will be false if the feed was non-empty + * @param wrapArray true iff the feed array should be opened/closed by this provider */ - virtual std::ostream& outputFeed(std::ostream& os) const; + virtual void outputFeed(std::ostream& os, bool& first, bool wrapArray=true) const; protected: /** Storage for feed. */ diff --git a/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp b/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp index ef2a3ec..0ba3c0e 100644 --- a/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp @@ -72,20 +72,19 @@ namespace opensaml { return m_feedTag; } - ostream& outputFeed(ostream& os) const { - os << "[\n"; + void outputFeed(ostream& os, bool& first, bool wrapArray=true) const { + if (wrapArray) + os << '['; // Lock each provider in turn and suck in its feed. for (vector::const_iterator m = m_providers.begin(); m != m_providers.end(); ++m) { - if (m != m_providers.begin()) - os << ",\n"; DiscoverableMetadataProvider* d = dynamic_cast(*m); if (d) { Locker locker(d); - d->outputFeed(os); + d->outputFeed(os, first, false); } } - os << ']'; - return os; + if (wrapArray) + os << "\n]"; } void onEvent(const ObservableMetadataProvider& provider) const { diff --git a/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp b/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp index fafce23..e3f8925 100644 --- a/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/DiscoverableMetadataProvider.cpp @@ -47,11 +47,9 @@ DiscoverableMetadataProvider::~DiscoverableMetadataProvider() void DiscoverableMetadataProvider::generateFeed() { bool first = true; - m_feed = "["; const XMLObject* object = getMetadata(); disco(m_feed, dynamic_cast(object), first); disco(m_feed, dynamic_cast(object), first); - m_feed += "\n]"; SAMLConfig::getConfig().generateRandomBytes(m_feedTag, 4); m_feedTag = SAMLArtifact::toHex(m_feedTag); @@ -62,9 +60,50 @@ string DiscoverableMetadataProvider::getCacheTag() const return m_feedTag; } -ostream& DiscoverableMetadataProvider::outputFeed(ostream& os) const +void DiscoverableMetadataProvider::outputFeed(ostream& os, bool& first, bool wrapArray) const { - return os << m_feed; + if (wrapArray) + os << '['; + if (!m_feed.empty()) { + if (first) + first = false; + else + os << ",\n"; + os << m_feed; + } + if (wrapArray) + os << "\n]"; +} + +static string& json_safe(string& s, const char* buf) +{ + for (; *buf; ++buf) { + switch (*buf) { + case '\\': + case '"': + s += '\\'; + s += *buf; + break; + case '\b': + s += "\\b"; + break; + case '\t': + s += "\\t"; + break; + case '\n': + s += "\\n"; + break; + case '\f': + s += "\\f"; + break; + case '\r': + s += "\\r"; + break; + default: + s += *buf; + } + } + return s; } void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* entity, bool& first) const @@ -80,7 +119,7 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti else s += ','; s += "\n{\n \"entityID\": \""; - s += entityid.get(); + json_safe(s, entityid.get()); s += '\"'; bool extFound = false; for (vector::const_iterator idp = idps.begin(); !extFound && idp != idps.end(); ++idp) { @@ -99,7 +138,7 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti auto_arrayptr val(toUTF8((*dispname)->getName())); auto_ptr_char lang((*dispname)->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -116,7 +155,7 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti auto_arrayptr val(toUTF8((*desc)->getDescription())); auto_ptr_char lang((*desc)->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -133,7 +172,7 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti auto_ptr_char val((*infurl)->getURL()); auto_ptr_char lang((*infurl)->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -150,7 +189,7 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti auto_ptr_char val((*priv)->getURL()); auto_ptr_char lang((*priv)->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; @@ -167,7 +206,7 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti s += "\n {\n"; auto_ptr_char val((*logo)->getURL()); s += " \"value\": \""; - s += val.get(); + json_safe(s, val.get()); ostringstream ht; ht << (*logo)->getHeight().second; s += "\",\n \"height\": \""; @@ -210,7 +249,7 @@ void DiscoverableMetadataProvider::disco(string& s, const EntityDescriptor* enti auto_arrayptr val(toUTF8((*dispname)->getName())); auto_ptr_char lang((*dispname)->getLang()); s += "\n {\n \"value\": \""; - s += val.get(); + json_safe(s, val.get()); s += "\",\n \"lang\": \""; s += lang.get(); s += "\"\n }"; -- 2.1.4