mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-09-22 04:15:54 -04:00
missed some NULL checks from previous character set commit. Add optional charset
setting on metadata update request and conversion code for it. svn path=/icecast/trunk/icecast/; revision=13663
This commit is contained in:
parent
7e5604b993
commit
47def32074
@ -48,6 +48,7 @@
|
||||
</table>
|
||||
<input type="hidden" name="mount" value="{@mount}"/>
|
||||
<input type="hidden" name="mode" value="updinfo"/>
|
||||
<input type="hidden" name="charset" value="UTF-8"/>
|
||||
</form>
|
||||
|
||||
<br />
|
||||
|
11
src/admin.c
11
src/admin.c
@ -854,7 +854,7 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
int response)
|
||||
{
|
||||
const char *action;
|
||||
const char *song, *title, *artist;
|
||||
const char *song, *title, *artist, *charset;
|
||||
format_plugin_t *plugin;
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr node;
|
||||
@ -869,6 +869,7 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
COMMAND_OPTIONAL(client, "song", song);
|
||||
COMMAND_OPTIONAL(client, "title", title);
|
||||
COMMAND_OPTIONAL(client, "artist", artist);
|
||||
COMMAND_OPTIONAL(client, "charset", charset);
|
||||
|
||||
if (strcmp (action, "updinfo") != 0)
|
||||
{
|
||||
@ -886,15 +887,15 @@ static void command_metadata(client_t *client, source_t *source,
|
||||
{
|
||||
if (song)
|
||||
{
|
||||
plugin->set_tag (plugin, "song", song);
|
||||
plugin->set_tag (plugin, "song", song, charset);
|
||||
INFO2 ("Metadata on mountpoint %s changed to \"%s\"", source->mount, song);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (artist && title)
|
||||
{
|
||||
plugin->set_tag (plugin, "title", title);
|
||||
plugin->set_tag (plugin, "artist", artist);
|
||||
plugin->set_tag (plugin, "title", title, charset);
|
||||
plugin->set_tag (plugin, "artist", artist, charset);
|
||||
INFO3("Metadata on mountpoint %s changed to \"%s - %s\"",
|
||||
source->mount, artist, title);
|
||||
}
|
||||
@ -936,7 +937,7 @@ static void command_shoutcast_metadata(client_t *client, source_t *source)
|
||||
|
||||
if (source->format && source->format->set_tag)
|
||||
{
|
||||
source->format->set_tag (source->format, "title", value);
|
||||
source->format->set_tag (source->format, "title", value, NULL);
|
||||
|
||||
DEBUG2("Metadata on mountpoint %s changed to \"%s\"",
|
||||
source->mount, value);
|
||||
|
@ -48,7 +48,7 @@ typedef struct _format_plugin_tag
|
||||
int (*write_buf_to_client)(client_t *client);
|
||||
void (*write_buf_to_file)(struct source_tag *source, refbuf_t *refbuf);
|
||||
int (*create_client_data)(struct source_tag *source, client_t *client);
|
||||
void (*set_tag)(struct _format_plugin_tag *plugin, const char *tag, const char *value);
|
||||
void (*set_tag)(struct _format_plugin_tag *plugin, const char *tag, const char *value, const char *charset);
|
||||
void (*free_plugin)(struct _format_plugin_tag *self);
|
||||
void (*apply_settings)(client_t *client, struct _format_plugin_tag *format, struct _mount_proxy *mount);
|
||||
|
||||
|
@ -61,7 +61,7 @@ static int format_mp3_create_client_data (source_t *source, client_t *client);
|
||||
static void free_mp3_client_data (client_t *client);
|
||||
static int format_mp3_write_buf_to_client(client_t *client);
|
||||
static void write_mp3_to_file (struct source_tag *source, refbuf_t *refbuf);
|
||||
static void mp3_set_tag (format_plugin_t *plugin, const char *tag, const char *value);
|
||||
static void mp3_set_tag (format_plugin_t *plugin, const char *tag, const char *in_value, const char *charset);
|
||||
static void format_mp3_apply_settings(client_t *client, format_plugin_t *format, mount_proxy *mount);
|
||||
|
||||
|
||||
@ -124,42 +124,43 @@ int format_mp3_get_plugin (source_t *source)
|
||||
}
|
||||
|
||||
|
||||
static void mp3_set_tag (format_plugin_t *plugin, const char *tag, const char *value)
|
||||
static void mp3_set_tag (format_plugin_t *plugin, const char *tag, const char *in_value, const char *charset)
|
||||
{
|
||||
mp3_state *source_mp3 = plugin->_state;
|
||||
unsigned int len;
|
||||
const char meta[] = "StreamTitle='";
|
||||
int size = sizeof (meta) + 1;
|
||||
char *value;
|
||||
|
||||
if (tag==NULL || value == NULL)
|
||||
if (tag==NULL || in_value == NULL)
|
||||
return;
|
||||
|
||||
/* protect against multiple updaters */
|
||||
thread_mutex_lock (&source_mp3->url_lock);
|
||||
|
||||
value = util_conv_string (in_value, charset, plugin->charset);
|
||||
if (value == NULL)
|
||||
value = strdup (in_value);
|
||||
|
||||
len = strlen (value)+1;
|
||||
size += len;
|
||||
/* protect against multiple updaters */
|
||||
thread_mutex_lock (&source_mp3->url_lock);
|
||||
|
||||
if (strcmp (tag, "title") == 0 || strcmp (tag, "song") == 0)
|
||||
{
|
||||
char *p = strdup (value);
|
||||
if (p)
|
||||
{
|
||||
free (source_mp3->url_title);
|
||||
free (source_mp3->url_artist);
|
||||
source_mp3->url_artist = NULL;
|
||||
source_mp3->url_title = p;
|
||||
source_mp3->update_metadata = 1;
|
||||
}
|
||||
free (source_mp3->url_title);
|
||||
free (source_mp3->url_artist);
|
||||
source_mp3->url_artist = NULL;
|
||||
source_mp3->url_title = value;
|
||||
source_mp3->update_metadata = 1;
|
||||
}
|
||||
else if (strcmp (tag, "artist") == 0)
|
||||
{
|
||||
char *p = strdup (value);
|
||||
if (p)
|
||||
{
|
||||
free (source_mp3->url_artist);
|
||||
source_mp3->url_artist = p;
|
||||
source_mp3->update_metadata = 1;
|
||||
}
|
||||
free (source_mp3->url_artist);
|
||||
source_mp3->url_artist = value;
|
||||
source_mp3->update_metadata = 1;
|
||||
}
|
||||
else
|
||||
free (value);
|
||||
thread_mutex_unlock (&source_mp3->url_lock);
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ static int process_vorbis_headers (ogg_state_t *ogg_info, ogg_codec_t *codec);
|
||||
static refbuf_t *process_vorbis_page (ogg_state_t *ogg_info,
|
||||
ogg_codec_t *codec, ogg_page *page);
|
||||
static refbuf_t *process_vorbis (ogg_state_t *ogg_info, ogg_codec_t *codec);
|
||||
static void vorbis_set_tag (format_plugin_t *plugin, const char *tag, const char *value);
|
||||
static void vorbis_set_tag (format_plugin_t *plugin, const char *tag, const char *value, const char *charset);
|
||||
|
||||
|
||||
static void free_ogg_packet (ogg_packet *packet)
|
||||
@ -413,12 +413,13 @@ ogg_codec_t *initial_vorbis_page (format_plugin_t *plugin, ogg_page *page)
|
||||
/* called from the admin interface, here we update the artist/title info
|
||||
* and schedule a new set of header pages
|
||||
*/
|
||||
static void vorbis_set_tag (format_plugin_t *plugin, const char *tag, const char *value)
|
||||
static void vorbis_set_tag (format_plugin_t *plugin, const char *tag, const char *in_value, const char *charset)
|
||||
{
|
||||
ogg_state_t *ogg_info = plugin->_state;
|
||||
ogg_codec_t *codec = ogg_info->codecs;
|
||||
vorbis_codec_t *source_vorbis;
|
||||
int change = 0;
|
||||
char *value;
|
||||
|
||||
/* avoid updating if multiple codecs in use */
|
||||
if (codec && codec->next == NULL)
|
||||
@ -426,43 +427,37 @@ static void vorbis_set_tag (format_plugin_t *plugin, const char *tag, const char
|
||||
else
|
||||
return;
|
||||
|
||||
value = util_conv_string (value, charset, "UTF-8");
|
||||
if (value == NULL)
|
||||
value = strdup (in_value);
|
||||
|
||||
if (strcmp (tag, "artist") == 0)
|
||||
{
|
||||
char *p = strdup (value);
|
||||
if (p)
|
||||
{
|
||||
free (ogg_info->artist);
|
||||
ogg_info->artist = p;
|
||||
change = 1;
|
||||
}
|
||||
free (ogg_info->artist);
|
||||
ogg_info->artist = value;
|
||||
change = 1;
|
||||
}
|
||||
if (strcmp (tag, "title") == 0)
|
||||
{
|
||||
char *p = strdup (value);
|
||||
if (p)
|
||||
{
|
||||
free (ogg_info->title);
|
||||
ogg_info->title = p;
|
||||
change = 1;
|
||||
}
|
||||
free (ogg_info->title);
|
||||
ogg_info->title = value;
|
||||
change = 1;
|
||||
}
|
||||
if (strcmp (tag, "song") == 0)
|
||||
{
|
||||
char *p = strdup (value);
|
||||
if (p)
|
||||
{
|
||||
free (ogg_info->artist);
|
||||
free (ogg_info->title);
|
||||
ogg_info->artist = NULL;
|
||||
ogg_info->title = p;
|
||||
change = 1;
|
||||
}
|
||||
free (ogg_info->artist);
|
||||
free (ogg_info->title);
|
||||
ogg_info->artist = NULL;
|
||||
ogg_info->title = value;
|
||||
change = 1;
|
||||
}
|
||||
if (change)
|
||||
{
|
||||
source_vorbis->stream_notify = 1;
|
||||
source_vorbis->rebuild_comment = 1;
|
||||
}
|
||||
else
|
||||
free (value);
|
||||
}
|
||||
|
||||
|
||||
|
18
src/source.c
18
src/source.c
@ -949,6 +949,10 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
if (source->client)
|
||||
parser = source->client->parser;
|
||||
|
||||
/* to be done before possible non-utf8 stats */
|
||||
if (source->format && source->format->apply_settings)
|
||||
source->format->apply_settings (source->client, source->format, mountinfo);
|
||||
|
||||
/* public */
|
||||
if (mountinfo && mountinfo->yp_public >= 0)
|
||||
val = mountinfo->yp_public;
|
||||
@ -994,7 +998,8 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
str = "Unspecified name";
|
||||
} while (0);
|
||||
}
|
||||
stats_event_conv (source->mount, "server_name", str, source->format->charset);
|
||||
if (str && source->format)
|
||||
stats_event_conv (source->mount, "server_name", str, source->format->charset);
|
||||
|
||||
/* stream description */
|
||||
if (mountinfo && mountinfo->stream_description)
|
||||
@ -1011,7 +1016,8 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
str = "Unspecified description";
|
||||
} while (0);
|
||||
}
|
||||
stats_event_conv (source->mount, "server_description", str, source->format->charset);
|
||||
if (str && source->format)
|
||||
stats_event_conv (source->mount, "server_description", str, source->format->charset);
|
||||
|
||||
/* stream URL */
|
||||
if (mountinfo && mountinfo->stream_url)
|
||||
@ -1027,7 +1033,8 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
if (str) break;
|
||||
} while (0);
|
||||
}
|
||||
stats_event (source->mount, "server_url", str);
|
||||
if (str && source->format)
|
||||
stats_event_conv (source->mount, "server_url", str, source->format->charset);
|
||||
|
||||
/* stream genre */
|
||||
if (mountinfo && mountinfo->stream_genre)
|
||||
@ -1044,7 +1051,8 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
str = "various";
|
||||
} while (0);
|
||||
}
|
||||
stats_event_conv (source->mount, "genre", str, source->format->charset);
|
||||
if (str && source->format)
|
||||
stats_event_conv (source->mount, "genre", str, source->format->charset);
|
||||
|
||||
/* stream bitrate */
|
||||
if (mountinfo && mountinfo->bitrate)
|
||||
@ -1132,8 +1140,6 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
if (mountinfo && mountinfo->fallback_when_full)
|
||||
source->fallback_when_full = mountinfo->fallback_when_full;
|
||||
|
||||
if (source->format && source->format->apply_settings)
|
||||
source->format->apply_settings (source->client, source->format, mountinfo);
|
||||
avl_tree_unlock (source->client_tree);
|
||||
}
|
||||
|
||||
|
40
src/util.c
40
src/util.c
@ -633,3 +633,43 @@ struct tm *localtime_r (const time_t *timep, struct tm *result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* helper function for converting a passed string in one character set to another
|
||||
* we use libxml2 for this
|
||||
*/
|
||||
char *util_conv_string (const char *string, const char *in_charset, const char *out_charset)
|
||||
{
|
||||
xmlCharEncodingHandlerPtr in, out;
|
||||
char *ret = NULL;
|
||||
|
||||
if (string == NULL || in_charset == NULL || out_charset == NULL)
|
||||
return NULL;
|
||||
|
||||
in = xmlFindCharEncodingHandler (in_charset);
|
||||
out = xmlFindCharEncodingHandler (out_charset);
|
||||
|
||||
if (in && out)
|
||||
{
|
||||
xmlBufferPtr orig = xmlBufferCreate ();
|
||||
xmlBufferPtr utf8 = xmlBufferCreate ();
|
||||
xmlBufferPtr conv = xmlBufferCreate ();
|
||||
|
||||
INFO2 ("converting metadata from %s to %s", in_charset, out_charset);
|
||||
xmlBufferCCat (orig, string);
|
||||
if (xmlCharEncInFunc (in, utf8, orig) > 0)
|
||||
{
|
||||
xmlCharEncOutFunc (out, conv, NULL);
|
||||
if (xmlCharEncOutFunc (out, conv, utf8) >= 0)
|
||||
ret = strdup ((const char *)xmlBufferContent (conv));
|
||||
}
|
||||
xmlBufferFree (orig);
|
||||
xmlBufferFree (utf8);
|
||||
xmlBufferFree (conv);
|
||||
}
|
||||
xmlCharEncCloseFunc (in);
|
||||
xmlCharEncCloseFunc (out);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -51,5 +51,6 @@ char *util_dict_urlencode(util_dict *dict, char delim);
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
struct tm *localtime_r (const time_t *timep, struct tm *result);
|
||||
#endif
|
||||
char *util_conv_string (const char *string, const char *in_charset, const char *out_charset);
|
||||
|
||||
#endif /* __UTIL_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user