diff options
author | Automerge script <automerge@asterisk.org> | 2013-01-12 07:21:01 +0000 |
---|---|---|
committer | Automerge script <automerge@asterisk.org> | 2013-01-12 07:21:01 +0000 |
commit | f7f7850f7a3a85df4174b5b736eea2235fc4e6eb (patch) | |
tree | 6e3238a3a2b71d15cca2b36a13c099ee57b5a3d2 /main | |
parent | 2c1720b4f7567e0df5b0842b64c79bcf382fc51a (diff) |
Merged revisions 378935 via svnmerge from
file:///srv/subversion/repos/asterisk/trunk
................
r378935 | dlee | 2013-01-12 00:43:37 -0600 (Sat, 12 Jan 2013) | 41 lines
Fix XML encoding of 'identity display' in NOTIFY messages.
XML encoding in chan_sip is accomplished by naively building the XML
directly from strings. While this usually works, it fails to take into
account escaping the reserved characters in XML.
This patch adds an 'ast_xml_escape' function, which works similarly to
'ast_uri_encode'. This is used to properly escape the local_display
attribute in XML formatted NOTIFY messages.
Several things to note:
* The Right Thing(TM) to do would probably be to replace the
ast_build_string stuff with building an ast_xml_doc. That's a much
bigger change, and out of scope for the original ticket, so I
refrained myself.
* It is with great sadness that I wrote my own ast_xml_escape
function. There's one in libxml2, but it's knee-deep in
libxml2-ness, and not easily used to one-off escape a
string.
* I only escaped the string we know is causing problems
(local_display). At least some of the other strings are
URI-encoded, which should be XML safe. Rather than figuring out
what's safe and escaping what's not, it would be much cleaner to
simply build an ast_xml_doc for the messages and let the XML
library do the XML escaping. Like I said, that's out of scope.
(closes issue ABE-2902)
Reported by: Guenther Kelleter
Tested by: Guenther Kelleter
Review: http://reviewboard.digium.internal/r/365/
........
Merged revision 378919 from https://origsvn.digium.com/svn/asterisk/be/branches/C.3-bier
........
Merged revisions 378933 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 378934 from http://svn.asterisk.org/svn/asterisk/branches/11
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/team/mmichelson/threadpool@378946 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r-- | main/utils.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/main/utils.c b/main/utils.c index cdb9b1a44..cc9dee38e 100644 --- a/main/utils.c +++ b/main/utils.c @@ -483,6 +483,69 @@ char *ast_escape_quoted(const char *string, char *outbuf, int buflen) return outbuf; } +int ast_xml_escape(const char *string, char * const outbuf, const size_t buflen) +{ + char *dst = outbuf; + char *end = outbuf + buflen - 1; /* save one for the null terminator */ + + /* Handle the case for the empty output buffer */ + if (buflen == 0) { + return -1; + } + + /* Escaping rules from http://www.w3.org/TR/REC-xml/#syntax */ + /* This also prevents partial entities at the end of a string */ + while (*string && dst < end) { + const char *entity = NULL; + int len = 0; + + switch (*string) { + case '<': + entity = "<"; + len = 4; + break; + case '&': + entity = "&"; + len = 5; + break; + case '>': + /* necessary if ]]> is in the string; easier to escape them all */ + entity = ">"; + len = 4; + break; + case '\'': + /* necessary in single-quoted strings; easier to escape them all */ + entity = "'"; + len = 6; + break; + case '"': + /* necessary in double-quoted strings; easier to escape them all */ + entity = """; + len = 6; + break; + default: + *dst++ = *string++; + break; + } + + if (entity) { + ast_assert(len == strlen(entity)); + if (end - dst < len) { + /* no room for the entity; stop */ + break; + } + /* just checked for length; strcpy is fine */ + strcpy(dst, entity); + dst += len; + ++string; + } + } + /* Write null terminator */ + *dst = '\0'; + /* If any chars are left in string, return failure */ + return *string == '\0' ? 0 : -1; +} + /*! \brief ast_inet_ntoa: Recursive thread safe replacement of inet_ntoa */ const char *ast_inet_ntoa(struct in_addr ia) { |