Escape xml pre-defined entities in native (de-)serialization.

* include/abg-libxml-utils.h (escape_xml_string)
	(unescape_xml_string): Declare new functions.
	* src/abg-libxml-utils.cc (escape_xml_string)
	(unescape_xml_string): Define them.
	* src/abg-reader.cc (build_function_decl, build_var_decl)
	(build_type_decl, build_enum_type_decl, build_class_decl)
	(build_type_tparameter, build_non_type_tparameter)
	(build_template_tparameter, handle_namespace_decl)
	(handle_typedef_decl): Use unescape_xml_string.
	* src/abg-writer.cc (write_type_decl, write_function_decl)
	(write_class_decl, write_type_tparameter)
	(write_non_type_tparameter, write_template_tparameter): Use
	escape_xml_string.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2014-01-13 16:38:57 +01:00
parent 5f97fc781c
commit c4991c6444
4 changed files with 192 additions and 24 deletions

View File

@ -98,5 +98,20 @@ int get_xml_node_depth(xmlNodePtr);
#define CHAR_STR(xml_char_str) \
reinterpret_cast<char*>(xml_char_str.get())
void
escape_xml_string(const std::string& str,
std::string& escaped);
std::string
escape_xml_string(const std::string& str);
void
unescape_xml_string(const std::string& str,
std::string& escaped);
std::string
unescape_xml_string(const std::string& str);
}//end namespace xml
}//end namespace abigail

View File

@ -146,5 +146,155 @@ get_xml_node_depth(xmlNodePtr n)
return 1 + get_xml_node_depth(n->parent);
}
/// Escape the 5 characters representing the predefined XML entities.
///
/// The resulting entities and their matching characters are:
///
/// &lt; for the character '<', &gt; for the character '>', &apos; for
/// the character ''', &quot; for the character '"', and &amp; for the
/// character '&'.
///
//// @param str the input string to read to search for the characters
//// to escape.
////
//// @param the output string where to write the resulting string that
//// contains the pre-defined characters escaped as predefined
//// entitites.
void
escape_xml_string(const std::string& str,
std::string& escaped)
{
for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
switch (*i)
{
case '<':
escaped += "&lt;";
break;
case '>':
escaped += "&gt;";
break;
case '&':
escaped += "&amp;";
break;
case '\'':
escaped += "&apos;";
break;
case '"':
escaped += "&quot;";
break;
default:
escaped += *i;
}
}
/// Escape the 5 characters representing the predefined XML entities.
///
/// The resulting entities and their matching characters are:
///
/// &lt; for the character '<', &gt; for the character '>', &apos; for
/// the character ''', &quot; for the character '"', and &amp; for the
/// character '&'.
///
//// @param str the input string to read to search for the characters
//// to escape.
////
//// @return the resulting string that contains the pre-defined
//// characters escaped as predefined entitites.
std::string
escape_xml_string(const std::string& str)
{
std::string result;
escape_xml_string(str, result);
return result;
}
/// Read a string, detect the 5 predefined XML entities it may contain
/// and un-escape them, by writting their corresponding characters
/// back in. The pre-defined entities are:
///
/// &lt; for the character '<', &gt; for the character '>', &apos; for
/// the character ''', &quot; for the character '"', and &amp; for the
/// character '&'.
///
/// @param str the input XML string to consider.
///
/// @param escaped where to write the resulting un-escaped string.
void
unescape_xml_string(const std::string& str,
std::string& escaped)
{
std::string::size_type i = 0;
while (i < str.size())
{
if (str[i] == '&')
{
if (str[i+1] == 'l'
&& str[i+2] == 't'
&& str[i+3] == ';')
{
escaped += '<';
i+= 4;
}
else if (str[i+1] == 'g'
&& str[i+2] == 't'
&& str[i+3] == ';')
{
escaped += '>';
i += 4;
}
else if (str[i+1] == 'a'
&& str[i+2] == 'm'
&& str[i+3] == 'p'
&& str[i+4] == ';')
{
escaped += '&';
i += 5;
}
else if (str[i+1] == 'a'
&& str[i+2] == 'p'
&& str[i+3] == 'o'
&& str[i+4] == 's'
&& str[i+5] == ';')
{
escaped += '\'';
i += 6;
}
else if (str[i+1] == 'q'
&& str[i+2] == 'u'
&& str[i+3] == 'o'
&& str[i+4] == 't'
&& str[i+5] == ';')
{
escaped += '"';
i += 6;
}
}
else
{
escaped += str[i];
++i;
}
}
}
/// Read a string, detect the 5 predefined XML entities it may contain
/// and un-escape them, by writting their corresponding characters
/// back in. The pre-defined entities are:
///
/// &lt; for the character '<', &gt; for the character '>', &apos; for
/// the character ''', &quot; for the character '"', and &amp; for the
/// character '&'.
///
/// @param str the input XML string to consider.
///
/// @return escaped where to write the resulting un-escaped string.
std::string
unescape_xml_string(const std::string& str)
{
std::string result;
unescape_xml_string(str, result);
return result;
}
}//end namespace xml
}//end namespace abigail

View File

@ -1228,11 +1228,11 @@ build_function_decl(read_context& ctxt,
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
string mangled_name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
mangled_name = CHAR_STR(s);
mangled_name = xml::unescape_xml_string(CHAR_STR(s));
string inline_prop;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "declared-inline"))
@ -1314,18 +1314,17 @@ build_var_decl(read_context& ctxt, const xmlNodePtr node,
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
string type_id;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
type_id = CHAR_STR(s);
shared_ptr<type_base> underlying_type = ctxt.get_type_decl(type_id);
if (!underlying_type)
return nil;
assert(underlying_type);
string mangled_name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
mangled_name = CHAR_STR(s);
mangled_name = xml::unescape_xml_string(CHAR_STR(s));
decl_base::visibility vis = decl_base::VISIBILITY_NONE;
read_visibility(node, vis);
@ -1367,7 +1366,7 @@ build_type_decl(read_context& ctxt,
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
string id;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
@ -1593,7 +1592,7 @@ build_enum_type_decl(read_context& ctxt, const xmlNodePtr node,
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
location loc;
read_location(ctxt, node, loc);
@ -1627,7 +1626,7 @@ build_enum_type_decl(read_context& ctxt, const xmlNodePtr node,
xml_char_sptr a = xml::build_sptr(xmlGetProp(n, BAD_CAST("name")));
if (a)
name = CHAR_STR(a);
name = xml::unescape_xml_string(CHAR_STR(a));
a = xml::build_sptr(xmlGetProp(n, BAD_CAST("value")));
if (a)
@ -1721,7 +1720,7 @@ build_class_decl(read_context& ctxt, const xmlNodePtr node,
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
size_t size_in_bits = 0, alignment_in_bits = 0;
read_size_and_alignment(node, size_in_bits, alignment_in_bits);
@ -2120,11 +2119,11 @@ build_type_tparameter(read_context& ctxt, const xmlNodePtr node,
if (!type_id.empty()
&& !(result = dynamic_pointer_cast<type_tparameter>
(ctxt.get_type_decl(type_id))))
return nil;
abort();
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
location loc;
read_location(ctxt, node,loc);
@ -2227,11 +2226,11 @@ build_non_type_tparameter(read_context& ctxt,
shared_ptr<type_base> type;
if (type_id.empty()
|| !(type = ctxt.get_type_decl(type_id)))
return r;
abort();
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
location loc;
read_location(ctxt, node,loc);
@ -2284,7 +2283,7 @@ build_template_tparameter(read_context& ctxt,
string name;
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
location loc;
read_location(ctxt, node, loc);
@ -2420,7 +2419,7 @@ handle_namespace_decl(read_context& ctxt)
string name;
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
location loc;
read_location(ctxt, loc);
@ -2611,7 +2610,7 @@ handle_typedef_decl(read_context& ctxt)
string name;
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "name"))
name = CHAR_STR(s);
name = xml::unescape_xml_string(CHAR_STR(s));
string type_id;
if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(r, "type-id"))

View File

@ -34,6 +34,7 @@
#include "abg-corpus.h"
#include "abg-libzip-utils.h"
#include "abg-writer.h"
#include "abg-libxml-utils.h"
namespace abigail
{
@ -768,7 +769,7 @@ write_type_decl(const shared_ptr<type_decl> d, write_context& ctxt,
do_indent(o, indent);
o << "<type-decl name='" << d->get_name() << "'";
o << "<type-decl name='" << xml::escape_xml_string(d->get_name()) << "'";
write_size_and_alignment(d, o);
@ -1084,10 +1085,13 @@ write_function_decl(const shared_ptr<function_decl> decl, write_context& ctxt,
do_indent(o, indent);
o << "<function-decl name='" << decl->get_name() << "'";
o << "<function-decl name='"
<< xml::escape_xml_string(decl->get_name())
<< "'";
if (!decl->get_mangled_name().empty())
o << " mangled-name='" << decl->get_mangled_name() << "'";
o << " mangled-name='"
<< xml::escape_xml_string(decl->get_mangled_name()) << "'";
write_location(decl, o);
@ -1156,7 +1160,7 @@ write_class_decl(const shared_ptr<class_decl> decl,
do_indent_to_level(ctxt, indent, 0);
o << "<class-decl name='" << decl->get_name() << "'";
o << "<class-decl name='" << xml::escape_xml_string(decl->get_name()) << "'";
write_size_and_alignment(decl, o);
@ -1346,7 +1350,7 @@ write_type_tparameter(const shared_ptr<type_tparameter> decl,
o << "<template-type-parameter "
<< id_attr_name << "='" << ctxt.get_id_for_type(decl) << "'";
std::string name = decl->get_name ();
std::string name = xml::escape_xml_string(decl->get_name ());
if (!name.empty())
o << " name='" << name << "'";
@ -1381,7 +1385,7 @@ write_non_type_tparameter(
<< ctxt.get_id_for_type(decl->get_type())
<< "'";
string name = decl->get_name();
string name = xml::escape_xml_string(decl->get_name());
if (!name.empty())
o << " name='" << name << "'";
@ -1420,7 +1424,7 @@ write_template_tparameter
o << "<template-template-parameter " << id_attr_name << "='"
<< ctxt.get_id_for_type(decl) << "'";
string name = decl->get_name();
string name = xml::escape_xml_string(decl->get_name());
if (!name.empty())
o << " name='" << name << "'";