summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2013-11-22 17:12:29 +0000
committerJoshua Colp <jcolp@digium.com>2013-11-22 17:12:29 +0000
commit2147e3930380b599a0cdab6a8533f0b3d39d0091 (patch)
treede6dca0818c29f76d548cd3bdc407cd403ce1e08
parent18c2cfa7b7465e5f8728eb1c996db7c00547dfe8 (diff)
translate: Move freeing of frame to after it is used.
When translating from one format to another it is possible to inform the translation function that the source frame should be freed. This was previously done immediately but shortly afterwards the frame that was freed was accessed and used again. This change moves code around a bit so that the frame is now freed after it has been completely used. (closes issue ASTERISK-22788) Reported by: Corey Farrell Patches: translate-access-after-free-11up.patch uploaded by coreyfarrell (license 5909) translate-access-after-free-1.8.patch uploaded by coreyfarrell (license 5909) ........ Merged revisions 403014 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 403015 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 403016 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403017 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--main/translate.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/main/translate.c b/main/translate.c
index 96019f1c7..df2754d11 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -518,41 +518,40 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
}
out = p->t->frameout(p);
}
- if (consume) {
- ast_frfree(f);
- }
- if (out == NULL) {
- return NULL;
- }
- /* we have a frame, play with times */
- if (!ast_tvzero(delivery)) {
- /* Regenerate prediction after a discontinuity */
- if (ast_tvzero(path->nextout)) {
- path->nextout = ast_tvnow();
- }
+ if (out) {
+ /* we have a frame, play with times */
+ if (!ast_tvzero(delivery)) {
+ /* Regenerate prediction after a discontinuity */
+ if (ast_tvzero(path->nextout)) {
+ path->nextout = ast_tvnow();
+ }
- /* Use next predicted outgoing timestamp */
- out->delivery = path->nextout;
+ /* Use next predicted outgoing timestamp */
+ out->delivery = path->nextout;
- /* Predict next outgoing timestamp from samples in this
- frame. */
- path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format)));
- if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
- ast_debug(4, "Sample size different %u vs %u\n", f->samples, out->samples);
- ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO);
+ /* Predict next outgoing timestamp from samples in this
+ frame. */
+ path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format)));
+ if (f->samples != out->samples && ast_test_flag(out, AST_FRFLAG_HAS_TIMING_INFO)) {
+ ast_debug(4, "Sample size different %u vs %u\n", f->samples, out->samples);
+ ast_clear_flag(out, AST_FRFLAG_HAS_TIMING_INFO);
+ }
+ } else {
+ out->delivery = ast_tv(0, 0);
+ ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
+ if (has_timing_info) {
+ out->ts = ts;
+ out->len = len;
+ out->seqno = seqno;
+ }
}
- } else {
- out->delivery = ast_tv(0, 0);
- ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
- if (has_timing_info) {
- out->ts = ts;
- out->len = len;
- out->seqno = seqno;
+ /* Invalidate prediction if we're entering a silence period */
+ if (out->frametype == AST_FRAME_CNG) {
+ path->nextout = ast_tv(0, 0);
}
}
- /* Invalidate prediction if we're entering a silence period */
- if (out->frametype == AST_FRAME_CNG) {
- path->nextout = ast_tv(0, 0);
+ if (consume) {
+ ast_frfree(f);
}
return out;
}