From d2051f06cb7f95b9fa7404ba3c0b3ca082d6f54e Mon Sep 17 00:00:00 2001
From: Jeff Morriss <jeff.morriss.ws@gmail.com>
Date: Wed, 29 May 2013 22:43:20 +0000
Subject: [PATCH 6/8] Fix the infinite recursion problem reported in
 https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8733
 :

We can't solely rely on the port in the URI to determine whether we will be
recursively called by decode_tcp_ports().  Instead also check the conversation
entry too: if we find that we are the subdissector for this conversation
(which we might be--without the port being in our list of ports--if we
heuristically picked up the conversation or the user did Decode-As),
just bail out and dissect the payload as data.

svn path=/trunk/; revision=49623
---
 epan/dissectors/packet-http.c |   28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index 1690ab8..becd73f 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -1786,10 +1786,11 @@ http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
 			  packet_info *pinfo, http_conv_t *conv_data)
 {
 	guint32 *ptr = NULL;
- 	guint32 dissect_as, saved_port;
+ 	guint32 uri_port, saved_port, srcport, destport;
 	gchar **strings; /* An array for splitting the request URI into hostname and port */
 	proto_item *item;
 	proto_tree *proxy_tree;
+	conversation_t *conv;
 
 	/* Grab the destination port number from the request URI to find the right subdissector */
 	strings = g_strsplit(conv_data->request_uri, ":", 2);
@@ -1812,15 +1813,28 @@ http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
 			PROTO_ITEM_SET_GENERATED(item);
 		}
 
-		/* We're going to get stuck in a loop if we let process_tcp_payload call
-		   us, so call the data dissector instead for proxy connections to http ports. */
-		dissect_as = (int)strtol(strings[1], NULL, 10); /* Convert string to a base-10 integer */
+		uri_port = (int)strtol(strings[1], NULL, 10); /* Convert string to a base-10 integer */
 
-		if (value_is_in_range(http_tcp_range, dissect_as)) {
+		if (value_is_in_range(http_tcp_range, pinfo->destport)) {
+			srcport = pinfo->srcport;
+			destport = uri_port;
+		} else {
+			srcport = uri_port;
+			destport = pinfo->destport;
+		}
+
+		conv = find_conversation(PINFO_FD_NUM(pinfo), &pinfo->src, &pinfo->dst, PT_TCP, srcport, destport, 0);
+
+		/* We may get stuck in a recursion loop if we let process_tcp_payload() call us.
+		 * So, if the port in the URI is one we're registered for or we have set up a
+		 * conversation (e.g., one we detected heuristically or via Decode-As) call the data
+		 * dissector directly.
+		 */
+		if (value_is_in_range(http_tcp_range, uri_port) || (conv && conv->dissector_handle == http_handle)) {
 			call_dissector(data_handle, tvb, pinfo, tree);
 		} else {
 			/* set pinfo->{src/dst port} and call the TCP sub-dissector lookup */
-			if ( !ptr && value_is_in_range(http_tcp_range, pinfo->destport) )
+			if (value_is_in_range(http_tcp_range, pinfo->destport))
 				ptr = &pinfo->destport;
 			else
 				ptr = &pinfo->srcport;
@@ -1833,7 +1847,7 @@ http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
 				pinfo->can_desegment++;
 
 			saved_port = *ptr;
-			*ptr = dissect_as;
+			*ptr = uri_port;
 			decode_tcp_ports(tvb, 0, pinfo, tree,
 				pinfo->srcport, pinfo->destport, NULL);
 			*ptr = saved_port;
-- 
1.7.10.4

