$NetBSD: patch-ab,v 1.2 2009/01/07 18:45:54 drochner Exp $

--- lib/http.c.orig	2009-01-07 18:27:06.000000000 +0100
+++ lib/http.c
@@ -115,7 +115,7 @@ httplib_parse_url(const char *url, URLIN
 
     /* search for a login '@' token */
     if (strchr(url, '@') != NULL) {
-	ret = sscanf(url, "%[^:]:%[^@]", urlinfo->username, urlinfo->password);
+	ret = sscanf(url, "%1023[^:]:%1023[^@]", urlinfo->username, urlinfo->password);
 #if defined (commentout)
 	if (ret < 2) return SR_ERROR_PARSE_FAILURE;
 #endif
@@ -132,13 +132,13 @@ httplib_parse_url(const char *url, URLIN
 
     /* search for a port seperator */
     if (strchr(url, ':') != NULL) {
-	ret = sscanf(url, "%[^:]:%hu/%s", urlinfo->host, 
+	ret = sscanf(url, "%511[^:]:%hu/%252s", urlinfo->host, 
 		     (short unsigned int*)&urlinfo->port, urlinfo->path+1);
 	if (urlinfo->port < 1) return SR_ERROR_PARSE_FAILURE;
 	ret -= 1;
     } else {
 	urlinfo->port = 80;
-	ret = sscanf(url, "%[^/]/%s", urlinfo->host, urlinfo->path+1);
+	ret = sscanf(url, "%511[^/]/%252s", urlinfo->host, urlinfo->path+1);
     }
     if (ret < 1) return SR_ERROR_INVALID_URL;
 
@@ -258,11 +258,11 @@ httplib_construct_page_request (const ch
 
 /* Return 1 if a match was found, 0 if not found */
 int
-extract_header_value (char *header, char *dest, char *match)
+extract_header_value (char *header, char *dest, char *match, int maxlen)
 {
     char* start = (char *)strstr(header, match);
     if (start) {
-	subnstr_until(start+strlen(match), "\n", dest, MAX_ICY_STRING);
+	subnstr_until(start+strlen(match), "\n", dest, maxlen);
 	return 1;
     } else {
 	return 0;
@@ -321,24 +321,32 @@ httplib_parse_sc_header (const char *url
     }
 
     // read generic headers
-    extract_header_value(header, info->http_location, "Location:");
-    extract_header_value(header, info->server, "Server:");
-    rc = extract_header_value(header, info->icy_name, "icy-name:");
+    extract_header_value(header, info->http_location, "Location:",
+			 sizeof(info->http_location));
+    extract_header_value(header, info->server, "Server:",
+			 sizeof(info->server));
+    rc = extract_header_value(header, info->icy_name, "icy-name:",
+			      sizeof(info->icy_name));
     if (rc == 0) {
 	/* Icecast 2.0.1 */
-	rc = extract_header_value(header, info->icy_name, "ice-name:");
+	rc = extract_header_value(header, info->icy_name, "ice-name:",
+				  sizeof(info->icy_name));
     }
     info->have_icy_name = rc;
-    extract_header_value(header, info->icy_url, "icy-url:");
-    rc = extract_header_value(header, stempbr, "icy-br:");
+    extract_header_value(header, info->icy_url, "icy-url:",
+			 sizeof(info->icy_url));
+    rc = extract_header_value(header, stempbr,
+			      "icy-br:", sizeof(stempbr));
     if (rc) {
 	info->icy_bitrate = atoi(stempbr);
     }
 
     /* interpret the content type from http header */
-    rc = extract_header_value(header, stempbr, "Content-Type:");
+    rc = extract_header_value(header, stempbr,
+			      "Content-Type:", sizeof(stempbr));
     if (rc == 0) {
-        rc = extract_header_value(header, stempbr, "content-type:");
+        rc = extract_header_value(header, stempbr,
+				  "content-type:", sizeof(stempbr));
     }
     if (rc == 0) {
 	info->content_type = CONTENT_TYPE_UNKNOWN;
@@ -407,6 +415,7 @@ httplib_parse_sc_header (const char *url
 	    info->content_type = content_type_by_url;
 	}
     }
+
     // Check for Icecast 1
     else if ((start = (char *)strstr(header, "icecast")) != NULL) {
 	if (!info->server[0]) {
@@ -418,19 +427,19 @@ httplib_parse_sc_header (const char *url
 	}
 
 	// icecast 1.x headers.
-	extract_header_value(header, info->icy_url, "x-audiocast-server-url:");
-	rc = extract_header_value(header, info->icy_name, "x-audiocast-name:");
+	extract_header_value(header, info->icy_url, "x-audiocast-server-url:",
+			     sizeof(info->icy_url));
+	rc = extract_header_value(header, info->icy_name, "x-audiocast-name:",
+				  sizeof(info->icy_name));
 	info->have_icy_name |= rc;
-	extract_header_value(header, info->icy_genre, "x-audiocast-genre:");
-	rc = extract_header_value(header, stempbr, "x-audiocast-bitrate:");
+	extract_header_value(header, info->icy_genre, "x-audiocast-genre:",
+			     sizeof(info->icy_genre));
+	rc = extract_header_value(header, stempbr, "x-audiocast-bitrate:",
+				  sizeof(stempbr));
 	if (rc) {
 	    info->icy_bitrate = atoi(stempbr);
 	}
     }
-    // WTF is Zwitterion?
-    else if ((start = (char *)strstr(header, "Zwitterion v")) != NULL) {
-	sscanf(start, "%[^<]<", info->server);
-    }
 
     /* Last chance to deduce content type */
     if (info->content_type == CONTENT_TYPE_UNKNOWN) {
@@ -626,16 +635,17 @@ httplib_get_pls (HSOCKET *sock, SR_HTTP_
 	int best_open = 0;
 
 	sprintf (buf1, "File%d=", s);
-	if (!extract_header_value (buf, location_buf, buf1)) {
+	if (!extract_header_value (buf, location_buf, buf1,
+				   sizeof(location_buf))) {
 	    break;
 	}
 	if (s == 1) {
-	    strcpy (info->http_location, location_buf);
+	    sr_strncpy (info->http_location, location_buf, MAX_HOST_LEN);
 	    rc = SR_SUCCESS;
 	}
 	
 	sprintf (buf1, "Title%d=", s);
-	if (!extract_header_value (buf, title_buf, buf1)) {
+	if (!extract_header_value (buf, title_buf, buf1, sizeof(title_buf))) {
 	    break;
 	}
 	num_scanned = sscanf (title_buf, "(#%*[0-9] - %d/%d",&used,&total);
@@ -644,12 +654,12 @@ httplib_get_pls (HSOCKET *sock, SR_HTTP_
 	}
 	open = total - used;
 	if (open > best_open) {
-	    strcpy (info->http_location, location_buf);
+	    sr_strncpy (info->http_location, location_buf, MAX_HOST_LEN);
 	    best_open = open;
 	}
     }
 
-    strcpy (info->http_location, location_buf);
+    sr_strncpy (info->http_location, location_buf, MAX_HOST_LEN);
 
     return rc;
 }
@@ -689,7 +699,7 @@ httplib_get_m3u (HSOCKET *sock, SR_HTTP_
 	if (len > 4 && !strcmp (&p[len-4], ".mp3")) {
 	    continue;
 	}
-	strcpy (info->http_location, p);
+	sr_strncpy (info->http_location, p, MAX_HOST_LEN);
 	debug_printf ("Redirecting from M3U to: %s\n", p);
 	return SR_SUCCESS;
     }
