From 016550f218fb0ea54aa6163d6a6eb7e02539da5e Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthm@freeswitch.org>
Date: Tue, 18 Sep 2012 18:42:00 -0500
Subject: [PATCH] FS-4627 --resolve

---
 libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c | 103 ++++++++++--------
 .../libsofia-sip-ua/msg/msg_parser.c          |   2 +
 .../msg/sofia-sip/msg_parser.h                |  28 +++++
 .../sofia-sip/libsofia-sip-ua/sip/sip_basic.c |  78 +++++++------
 .../libsofia-sip-ua/sip/sip_caller_prefs.c    |  60 +++++-----
 .../sofia-sip/libsofia-sip-ua/sip/sip_extra.c |  66 ++++++-----
 libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c |  30 ++---
 .../libsofia-sip-ua/sip/sip_reason.c          |  27 +++--
 .../libsofia-sip-ua/sip/sip_security.c        |  24 ++--
 9 files changed, 252 insertions(+), 166 deletions(-)

diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c
index 4fe75a24de..e889ceb633 100644
--- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c
+++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_mime.c
@@ -1069,28 +1069,33 @@ MSG_HEADER_CLASS(msg_, accept, "Accept", "", ac_params, apndlist,
 
 issize_t msg_accept_d(su_home_t *home, msg_header_t *h, char *s, isize_t slen)
 {
-  msg_accept_t *ac = (msg_accept_t *)h;
+	msg_accept_t *ac;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+	for(;;) {
+		ac = (msg_accept_t *)h;
 
-  if (*s == '\0') {
-    /* Empty Accept list is not an error */
-    ac->ac_type = ac->ac_subtype = "";
-    return 0;
-  }
+		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+			*s = '\0', s += span_lws(s + 1) + 1;
 
-  /* "Accept:" #(type/subtyp ; *(parameters))) */
-  if (msg_mediatype_d(&s, &ac->ac_type) == -1)
-    return -1;
-  if (!(ac->ac_subtype = strchr(ac->ac_type, '/')))
-    return -1;
-  ac->ac_subtype++;
+		if (*s == '\0') {
+			/* Empty Accept list is not an error */
+			ac->ac_type = ac->ac_subtype = "";
+			return 0;
+		}
 
-  if (*s == ';' && msg_params_d(home, &s, &ac->ac_params) == -1)
-    return -1;
+		/* "Accept:" #(type/subtyp ; *(parameters))) */
+		if (msg_mediatype_d(&s, &ac->ac_type) == -1)
+			return -1;
+		if (!(ac->ac_subtype = strchr(ac->ac_type, '/')))
+			return -1;
+		ac->ac_subtype++;
+
+		if (*s == ';' && msg_params_d(home, &s, &ac->ac_params) == -1)
+			return -1;
+  
+		msg_parse_next_field_without_recursion();
+	}
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 issize_t msg_accept_e(char b[], isize_t bsiz, msg_header_t const *h, int flags)
@@ -1167,22 +1172,26 @@ issize_t msg_accept_any_d(su_home_t *home,
 			  char *s, isize_t slen)
 {
   /** @relatesalso msg_accept_any_s */
-  msg_accept_any_t *aa = (msg_accept_any_t *)h;
+	msg_accept_any_t *aa;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+	for(;;) {
+		aa = (msg_accept_any_t *)h;
+		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+			*s = '\0', s += span_lws(s + 1) + 1;
 
-  if (*s == '\0')
-    return -2;			/* Empty list */
+		if (*s == '\0')
+			return -2;			/* Empty list */
 
-  /* "Accept-*:" 1#(token *(SEMI accept-param)) */
-  if (msg_token_d(&s, &aa->aa_value) == -1)
-    return -1;
+		/* "Accept-*:" 1#(token *(SEMI accept-param)) */
+		if (msg_token_d(&s, &aa->aa_value) == -1)
+			return -1;
 
-  if (*s == ';' && msg_params_d(home, &s, &aa->aa_params) == -1)
-    return -1;
+		if (*s == ';' && msg_params_d(home, &s, &aa->aa_params) == -1)
+			return -1;
+		
+		msg_parse_next_field_without_recursion();
+	}
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 /** Encode an Accept-* header field. */
@@ -2071,29 +2080,33 @@ MSG_HEADER_CLASS_G(content_transfer_encoding, "Content-Transfer-Encoding",
 
 issize_t msg_warning_d(su_home_t *home, msg_header_t *h, char *s, isize_t slen)
 {
-  msg_warning_t *w = (msg_warning_t *)h;
+	msg_warning_t *w;
   char *text;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+  for(;;) {
+	  w = (msg_warning_t *)h;
+	  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+		  *s = '\0', s += span_lws(s + 1) + 1;
 
-  /* Parse protocol */
-  if (!IS_DIGIT(*s))
-    return -1;
-  w->w_code = strtoul(s, &s, 10);
-  skip_lws(&s);
+	  /* Parse protocol */
+	  if (!IS_DIGIT(*s))
+		  return -1;
+	  w->w_code = strtoul(s, &s, 10);
+	  skip_lws(&s);
 
-  /* Host (and port) */
-  if (msg_hostport_d(&s, &w->w_host, &w->w_port) == -1)
-    return -1;
-  if (msg_quoted_d(&s, &text) == -1)
-    return -1;
-  if (msg_unquote(text, text) == NULL)
-    return -1;
+	  /* Host (and port) */
+	  if (msg_hostport_d(&s, &w->w_host, &w->w_port) == -1)
+		  return -1;
+	  if (msg_quoted_d(&s, &text) == -1)
+		  return -1;
+	  if (msg_unquote(text, text) == NULL)
+		  return -1;
 
-  w->w_text = text;
+	  w->w_text = text;
+	  
+	  msg_parse_next_field_without_recursion();
+  }
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 issize_t msg_warning_e(char b[], isize_t bsiz, msg_header_t const *h, int f)
diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_parser.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_parser.c
index e4bf3debca..d75b975689 100644
--- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_parser.c
+++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_parser.c
@@ -1190,6 +1190,7 @@ msg_header_t *error_header_parse(msg_t *msg, msg_pub_t *mo,
   return h;
 }
 
+
 /** Complete this header field and parse next header field.
  *
  * This function completes parsing a multi-field header like @Accept,
@@ -1238,6 +1239,7 @@ issize_t msg_parse_next_field(su_home_t *home, msg_header_t *prev,
   return hc->hc_parse(home, h, s, end - s);
 }
 
+
 /** Decode a message header. */
 msg_header_t *msg_header_d(su_home_t *home, msg_t const *msg, char const *b)
 {
diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_parser.h b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_parser.h
index c2fc31f862..7d784b5a61 100644
--- a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_parser.h
+++ b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_parser.h
@@ -185,6 +185,34 @@ SOFIAPUBFUN issize_t msg_unquoted_e(char *b, isize_t bsiz, char const *s);
 SOFIAPUBFUN issize_t msg_parse_next_field(su_home_t *home, msg_header_t *prev,
 					  char *s, isize_t slen);
 
+#define msg_parse_next_field_without_recursion() {				\
+		msg_header_t *prev = h;									\
+		msg_hclass_t *hc = prev->sh_class;						\
+		char *end = s + slen;									\
+																\
+		if (*s && *s != ',')									\
+			return -1;											\
+																\
+		if (msg_header_update_params(prev->sh_common, 0) < 0)	\
+			return -1;											\
+																\
+		while (*s == ',')										\
+			*s = '\0', s += span_lws(s + 1) + 1;				\
+																\
+		if (*s == 0)											\
+			return 0;											\
+																\
+		h = msg_header_alloc(home, hc, 0);						\
+		if (!h)													\
+			return -1;											\
+																\
+		prev->sh_succ = h, h->sh_prev = &prev->sh_succ;			\
+		prev->sh_next = h;										\
+		slen = end - s;											\
+	}															
+
+
+
 /** Terminate encoding. @HI */
 #define MSG_TERM_E(p, e) ((p) < (e) ? (p)[0] = '\0' : '\0')
 
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c
index b3dd3c396a..d2e1c0875e 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_basic.c
@@ -1391,18 +1391,23 @@ issize_t sip_contact_d(su_home_t *home,
 		       char *s,
 		       isize_t slen)
 {
-  sip_contact_t *m = (sip_contact_t *)h;
+  sip_contact_t *m;
 
   assert(h);
+  for(;;) {
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+	  m = (sip_contact_t *)h;
 
-  if (sip_name_addr_d(home, &s, &m->m_display, m->m_url,
-		      &m->m_params, &m->m_comment) == -1)
-    return -1;
+	  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+		  *s = '\0', s += span_lws(s + 1) + 1;
+	  
+	  if (sip_name_addr_d(home, &s, &m->m_display, m->m_url,
+						  &m->m_params, &m->m_comment) == -1)
+		  return -1;
+
+	  msg_parse_next_field_without_recursion();
+  }
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 
@@ -2106,18 +2111,24 @@ issize_t sip_any_route_d(su_home_t *home,
 			 char *s,
 			 isize_t slen)
 {
-  sip_route_t *r = (sip_route_t *)h;
+	sip_route_t *r;
+
 
   assert(h);
+  for (;;) {
+	  r = (sip_route_t *)h;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+	  while (*s == ',')  { /* Ignore empty entries (comma-whitespace) */
+		  *s = '\0', s += span_lws(s + 1) + 1;
+	  }
 
-  if (sip_name_addr_d(home, &s, &r->r_display,
-		      r->r_url, &r->r_params, NULL) < 0)
-    return -1;
+	  if (sip_name_addr_d(home, &s, &r->r_display, r->r_url, &r->r_params, NULL) < 0) {
+		  return -1;
+	  }
+
+	  msg_parse_next_field_without_recursion();
+  }
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 issize_t sip_any_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
@@ -2534,29 +2545,32 @@ SIP_HEADER_CLASS(via, "Via", "v", v_params, prepend, via);
 
 issize_t sip_via_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
 {
-  sip_via_t *v = (sip_via_t *)h;
+  sip_via_t *v;
 
   assert(h);
+  for (;;) {
+	  v = (sip_via_t *)h;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+	  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+		  *s = '\0', s += span_lws(s + 1) + 1;
 
-  /* sent-protocol sent-by *( ";" via-params ) [ comment ] */
+	  /* sent-protocol sent-by *( ";" via-params ) [ comment ] */
+	  
+	  /* Parse protocol */
+	  if (sip_transport_d(&s, &v->v_protocol) == -1)
+		  return -1;
+	  /* Host (and port) */
+	  if (msg_hostport_d(&s, &v->v_host, &v->v_port) == -1)
+		  return -1;
+	  /* Parameters */
+	  if (*s == ';' && msg_params_d(home, &s, &v->v_params) == -1)
+		  return -1;
+	  /* Comment */
+	  if (*s == '(' && msg_comment_d(&s, &v->v_comment) == -1)
+		  return -1;
 
-  /* Parse protocol */
-  if (sip_transport_d(&s, &v->v_protocol) == -1)
-    return -1;
-  /* Host (and port) */
-  if (msg_hostport_d(&s, &v->v_host, &v->v_port) == -1)
-    return -1;
-  /* Parameters */
-  if (*s == ';' && msg_params_d(home, &s, &v->v_params) == -1)
-    return -1;
-  /* Comment */
-  if (*s == '(' && msg_comment_d(&s, &v->v_comment) == -1)
-    return -1;
-
-  return msg_parse_next_field(home, h, s, slen);
+	  msg_parse_next_field_without_recursion();
+  }
 }
 
 issize_t sip_via_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_caller_prefs.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_caller_prefs.c
index 9cbc5ed2ee..b2dc3d8e50 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_caller_prefs.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_caller_prefs.c
@@ -194,39 +194,41 @@ static
 issize_t sip_caller_prefs_d(su_home_t *home, sip_header_t *h,
 			    char *s, isize_t slen)
 {
-  sip_caller_prefs_t *cp = (sip_caller_prefs_t *)h;
-  url_t url[1];
-  char const *ignore = NULL;
-  int kludge = 0;
+	for(;;) {
+		sip_caller_prefs_t *cp = (sip_caller_prefs_t *)h;
+		url_t url[1];
+		char const *ignore = NULL;
+		int kludge = 0;
 
-  assert(h);
+		assert(h);
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+			*s = '\0', s += span_lws(s + 1) + 1;
 
-  /* Kludge: support PoC IS spec with a typo... */
-  if (su_casenmatch(s, "*,", 2))
-    s[1] = ';',  kludge = 0;
-  else if (s[0] != '*' && s[0] != '<') {
-    /* Kludge: missing URL -  */
-    size_t n = span_attribute_value(s);
-    kludge = n > 0 && (s[n] == '\0' || s[n] == ',' || s[n] == ';');
-  }
+		/* Kludge: support PoC IS spec with a typo... */
+		if (su_casenmatch(s, "*,", 2))
+			s[1] = ';',  kludge = 0;
+		else if (s[0] != '*' && s[0] != '<') {
+			/* Kludge: missing URL -  */
+			size_t n = span_attribute_value(s);
+			kludge = n > 0 && (s[n] == '\0' || s[n] == ',' || s[n] == ';');
+		}
 
-  if (kludge) {
-    if (msg_any_list_d(home, &s, (msg_param_t **)&cp->cp_params,
-		       msg_attribute_value_scanner, ';') == -1)
-      return -1;
-  }
-  /* Parse params (and ignore display name and url) */
-  else if (sip_name_addr_d(home, &s, &ignore, url, &cp->cp_params, NULL)
-	   == -1)
-    return -1;
-  /* Be liberal... */
-  /* if (url->url_type != url_any)
-     return -1; */
-
-  return msg_parse_next_field(home, h, s, slen);
+		if (kludge) {
+			if (msg_any_list_d(home, &s, (msg_param_t **)&cp->cp_params,
+							   msg_attribute_value_scanner, ';') == -1)
+				return -1;
+		}
+		/* Parse params (and ignore display name and url) */
+		else if (sip_name_addr_d(home, &s, &ignore, url, &cp->cp_params, NULL)
+				 == -1)
+			return -1;
+		/* Be liberal... */
+		/* if (url->url_type != url_any)
+		   return -1; */
+		msg_parse_next_field_without_recursion();
+	}
+	
 }
 
 static
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c
index 48cb7a6bbf..8b2913f43b 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_extra.c
@@ -40,15 +40,17 @@
 #define MSG_PUB_T       struct sip_s
 #define MSG_HDR_T       union sip_header_u
 
+
 #include "sofia-sip/sip_parser.h"
 #include "sofia-sip/sip_extra.h"
+#include "../su/sofia-sip/su_alloc.h"
 
 #include <stdio.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
-
+#
 #include <assert.h>
 
 /* ====================================================================== */
@@ -887,16 +889,19 @@ issize_t sip_info_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
   sip_call_info_t *ci = h->sh_call_info;
   char *end = s + slen;
 
-  assert(h);
+  for(;;) {
+	  ci = h->sh_call_info;
+	  end = s + slen;
 
-  while (*s == ',')
-    s += span_lws(s + 1) + 1;
+	  while (*s == ',')
+		  s += span_lws(s + 1) + 1;
 
-  if (sip_name_addr_d(home, &s, NULL, ci->ci_url, &ci->ci_params, NULL) < 0)
-    return -1;
+	  if (sip_name_addr_d(home, &s, NULL, ci->ci_url, &ci->ci_params, NULL) < 0)
+		  return -1;
 
-  /* Recurse */
-  return msg_parse_next_field(home, h, s, end - s);
+	  slen = end - s;
+	  msg_parse_next_field_without_recursion();
+  }
 }
 
 isize_t sip_info_dup_xtra(sip_header_t const *h, isize_t offset)
@@ -1148,18 +1153,23 @@ SIP_HEADER_CLASS(remote_party_id, "Remote-Party-ID", "",
 issize_t sip_remote_party_id_d(su_home_t *home, sip_header_t *h,
 			       char *s, isize_t slen)
 {
-  sip_remote_party_id_t *rpid = (sip_remote_party_id_t *)h;
+	sip_remote_party_id_t *rpid;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+	for(;;) {
+		rpid = (sip_remote_party_id_t *)h;
 
-  if (sip_name_addr_d(home, &s,
-		      &rpid->rpid_display,
-		      rpid->rpid_url,
-		      &rpid->rpid_params, NULL) == -1)
-    return -1;
+		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+			*s = '\0', s += span_lws(s + 1) + 1;
+
+		if (sip_name_addr_d(home, &s,
+							&rpid->rpid_display,
+							rpid->rpid_url,
+							&rpid->rpid_params, NULL) == -1)
+			return -1;
+
+		msg_parse_next_field_without_recursion();
+	}
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 issize_t sip_remote_party_id_e(char b[], isize_t bsiz,
@@ -1288,18 +1298,22 @@ SIP_HEADER_CLASS(p_asserted_identity, "P-Asserted-Identity", "",
 issize_t sip_p_asserted_identity_d(su_home_t *home, sip_header_t *h,
 				   char *s, isize_t slen)
 {
-  sip_p_asserted_identity_t *paid = (sip_p_asserted_identity_t *)h;
+	sip_p_asserted_identity_t *paid;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+	for(;;) {
+		paid = (sip_p_asserted_identity_t *)h;
+		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+			*s = '\0', s += span_lws(s + 1) + 1;
 
-  if (sip_name_addr_d(home, &s,
-		      &paid->paid_display,
-		      paid->paid_url,
-		      NULL, NULL) == -1)
-    return -1;
+		if (sip_name_addr_d(home, &s,
+							&paid->paid_display,
+							paid->paid_url,
+							NULL, NULL) == -1)
+			return -1;
+
+		msg_parse_next_field_without_recursion();
+	}
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 issize_t sip_p_asserted_identity_e(char b[], isize_t bsiz,
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c
index 90cce374de..62286bc0fa 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_mime.c
@@ -135,24 +135,28 @@ SIP_HEADER_CLASS(accept_disposition, "Accept-Disposition", "",
 
 issize_t sip_accept_disposition_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
 {
-  sip_accept_disposition_t *ad = (sip_accept_disposition_t *)h;
+	sip_accept_disposition_t *ad;
 
-  assert(h);
+	assert(h);
 
-  /* Ignore empty entries (comma-whitespace) */
-  while (*s == ',')
-    s += span_lws(s + 1) + 1;
+	for(;;) {
+		ad = (sip_accept_disposition_t *)h;
+		/* Ignore empty entries (comma-whitespace) */
+		while (*s == ',')
+			s += span_lws(s + 1) + 1;
 
-  /* "Accept:" #(type/subtyp ; *(parameters))) */
-  if (/* Parse protocol */
-      sip_version_d(&s, &ad->ad_type) == -1 ||
-      (ad->ad_subtype = strchr(ad->ad_type, '/')) == NULL ||
-      (*s == ';' && msg_params_d(home, &s, &ad->ad_params) == -1))
-    return -1;
+		/* "Accept:" #(type/subtyp ; *(parameters))) */
+		if (/* Parse protocol */
+			sip_version_d(&s, &ad->ad_type) == -1 ||
+			(ad->ad_subtype = strchr(ad->ad_type, '/')) == NULL ||
+			(*s == ';' && msg_params_d(home, &s, &ad->ad_params) == -1))
+			return -1;
 
-  if (ad->ad_subtype) ad->ad_subtype++;
+		if (ad->ad_subtype) ad->ad_subtype++;
+
+		msg_parse_next_field_without_recursion();
+	}
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 issize_t sip_accept_disposition_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c
index bb7dbd068f..995fd8c816 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_reason.c
@@ -96,20 +96,25 @@ SIP_HEADER_CLASS(reason, "Reason", "", re_params, append, reason);
 
 issize_t sip_reason_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
 {
-  sip_reason_t *re = (sip_reason_t *)h;
-  size_t n;
+	sip_reason_t *re;
+	size_t n;
+	for (;;) {
+		re = (sip_reason_t *)h;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+			*s = '\0', s += span_lws(s + 1) + 1;
+
+		re->re_protocol = s;
+		if ((n = span_token(s)) == 0)
+			return -1;
+		s += n; while (IS_LWS(*s)) *s++ = '\0';
+		if (*s == ';' && msg_params_d(home, &s, &re->re_params) < 0)
+			return -1;
+
+		msg_parse_next_field_without_recursion();
+	}
 
-  re->re_protocol = s;
-  if ((n = span_token(s)) == 0)
-    return -1;
-  s += n; while (IS_LWS(*s)) *s++ = '\0';
-  if (*s == ';' && msg_params_d(home, &s, &re->re_params) < 0)
-    return -1;
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 issize_t sip_reason_e(char b[], isize_t bsiz, sip_header_t const *h, int f)
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c b/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c
index 99520b2aac..69cddff252 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sip_security.c
@@ -458,20 +458,24 @@ typedef struct sip_security_agree_s sip_security_agree_t;
 static
 issize_t sip_security_agree_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
 {
-  sip_security_agree_t *sa = (sip_security_agree_t *)h;
 
-  isize_t n;
+	for (;;) {
+		sip_security_agree_t *sa = (sip_security_agree_t *)h;
 
-  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
-    *s = '\0', s += span_lws(s + 1) + 1;
+		isize_t n;
 
-  if ((n = span_token(s)) == 0)
-    return -1;
-  sa->sa_mec = s; s += n; while (IS_LWS(*s)) *s++ = '\0';
-  if (*s == ';' && msg_params_d(home, &s, &sa->sa_params) < 0)
-    return -1;
+		while (*s == ',')   /* Ignore empty entries (comma-whitespace) */
+			*s = '\0', s += span_lws(s + 1) + 1;
+
+		if ((n = span_token(s)) == 0)
+			return -1;
+		sa->sa_mec = s; s += n; while (IS_LWS(*s)) *s++ = '\0';
+		if (*s == ';' && msg_params_d(home, &s, &sa->sa_params) < 0)
+			return -1;
+
+		msg_parse_next_field_without_recursion();
+	}
 
-  return msg_parse_next_field(home, h, s, slen);
 }
 
 static