mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-02 19:16:15 +00:00
strings.h: Fix issues with escape string functions.
Fixes for issues with the ASTERISK-24934 patch. * Fixed ast_escape_alloc() and ast_escape_c_alloc() if the s parameter is an empty string. If it were an empty string the functions returned NULL as if there were a memory allocation failure. This failure caused the AMI VarSet event to not get posted if the new value was an empty string. * Fixed dest buffer overwrite potential in ast_escape() and ast_escape_c(). If the dest buffer size is smaller than the space needed by the escaped s parameter string then the dest buffer would be written beyond the end by the nul string terminator. The num parameter was really the dest buffer size parameter so I renamed it to size. * Made nul terminate the dest buffer if the source string parameter s was an empty string in ast_escape() and ast_escape_c(). * Updated ast_escape() and ast_escape_c() doxygen function description comments to reflect reality. * Added some more unit test cases to /main/strings/escape to cover the empty source string issues. ASTERISK-25255 #close Reported by: Richard Mudgett Change-Id: Id77fc704600ebcce81615c1200296f74de254104
This commit is contained in:
50
main/utils.c
50
main/utils.c
@@ -1634,40 +1634,50 @@ static char escape_sequences_map[] = {
|
||||
'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"', '?', '\0'
|
||||
};
|
||||
|
||||
char* ast_escape(char *dest, const char *s, size_t num, const char *to_escape)
|
||||
char *ast_escape(char *dest, const char *s, size_t size, const char *to_escape)
|
||||
{
|
||||
char *p;
|
||||
char *c;
|
||||
|
||||
if (!dest || ast_strlen_zero(s)) {
|
||||
if (!dest || !size) {
|
||||
return dest;
|
||||
}
|
||||
if (ast_strlen_zero(s)) {
|
||||
*dest = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(to_escape)) {
|
||||
ast_copy_string(dest, s, num);
|
||||
ast_copy_string(dest, s, size);
|
||||
return dest;
|
||||
}
|
||||
|
||||
for (p = dest; *s && num--; ++s, ++p) {
|
||||
for (p = dest; *s && --size; ++s, ++p) {
|
||||
/* If in the list of characters to escape then escape it */
|
||||
if (strchr(to_escape, *s)) {
|
||||
if (!--size) {
|
||||
/* Not enough room left for the escape sequence. */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the character to escape is part of the standard escape
|
||||
* sequences. If so we'll have to use its mapped counterpart
|
||||
* otherwise just use the current character.
|
||||
*/
|
||||
char *c = strchr(escape_sequences, *s);
|
||||
c = strchr(escape_sequences, *s);
|
||||
*p++ = '\\';
|
||||
*p = c ? escape_sequences_map[c - escape_sequences] : *s;
|
||||
} else {
|
||||
*p = *s;
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* ast_escape_c(char *dest, const char *s, size_t num)
|
||||
char *ast_escape_c(char *dest, const char *s, size_t size)
|
||||
{
|
||||
/*
|
||||
* Note - This is an optimized version of ast_escape. When looking only
|
||||
@@ -1675,32 +1685,42 @@ char* ast_escape_c(char *dest, const char *s, size_t num)
|
||||
* be left out thus making it slightly more efficient.
|
||||
*/
|
||||
char *p;
|
||||
char *c;
|
||||
|
||||
if (!dest || ast_strlen_zero(s)) {
|
||||
if (!dest || !size) {
|
||||
return dest;
|
||||
}
|
||||
if (ast_strlen_zero(s)) {
|
||||
*dest = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
for (p = dest; *s && num--; ++s, ++p) {
|
||||
for (p = dest; *s && --size; ++s, ++p) {
|
||||
/*
|
||||
* See if the character to escape is part of the standard escape
|
||||
* sequences. If so use its mapped counterpart.
|
||||
*/
|
||||
char *c = strchr(escape_sequences, *s);
|
||||
c = strchr(escape_sequences, *s);
|
||||
if (c) {
|
||||
if (!--size) {
|
||||
/* Not enough room left for the escape sequence. */
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = '\\';
|
||||
*p = escape_sequences_map[c - escape_sequences];
|
||||
} else {
|
||||
*p = *s;
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static char *escape_alloc(const char *s, size_t *size)
|
||||
{
|
||||
if (!s || !(*size = strlen(s))) {
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1708,14 +1728,15 @@ static char *escape_alloc(const char *s, size_t *size)
|
||||
* The result string needs to be twice the size of the given
|
||||
* string just in case every character in it needs to be escaped.
|
||||
*/
|
||||
*size = *size * 2 + 1;
|
||||
return ast_calloc(sizeof(char), *size);
|
||||
*size = strlen(s) * 2 + 1;
|
||||
return ast_malloc(*size);
|
||||
}
|
||||
|
||||
char *ast_escape_alloc(const char *s, const char *to_escape)
|
||||
{
|
||||
size_t size = 0;
|
||||
char *dest = escape_alloc(s, &size);
|
||||
|
||||
return ast_escape(dest, s, size, to_escape);
|
||||
}
|
||||
|
||||
@@ -1723,6 +1744,7 @@ char *ast_escape_c_alloc(const char *s)
|
||||
{
|
||||
size_t size = 0;
|
||||
char *dest = escape_alloc(s, &size);
|
||||
|
||||
return ast_escape_c(dest, s, size);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user