diff options
author | zuul <zuul@gerrit.asterisk.org> | 2017-03-15 19:25:09 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-03-15 19:25:09 -0500 |
commit | 6e38a72763a7dcc6dadf706a502d6b708e544467 (patch) | |
tree | ec595358b5e7baf418e18c2f9057380f627868fd | |
parent | 7e8cad893fa5b3524a7f298899223cfa6d13a6b6 (diff) | |
parent | eb50a37e8e50b60e3624849fc7bbd667ee049ca4 (diff) |
Merge "pbx.c: Fix crash from malformed exten pattern." into 14
-rw-r--r-- | main/pbx.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/main/pbx.c b/main/pbx.c index 24a4a7f86..bf665787c 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -656,7 +656,7 @@ static int ast_add_extension2_lockopt(struct ast_context *con, static struct ast_context *find_context_locked(const char *context); static struct ast_context *find_context(const char *context); static void get_device_state_causing_channels(struct ao2_container *c); -static int ext_strncpy(char *dst, const char *src, int len, int nofluff); +static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff); /*! * \internal @@ -6965,32 +6965,51 @@ int ast_async_goto_by_name(const char *channame, const char *context, const char return res; } -/*! \brief copy a string skipping whitespace and dashes */ -static int ext_strncpy(char *dst, const char *src, int len, int nofluff) +/*! + * \internal + * \brief Copy a string skipping whitespace and optionally dashes. + * + * \param dst Destination buffer to copy src string. + * \param src Null terminated string to copy. + * \param dst_size Number of bytes in the dst buffer. + * \param nofluf Nonzero if '-' chars are not copied. + * + * \return Number of bytes written to dst including null terminator. + */ +static unsigned int ext_strncpy(char *dst, const char *src, size_t dst_size, int nofluff) { - int count = 0; - int insquares = 0; + unsigned int count; + unsigned int insquares; + unsigned int is_pattern; - while (*src && (count < len - 1)) { + if (!dst_size--) { + /* There really is no dst buffer */ + return 0; + } + + count = 0; + insquares = 0; + is_pattern = *src == '_'; + while (*src && count < dst_size) { if (*src == '[') { - insquares = 1; + if (is_pattern) { + insquares = 1; + } } else if (*src == ']') { insquares = 0; } else if (*src == ' ' && !insquares) { - src++; + ++src; continue; } else if (*src == '-' && !insquares && nofluff) { - src++; + ++src; continue; } - *dst = *src; - dst++; - src++; - count++; + *dst++ = *src++; + ++count; } *dst = '\0'; - return count; + return count + 1; } /*! @@ -7304,10 +7323,10 @@ static int ast_add_extension2_lockopt(struct ast_context *con, p += strlen(label) + 1; } tmp->name = p; - p += ext_strncpy(p, extension, strlen(extension) + 1, 0) + 1; + p += ext_strncpy(p, extension, strlen(extension) + 1, 0); if (exten_fluff) { tmp->exten = p; - p += ext_strncpy(p, extension, strlen(extension) + 1, 1) + 1; + p += ext_strncpy(p, extension, strlen(extension) + 1 - exten_fluff, 1); } else { /* no fluff, we don't need a copy. */ tmp->exten = tmp->name; @@ -7317,10 +7336,10 @@ static int ast_add_extension2_lockopt(struct ast_context *con, /* Blank callerid and NULL callerid are two SEPARATE things. Do NOT confuse the two!!! */ if (callerid) { - p += ext_strncpy(p, callerid, strlen(callerid) + 1, 0) + 1; + p += ext_strncpy(p, callerid, strlen(callerid) + 1, 0); if (callerid_fluff) { tmp->cidmatch = p; - p += ext_strncpy(p, callerid, strlen(callerid) + 1, 1) + 1; + p += ext_strncpy(p, callerid, strlen(callerid) + 1 - callerid_fluff, 1); } tmp->matchcid = AST_EXT_MATCHCID_ON; } else { |