aboutsummaryrefslogtreecommitdiffstats
path: root/pbx.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-08-14 02:14:14 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-08-14 02:14:14 +0000
commit02ed9fcda9904ece63bbd064327993ef542c61fd (patch)
treedcf9f806e87c4dd39afe167ac5e8eec0555b694a /pbx.c
parent6587d2ab753f064b0ec1c7ccfe246b964adf8c81 (diff)
When taking a substring and a negative length is provided, instead of just
ignoring it, allow this to mean that we want that many characters off of the end of the string so that ${EXTEN:0:$[${LEN(${EXTEN}) - 1]} can become ${EXTEN:0:-1}. (issue #7586, Corydon) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@39659 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'pbx.c')
-rw-r--r--pbx.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/pbx.c b/pbx.c
index 4b009b629..b224ca59e 100644
--- a/pbx.c
+++ b/pbx.c
@@ -36,6 +36,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <errno.h>
#include <time.h>
#include <sys/time.h>
+#include <limits.h>
#include "asterisk/lock.h"
#include "asterisk/cli.h"
@@ -1020,9 +1021,6 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan,
return NULL;
}
-/* Note that it's negative -- that's important later. */
-#define DONT_HAVE_LENGTH 0x80000000
-
/*! \brief extract offset:length from variable name.
* Returns 1 if there is a offset:length part, which is
* trimmed off (values go into variables)
@@ -1032,7 +1030,7 @@ static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
int parens=0;
*offset = 0;
- *length = DONT_HAVE_LENGTH;
+ *length = INT_MAX;
*isfunc = 0;
for (; *var; var++) {
if (*var == '(') {
@@ -1053,8 +1051,8 @@ static int parse_variable_name(char *var, int *offset, int *length, int *isfunc)
*
* offset < 0 means start from the end of the string and set the beginning
* to be that many characters back.
- * length is the length of the substring, -1 means unlimited
- * (we take any negative value).
+ * length is the length of the substring. A value less than 0 means to leave
+ * that many off the end.
* Always return a copy in workspace.
*/
static char *substring(const char *value, int offset, int length, char *workspace, size_t workspace_len)
@@ -1064,12 +1062,12 @@ static char *substring(const char *value, int offset, int length, char *workspac
ast_copy_string(workspace, value, workspace_len); /* always make a copy */
+ lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
+
/* Quick check if no need to do anything */
- if (offset == 0 && length < 0) /* take the whole string */
+ if (offset == 0 && length >= lr) /* take the whole string */
return ret;
- lr = strlen(ret); /* compute length after copy, so we never go out of the workspace */
-
if (offset < 0) { /* translate negative offset into positive ones */
offset = lr + offset;
if (offset < 0) /* If the negative offset was greater than the length of the string, just start at the beginning */
@@ -1083,6 +1081,12 @@ static char *substring(const char *value, int offset, int length, char *workspac
ret += offset; /* move to the start position */
if (length >= 0 && length < lr - offset) /* truncate if necessary */
ret[length] = '\0';
+ else if (length < 0) {
+ if (lr > offset - length) /* After we remove from the front and from the rear, is there anything left? */
+ ret[lr + length - offset] = '\0';
+ else
+ ret[0] = '\0';
+ }
return ret;
}