[svn-commits] tilghman: trunk r182278 - /trunk/funcs/func_env.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Mar 16 12:33:50 CDT 2009


Author: tilghman
Date: Mon Mar 16 12:33:38 2009
New Revision: 182278

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=182278
Log:
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

Modified:
    trunk/funcs/func_env.c

Modified: trunk/funcs/func_env.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/funcs/func_env.c?view=diff&rev=182278&r1=182277&r2=182278
==============================================================================
--- trunk/funcs/func_env.c (original)
+++ trunk/funcs/func_env.c Mon Mar 16 12:33:38 2009
@@ -74,11 +74,12 @@
 		<syntax>
 			<parameter name="filename" required="true" />
 			<parameter name="offset" required="true">
-				<para>Maybe specified as any number. if negative <replaceable>offset</replaceable> specifies the number
+				<para>Maybe specified as any number. If negative, <replaceable>offset</replaceable> specifies the number
 				of bytes back from the end of the file.</para>
 			</parameter>
 			<parameter name="length" required="true">
-				<para>If specified, will limit the length of the data read to that size.</para>
+				<para>If specified, will limit the length of the data read to that size. If negative,
+				trims <replaceable>length</replaceable> bytes from the end of the file.</para>
 			</parameter>
 		</syntax>
 		<description>
@@ -166,40 +167,59 @@
 		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);
+		/* 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 if (length > len) {
-			ast_log(LOG_WARNING, "Length %d is greater than the max (%d).  Truncating output.\n", length, (int)len);
-			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;
-		}
-		ast_copy_string(buf, &contents[tmp + offset], length);
-	}
+	}
+
+	do {
+		contents_len = strlen(contents);
+		if (offset > contents_len) {
+			res = -1;
+			break;
+		}
+
+		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 = {




More information about the svn-commits mailing list