changeset 507:0155ad752279 trunk

[svn] Fix case in curl where icecast metadata is wrapped around the end of the ring buffer.
author iabervon
date Sun, 21 Jan 2007 22:18:40 -0800
parents fb54b6f4955a
children 1e5df88b631d
files ChangeLog src/curl/curl.c
diffstat 2 files changed, 42 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Jan 21 22:15:24 2007 -0800
+++ b/ChangeLog	Sun Jan 21 22:18:40 2007 -0800
@@ -1,3 +1,11 @@
+2007-01-22 06:15:24 +0000  William Pitcock <nenolod@sacredspiral.co.uk>
+  revision [1098]
+  - don't depend on feof here, as it's reliability is not guaranteed. 
+  
+  trunk/src/amidi-plug/i_midi.c |    2 +-
+  1 file changed, 1 insertion(+), 1 deletion(-)
+
+
 2007-01-22 06:14:15 +0000  William Pitcock <nenolod@sacredspiral.co.uk>
   revision [1096]
   - tweak behaviour a little
--- a/src/curl/curl.c	Sun Jan 21 22:15:24 2007 -0800
+++ b/src/curl/curl.c	Sun Jan 21 22:18:40 2007 -0800
@@ -32,6 +32,7 @@
 #define DEBUG_READ 0
 #define DEBUG_HEADERS 0
 #define DEBUG_ICY 0
+#define DEBUG_ICY_WRAP 0
 #define DEBUG_ICY_VERBOSE 0
 #define DEBUG_METADATA_REPORT 0
 
@@ -197,24 +198,47 @@
 static gboolean match_inline(CurlHandle *handle, size_t posn, 
 			     const char *name)
 {
-  // XXXX Wrapped
-  return (!strncmp(handle->buffer + posn, name, strlen(name)));
+  size_t len = strlen(name);
+  size_t i;
+  if (DEBUG_ICY_WRAP)
+    g_print("Posn=%d\n", posn);
+  if (DEBUG_ICY_WRAP && posn + len > handle->buffer_length)
+    g_print("Wrapped inline key\n");
+  if (((handle->wr_index - posn + handle->buffer_length) %
+       handle->buffer_length) <= len)
+    return FALSE;
+  for (i = 0; i < len; i++)
+    if (handle->buffer[(posn + i) % handle->buffer_length] != name[i])
+      {
+	return FALSE;
+      }
+  return TRUE;
 }
 
 static gchar *get_inline_value(CurlHandle *handle, size_t posn,
 			       const char *name)
 {
-  // XXXX Wrapped
   size_t end;
   size_t sz;
   gchar *ret;
-  posn += strlen(name);
-  end = posn + 1;
-  while (handle->buffer[end] != ';')
+  posn = (posn + strlen(name) + 1) % handle->buffer_length;
+  end = posn;
+  while (handle->buffer[end % handle->buffer_length] != ';')
     end++;
-  sz = end - posn - 1;
+  sz = (end - posn + handle->buffer_length) % handle->buffer_length;
   ret = g_malloc(sz);
-  memcpy(ret, handle->buffer + posn + 1, sz);
+  if (end % handle->buffer_length < posn % handle->buffer_length)
+    {
+      size_t prewrap = handle->buffer_length - posn;
+      memcpy(ret, handle->buffer + posn, prewrap);
+      memcpy(ret + prewrap, handle->buffer, sz - prewrap);
+      if (DEBUG_ICY_WRAP)
+	g_print("Wrapped inline metadata value\n");
+    }
+  else
+    {
+      memcpy(ret, handle->buffer + posn, sz);
+    }
   ret[sz - 1] = '\0';
   return ret;
 }
@@ -224,6 +248,8 @@
   size_t i = (handle->hdr_index + 1) % handle->buffer_length;
   if (match_inline(handle, i, TITLE_INLINE))
     {
+      if (handle->title)
+	free(handle->title);
       handle->title = get_inline_value(handle, i, TITLE_INLINE);
       if (DEBUG_ICY)
 	g_print("Title: '%s'\n", handle->title);