diff options
Diffstat (limited to 'res/res_pjsip/presence_xml.c')
-rw-r--r-- | res/res_pjsip/presence_xml.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/res/res_pjsip/presence_xml.c b/res/res_pjsip/presence_xml.c index 12bfa078c..b98ea0237 100644 --- a/res/res_pjsip/presence_xml.c +++ b/res/res_pjsip/presence_xml.c @@ -30,45 +30,54 @@ void ast_sip_sanitize_xml(const char *input, char *output, size_t len) { char *copy = ast_strdupa(input); char *break_point; + size_t remaining = len - 1; output[0] = '\0'; - while ((break_point = strpbrk(copy, "<>\"&'\n\r"))) { + while ((break_point = strpbrk(copy, "<>\"&'\n\r")) && remaining) { char to_escape = *break_point; *break_point = '\0'; - strncat(output, copy, len); + strncat(output, copy, remaining); + + /* The strncat function will write remaining+1 if the string length is + * equal to or greater than the size provided to it. We take this into + * account by subtracting 1, which ensures that the NULL byte is written + * inside of the provided buffer. + */ + remaining = len - strlen(output) - 1; switch (to_escape) { case '<': - strncat(output, "<", len); + strncat(output, "<", remaining); break; case '>': - strncat(output, ">", len); + strncat(output, ">", remaining); break; case '"': - strncat(output, """, len); + strncat(output, """, remaining); break; case '&': - strncat(output, "&", len); + strncat(output, "&", remaining); break; case '\'': - strncat(output, "'", len); + strncat(output, "'", remaining); break; case '\r': - strncat(output, " ", len); + strncat(output, " ", remaining); break; case '\n': - strncat(output, " ", len); + strncat(output, " ", remaining); break; }; copy = break_point + 1; + remaining = len - strlen(output) - 1; } /* Be sure to copy everything after the final bracket */ - if (*copy) { - strncat(output, copy, len); + if (*copy && remaining) { + strncat(output, copy, remaining); } } |