-/*
- * Copyright 2001-2007 Internet2
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * UCAID licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the
+ * License at
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
*/
/**
#include "util/XMLHelper.h"
#include <stdarg.h>
+#include <memory>
#include <sstream>
+#include <boost/lexical_cast.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
using namespace xmltooling;
+using namespace xercesc;
+using namespace boost;
using namespace std;
using xmlconstants::XMLTOOLING_NS;
m_processedmsg.erase();
}
-inline const char* get_digit_character()
-{
- static const char s_characters[19] =
- {
- '9'
- , '8'
- , '7'
- , '6'
- , '5'
- , '4'
- , '3'
- , '2'
- , '1'
- , '0'
- , '1'
- , '2'
- , '3'
- , '4'
- , '5'
- , '6'
- , '7'
- , '8'
- , '9'
- };
- static const char *s_mid = s_characters + 9;
-
- return s_mid;
-}
-
-inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, int i)
-{
- char* psz=buf + cchBuf - 1; // Set psz to last char
- *psz = 0; // Set terminating null
-
- do {
- unsigned int lsd = i % 10; // Get least significant
- // digit
-
- i /= 10; // Prepare for next most
- // significant digit
-
- --psz; // Move back
-
- *psz = get_digit_character()[lsd]; // Place the digit
-
- } while(i!=0 && psz>buf);
-
- return psz;
-}
-
void XMLToolingException::addProperties(const params& p)
{
m_processedmsg.erase();
- int i=m_params.size()+1;
- char buf[20];
+ map<string,string>::size_type i = m_params.size() + 1;
const vector<const char*>& v=p.get();
- for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {
- m_params[unsigned_integer_to_string(buf,sizeof(buf),i++)] = *ci;
+ for (vector<const char*>::const_iterator ci = v.begin(); ci != v.end(); ++ci) {
+ try {
+ m_params[lexical_cast<string>(i++)] = *ci;
+ }
+ catch (bad_lexical_cast&) {
+ }
}
}
void XMLToolingException::addProperties(const namedparams& p)
{
m_processedmsg.erase();
- const vector<const char*>& v=p.get();
- for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {
+ const vector<const char*>& v = p.get();
+ for (vector<const char*>::const_iterator ci = v.begin(); ci != v.end(); ++ci) {
m_params.erase(*ci);
m_params[*ci] = *(ci+1);
- ci++; // advance past name to value, then loop will advance it again
+ ++ci; // advance past name to value, then loop will advance it again
}
}
const char* XMLToolingException::getProperty(unsigned int index) const
{
- char buf[20];
- map<string,string>::const_iterator i=m_params.find(unsigned_integer_to_string(buf,sizeof(buf),index));
- return (i==m_params.end()) ? NULL : i->second.c_str();
+ try {
+ map<string,string>::const_iterator i = m_params.find(lexical_cast<string>(index));
+ return (i==m_params.end()) ? nullptr : i->second.c_str();
+ }
+ catch (bad_lexical_cast&) {
+ return nullptr;
+ }
}
const char* XMLToolingException::getProperty(const char* name) const
{
- map<string,string>::const_iterator i=m_params.find(name);
- return (i==m_params.end()) ? NULL : i->second.c_str();
+ map<string,string>::const_iterator i = m_params.find(name);
+ return (i==m_params.end()) ? nullptr : i->second.c_str();
}
const char* XMLToolingException::getMessage() const
return m_processedmsg.c_str();
}
+void xml_encode(string& s, const char* pre, const char* start, const char* post)
+{
+ s += pre;
+ size_t pos;
+ while (start && *start) {
+ pos = strcspn(start, "\"<>&");
+ if (pos > 0) {
+ s.append(start, pos);
+ start += pos;
+ }
+ else {
+ switch (*start) {
+ case '\'': s += "'"; break;
+ case '<': s += "<"; break;
+ case '>': s += ">"; break;
+ case '&': s += "&"; break;
+ default: s += *start;
+ }
+ start++;
+ }
+ }
+ s += post;
+}
+
string XMLToolingException::toString() const
{
- string xml=string("<exception xmlns=\"http://www.opensaml.org/xmltooling\" type=\"") + getClassName() + "\">";
+ string xml=string("<exception xmlns='http://www.opensaml.org/xmltooling' type='") + getClassName() + "'>";
const char* msg=getMessage();
if (msg)
- xml=xml + "<message>" + msg + "</message>";
- for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++)
- xml=xml + "<param name=\"" + i->first + "\">" + i->second + "</param>";
+ xml_encode(xml, "<message>", msg, "</message>");
+ const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();
+ for (map<string,string>::const_iterator i = m_params.begin(); i != m_params.end(); ++i) {
+ xml_encode(xml, "<param name='", i->first.c_str(), "'");
+ xml_encode(xml, ">", encoder->encode(i->second.c_str()).c_str(), "</param>");
+ }
xml+="</exception>";
return xml;
}
string XMLToolingException::toQueryString() const
{
+ string q;
const URLEncoder* enc = XMLToolingConfig::getConfig().getURLEncoder();
- string q("errorType=");
- q = q + enc->encode(getClassName()) + "&errorText=" + enc->encode(what());
- for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++)
- q = q + '&' + i->first + '=' + enc->encode(i->second.c_str());
+ for (map<string,string>::const_iterator i = m_params.begin(); i != m_params.end(); ++i) {
+ if (!q.empty())
+ q += '&';
+ q = q + i->first + '=' + enc->encode(i->second.c_str());
+ }
return q;
}
XMLToolingException* XMLToolingException::fromStream(std::istream& in)
{
- static const XMLCh exception[] = { chLatin_e, chLatin_x, chLatin_c, chLatin_e, chLatin_p, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull };
- static const XMLCh message[] = { chLatin_m, chLatin_e, chLatin_s, chLatin_s, chLatin_a, chLatin_g, chLatin_e, chNull };
- static const XMLCh name[] = { chLatin_n, chLatin_a, chLatin_m, chLatin_e, chNull };
- static const XMLCh param[] = { chLatin_p, chLatin_a, chLatin_r, chLatin_a, chLatin_m, chNull };
- static const XMLCh type[] = { chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };
+ static const XMLCh exception[] = UNICODE_LITERAL_9(e,x,c,e,p,t,i,o,n);
+ static const XMLCh message[] = UNICODE_LITERAL_7(m,e,s,s,a,g,e);
+ static const XMLCh name[] = UNICODE_LITERAL_4(n,a,m,e);
+ static const XMLCh param[] = UNICODE_LITERAL_5(p,a,r,a,m);
+ static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e);
DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
throw XMLToolingException("Invalid root element on serialized exception.");
}
- auto_ptr_char classname(root->getAttributeNS(NULL,type));
+ auto_ptr_char classname(root->getAttributeNS(nullptr,type));
auto_ptr<XMLToolingException> excep(XMLToolingException::getInstance(classname.get()));
DOMElement* child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,message);
excep->setMessage(m.get());
}
+ const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();
child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,param);
while (child && child->hasChildNodes()) {
- auto_ptr_char n(child->getAttributeNS(NULL,name));
- char* v=toUTF8(child->getFirstChild()->getNodeValue());
- if (n.get() && v)
- excep->addProperty(n.get(), v);
- XMLString::release(&v);
- child=XMLHelper::getNextSiblingElement(root,XMLTOOLING_NS,param);
+ auto_ptr_char n(child->getAttributeNS(nullptr,name));
+ char* encoded = XMLString::transcode(child->getFirstChild()->getNodeValue());
+ if (n.get() && encoded) {
+ encoder->decode(encoded);
+ excep->addProperty(n.get(), encoded);
+ }
+ XMLString::release(&encoded);
+ child=XMLHelper::getNextSiblingElement(child,XMLTOOLING_NS,param);
}
doc->release();