From 6a284f3de622e79cb0fbc01a28a2ebc4f04b7db4 Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Mon, 16 Mar 2009 17:36:51 +0000 Subject: [PATCH] Merged revisions 182278 via svnmerge from https://origsvn.digium.com/svn/asterisk/trunk ........ r182278 | tilghman | 2009-03-16 12:33:38 -0500 (Mon, 16 Mar 2009) | 7 lines Fix an off-by-one error in the FILE() function, and extend FILE()'s length parameter to work like variable substitution. Previously, FILE() returned one less character than specified, due to the terminating NULL. Both the offset and length parameters now behave identically to the way variable substitution offsets and lengths also work. (closes issue #14670) Reported by: BMC ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.0@182279 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- funcs/func_env.c | 57 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/funcs/func_env.c b/funcs/func_env.c index 4eba211bb0..095252b5ae 100644 --- a/funcs/func_env.c +++ b/funcs/func_env.c @@ -113,40 +113,59 @@ static int file_read(struct ast_channel *chan, const char *cmd, char *data, char AST_APP_ARG(offset); AST_APP_ARG(length); ); - int offset = 0, length; + int offset = 0, length, res = 0; char *contents; + size_t contents_len; AST_STANDARD_APP_ARGS(args, data); - if (args.argc > 1) + if (args.argc > 1) { offset = atoi(args.offset); + } if (args.argc > 2) { - if ((length = atoi(args.length)) < 1) { - ast_log(LOG_WARNING, "Invalid length '%s'. Returning the max (%d)\n", args.length, (int)len); - length = len; - } else if (length > len) { - ast_log(LOG_WARNING, "Length %d is greater than the max (%d). Truncating output.\n", length, (int)len); + /* The +1/-1 in this code section is to accomodate for the terminating NULL. */ + if ((length = atoi(args.length) + 1) > len) { + ast_log(LOG_WARNING, "Length %d is greater than the max (%d). Truncating output.\n", length - 1, (int)len - 1); length = len; } - } else + } else { length = len; + } - if (!(contents = ast_read_textfile(args.filename))) + if (!(contents = ast_read_textfile(args.filename))) { return -1; + } - if (offset >= 0) - ast_copy_string(buf, &contents[offset], length); - else { - size_t tmp = strlen(contents); - if (offset * -1 > tmp) { - ast_log(LOG_WARNING, "Offset is larger than the file size.\n"); - offset = tmp * -1; + do { + contents_len = strlen(contents); + if (offset > contents_len) { + res = -1; + break; } - ast_copy_string(buf, &contents[tmp + offset], length); - } + + if (offset >= 0) { + if (length < 0) { + if (contents_len - offset + length < 0) { + /* Nothing left after trimming */ + res = -1; + break; + } + ast_copy_string(buf, &contents[offset], contents_len + length); + } else { + ast_copy_string(buf, &contents[offset], length); + } + } else { + if (offset * -1 > contents_len) { + ast_log(LOG_WARNING, "Offset is larger than the file size.\n"); + offset = contents_len * -1; + } + ast_copy_string(buf, &contents[contents_len + offset], length); + } + } while (0); + ast_free(contents); - return 0; + return res; } static struct ast_custom_function env_function = {