mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-17 07:24:34 +00:00
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:
parent
5f97fc781c
commit
c4991c6444
@ -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
|
||||
|
@ -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:
|
||||
///
|
||||
/// < for the character '<', > for the character '>', ' for
|
||||
/// the character ''', " for the character '"', and & 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 += "<";
|
||||
break;
|
||||
case '>':
|
||||
escaped += ">";
|
||||
break;
|
||||
case '&':
|
||||
escaped += "&";
|
||||
break;
|
||||
case '\'':
|
||||
escaped += "'";
|
||||
break;
|
||||
case '"':
|
||||
escaped += """;
|
||||
break;
|
||||
default:
|
||||
escaped += *i;
|
||||
}
|
||||
}
|
||||
|
||||
/// Escape the 5 characters representing the predefined XML entities.
|
||||
///
|
||||
/// The resulting entities and their matching characters are:
|
||||
///
|
||||
/// < for the character '<', > for the character '>', ' for
|
||||
/// the character ''', " for the character '"', and & 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:
|
||||
///
|
||||
/// < for the character '<', > for the character '>', ' for
|
||||
/// the character ''', " for the character '"', and & 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:
|
||||
///
|
||||
/// < for the character '<', > for the character '>', ' for
|
||||
/// the character ''', " for the character '"', and & 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
|
||||
|
@ -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"))
|
||||
|
@ -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 << "'";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user