[sr-dev] git:master: core: switch(string) memleak fix

Andrei Pelinescu-Onciul andrei at iptel.org
Sun Sep 26 21:33:47 CEST 2010


Module: sip-router
Branch: master
Commit: 6ab93de37f2f1991d3406f52ac9502a7c795ef55
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6ab93de37f2f1991d3406f52ac9502a7c795ef55

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at iptel.org>
Date:   Sun Sep 26 21:28:47 2010 +0200

core: switch(string) memleak fix

When a switch(string) is used and one of the case blocks exits the
script (by drop, exit or a module function that causes the script
to end), the dynamic string rvals were not cleaned up.
This happened because run_actions() uses longjmp() to quickly end
the script (skipping this way over the cleanups done after the
run_actions() call).

Reported-by: Daniel-Constantin Mierla <miconda at gmail.com>
Reported-by: César Pinto Magán  Cesar.Pinto a-e es

---

 action.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/action.c b/action.c
index 8349ff9..ec098ff 100644
--- a/action.c
+++ b/action.c
@@ -1320,17 +1320,39 @@ sw_jt_def:
 					  regexec(mct->match[i].l.regex, s.s, 0, 0, 0) == 0)
 					){
 					if (likely(mct->jump[i])){
+						/* make sure we cleanup first, in case run_actions()
+						   exits the script directly via longjmp() */
+						if (rv1){
+							rval_destroy(rv1);
+							rval_destroy(rv);
+							rval_cache_clean(&c1);
+						}else if (rv){
+							rval_destroy(rv);
+							rval_cache_clean(&c1);
+						}
 						ret=run_actions(h, mct->jump[i], msg);
 						h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
 													   returns passthrough */
+						break;
 					}
 					goto match_cleanup;
 				}
 match_cond_def:
 			if (mct->def){
+				/* make sure we cleanup first, in case run_actions()
+				   exits the script directly via longjmp() */
+				if (rv1){
+					rval_destroy(rv1);
+					rval_destroy(rv);
+					rval_cache_clean(&c1);
+				}else if (rv){
+					rval_destroy(rv);
+					rval_cache_clean(&c1);
+				}
 				ret=run_actions(h, mct->def, msg);
 				h->run_flags &= ~BREAK_R_F; /* catch breaks, but let
 											   returns passthrough */
+				break;
 			}
 match_cleanup:
 			if (rv1){




More information about the sr-dev mailing list