]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 182211,182278 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Mon, 16 Mar 2009 17:38:50 +0000 (17:38 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Mon, 16 Mar 2009 17:38:50 +0000 (17:38 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
  r182211 | tilghman | 2009-03-16 10:50:55 -0500 (Mon, 16 Mar 2009) | 14 lines

  Merged revisions 182208 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.4

  ........
    r182208 | tilghman | 2009-03-16 10:39:15 -0500 (Mon, 16 Mar 2009) | 7 lines

    Fixup glare detection, to fix a memory leak of a local pvt structure.
    (closes issue #14656)
     Reported by: caspy
     Patches:
           20090313__bug14656__2.diff.txt uploaded by tilghman (license 14)
     Tested by: caspy
  ........
................
  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.1@182280 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_local.c
funcs/func_env.c

index a9a27ff8c2fc270c5dadf8e937baafbdc1d500f4..936264d21e8fbcc551daeecc655a65f6d88192ab 100644 (file)
@@ -203,23 +203,17 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra
        /* Recalculate outbound channel */
        other = isoutbound ? p->owner : p->chan;
 
-       /* Set glare detection */
-       ast_set_flag(p, LOCAL_GLARE_DETECT);
-       if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
-               /* We had a glare on the hangup.  Forget all this business,
-               return and destroy p.  */
-               ast_mutex_unlock(&p->lock);
-               p = local_pvt_destroy(p);
-               return -1;
-       }
        if (!other) {
-               ast_clear_flag(p, LOCAL_GLARE_DETECT);
                return 0;
        }
 
        /* do not queue frame if generator is on both local channels */
-       if (us && us->generator && other->generator)
+       if (us && us->generator && other->generator) {
                return 0;
+       }
+
+       /* Set glare detection */
+       ast_set_flag(p, LOCAL_GLARE_DETECT);
 
        /* Ensure that we have both channels locked */
        while (other && ast_channel_trylock(other)) {
@@ -235,6 +229,17 @@ static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_fra
                other = isoutbound ? p->owner : p->chan;
        }
 
+       /* Since glare detection only occurs within this function, and because
+        * a pvt flag cannot be set without having the pvt lock, this is the only
+        * location where we could detect a cancelling of the queue. */
+       if (ast_test_flag(p, LOCAL_CANCEL_QUEUE)) {
+               /* We had a glare on the hangup.  Forget all this business,
+               return and destroy p.  */
+               ast_mutex_unlock(&p->lock);
+               p = local_pvt_destroy(p);
+               return -1;
+       }
+
        if (other) {
                ast_queue_frame(other, f);
                ast_channel_unlock(other);
index 4eba211bb0d6f23ba28cf635d3b4682b92692977..095252b5ae65fa689c1dec3f3a0ac78ba7d572ac 100644 (file)
@@ -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 = {