/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
if (!m_output.isstruct())
m_output.structure();
- m_output.addmember("redirect").string(url);
+ m_output.addmember("redirect").unsafe_string(url);
return HTTPResponse::XMLTOOLING_HTTP_STATUS_MOVED;
}
DDF in = DDF(m_address.c_str()).structure();
in.addmember("application_id").string(request.getApplication().getId());
in.addmember("scheme").string(request.getScheme());
- in.addmember("hostname").string(request.getHostname());
+ in.addmember("hostname").unsafe_string(request.getHostname());
in.addmember("port").integer(request.getPort());
in.addmember("content_type").string(request.getContentType().c_str());
in.addmember("content_length").integer(request.getContentLength());
in.addmember("remote_user").string(request.getRemoteUser().c_str());
in.addmember("client_addr").string(request.getRemoteAddr().c_str());
in.addmember("method").string(request.getMethod());
- in.addmember("uri").string(request.getRequestURI());
- in.addmember("url").string(request.getRequestURL());
+ in.addmember("uri").unsafe_string(request.getRequestURI());
+ in.addmember("url").unsafe_string(request.getRequestURL());
in.addmember("query").string(request.getQueryString());
if (headers) {
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// constructors
DDF() : m_handle(NULL) {}
DDF(const char* n);
- DDF(const char* n, const char* val);
+ DDF(const char* n, const char* val, bool safe=true);
DDF(const char* n, long val);
DDF(const char* n, double val);
DDF(const char* n, void* val);
DDF& string(const char* val) {
return string(const_cast<char*>(val), true);
}
- DDF& string(char* val, bool copyit=true);
+ DDF& unsafe_string(const char* val) {
+ return string(const_cast<char*>(val), true, false);
+ }
+ DDF& string(char* val, bool copyit=true, bool safe=true);
DDF& string(long val);
DDF& string(double val);
DDF& integer(long val);
/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/ParserPool.h>
+#include <xmltooling/util/URLEncoder.h>
#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
DDF_FLOAT,
DDF_STRUCT,
DDF_LIST,
- DDF_POINTER
+ DDF_POINTER,
+ DDF_STRING_UNSAFE
} type; // data type of node
union {
name(n);
}
-DDF::DDF(const char* n, const char* val)
+DDF::DDF(const char* n, const char* val, bool safe)
{
m_handle=new(nothrow) ddf_body_t;
name(n);
- string(val);
+ string(const_cast<char*>(val), true, safe);
}
DDF::DDF(const char* n, long val)
case ddf_body_t::DDF_EMPTY:
return DDF(m_handle->name);
case ddf_body_t::DDF_STRING:
- return DDF(m_handle->name,m_handle->value.string);
+ case ddf_body_t::DDF_STRING_UNSAFE:
+ return DDF(m_handle->name,m_handle->value.string,(m_handle->type==ddf_body_t::DDF_STRING));
case ddf_body_t::DDF_INT:
return DDF(m_handle->name,m_handle->value.integer);
case ddf_body_t::DDF_FLOAT:
bool DDF::isstring() const
{
- return m_handle ? (m_handle->type==ddf_body_t::DDF_STRING) : false;
+ return m_handle ? (m_handle->type==ddf_body_t::DDF_STRING || m_handle->type==ddf_body_t::DDF_STRING_UNSAFE) : false;
}
bool DDF::isint() const
return *this;
}
-DDF& DDF::string(char* val, bool copyit)
+DDF& DDF::string(char* val, bool copyit, bool safe)
{
if (empty().m_handle) {
m_handle->value.string = copyit ? ddf_strdup(val) : val;
if (!m_handle->value.string && val && *val)
return destroy();
- m_handle->type=ddf_body_t::DDF_STRING;
+ m_handle->type=(safe ? ddf_body_t::DDF_STRING : ddf_body_t::DDF_STRING_UNSAFE);
}
return *this;
}
break;
case ddf_body_t::DDF_STRING:
+ case ddf_body_t::DDF_STRING_UNSAFE:
if (m_handle->name)
fprintf(f,"char* %s = ",m_handle->name);
else
switch (p->type) {
case ddf_body_t::DDF_STRING:
+ case ddf_body_t::DDF_STRING_UNSAFE:
os << "<string";
if (name_attr && p->name) {
os << " name=\"";
os << '"';
}
if (p->value.string) {
- os << '>';
- xml_encode(os,p->value.string);
+ if (p->type == ddf_body_t::DDF_STRING) {
+ os << '>';
+ xml_encode(os,p->value.string);
+ }
+ else {
+ os << " unsafe=\"1\">";
+ xml_encode(os,XMLToolingConfig::getConfig().getURLEncoder()->encode(p->value.string).c_str());
+ }
os << "</string>";
}
else
static const XMLCh _array[] = UNICODE_LITERAL_5(a,r,r,a,y);
static const XMLCh _struct[] = UNICODE_LITERAL_6(s,t,r,u,c,t);
static const XMLCh _lowercase[] = UNICODE_LITERAL_9(l,o,w,e,r,c,a,s,e);
+static const XMLCh _unsafe[] = UNICODE_LITERAL_6(u,n,s,a,f,e);
DDF deserialize(DOMElement* root, bool lowercase)
{
DDF obj(NULL);
- auto_ptr_char name_val(root->getAttribute(_name));
+ auto_ptr_char name_val(root->getAttributeNS(NULL, _name));
if (name_val.get() && *name_val.get()) {
if (lowercase)
for (char* pch=const_cast<char*>(name_val.get()); *pch=tolower(*pch); pch++);
if (XMLString::equals(tag,_string)) {
DOMNode* child=root->getFirstChild();
if (child && child->getNodeType()==DOMNode::TEXT_NODE) {
- char* val = toUTF8(child->getNodeValue(), true); // use malloc
- if (val)
- obj.string(val, false); // don't re-copy the string
+ const XMLCh* unsafe = root->getAttributeNS(NULL, _unsafe);
+ if (unsafe && *unsafe==chDigit_1) {
+ // If it's unsafe, it's not UTF-8 data, so we have to convert to ASCII and decode it.
+ char* encoded = XMLString::transcode(child->getNodeValue());
+ XMLToolingConfig::getConfig().getURLEncoder()->decode(encoded);
+ obj.string(encoded, true, false); // re-copy into free-able buffer, plus mark unsafe
+ XMLString::release(&encoded);
+ }
+ else {
+ char* val = toUTF8(child->getNodeValue(), true); // use malloc
+ if (val)
+ obj.string(val, false); // don't re-copy the string
+ }
}
}
else if (XMLString::equals(tag,_number)) {