diff options
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) { |