diff --git a/src/format.h b/src/format.h index f8a414eb..7e6baf1b 100644 --- a/src/format.h +++ b/src/format.h @@ -24,7 +24,8 @@ typedef struct _format_plugin_tag */ int has_predata; - refbuf_t *(*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long len); + int (*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long + len, refbuf_t **buffer); refbuf_queue_t *(*get_predata)(struct _format_plugin_tag *self); void (*free_plugin)(struct _format_plugin_tag *self); diff --git a/src/format_vorbis.c b/src/format_vorbis.c index 94bcfd0f..91438b01 100644 --- a/src/format_vorbis.c +++ b/src/format_vorbis.c @@ -16,6 +16,8 @@ #include "stats.h" #include "format.h" +#define MAX_HEADER_PAGES 10 + typedef struct _vstate_tag { ogg_sync_state oy; @@ -26,12 +28,12 @@ typedef struct _vstate_tag ogg_page og; unsigned long serialno; int header; - refbuf_t *headbuf[10]; + refbuf_t *headbuf[MAX_HEADER_PAGES]; int packets; } vstate_t; void format_vorbis_free_plugin(format_plugin_t *self); -refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len); +int format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len, refbuf_t **buffer); refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self); format_plugin_t *format_vorbis_get_plugin(void) @@ -68,7 +70,7 @@ void format_vorbis_free_plugin(format_plugin_t *self) vorbis_comment_clear(&state->vc); vorbis_info_clear(&state->vi); - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_HEADER_PAGES; i++) { if (state->headbuf[i]) { refbuf_release(state->headbuf[i]); state->headbuf[i] = NULL; @@ -81,19 +83,19 @@ void format_vorbis_free_plugin(format_plugin_t *self) free(self); } -refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len) +int format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len, refbuf_t **buffer) { - char *buffer; - refbuf_t *refbuf; + char *buf; int i, result; ogg_packet op; char *tag; + refbuf_t *refbuf; vstate_t *state = (vstate_t *)self->_state; if (data) { /* write the data to the buffer */ - buffer = ogg_sync_buffer(&state->oy, len); - memcpy(buffer, data, len); + buf = ogg_sync_buffer(&state->oy, len); + memcpy(buf, data, len); ogg_sync_wrote(&state->oy, len); } @@ -109,7 +111,7 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l state->packets = 0; /* release old headers, stream state, vorbis data */ - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_HEADER_PAGES; i++) { if (state->headbuf[i]) { refbuf_release(state->headbuf[i]); state->headbuf[i] = NULL; @@ -150,6 +152,10 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l /* cache header pages */ if (state->header > 0) { + if(state->header > MAX_HEADER_PAGES) { + refbuf_release(refbuf); + return -1; + } refbuf_addref(refbuf); state->headbuf[state->header - 1] = refbuf; @@ -174,7 +180,8 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l } } - return refbuf; + *buffer = refbuf; + return 0; } refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self) @@ -184,7 +191,7 @@ refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self) vstate_t *state = (vstate_t *)self->_state; queue = NULL; - for (i = 0; i < 10; i++) { + for (i = 0; i < MAX_HEADER_PAGES; i++) { if (state->headbuf[i]) { refbuf_addref(state->headbuf[i]); refbuf_queue_add(&queue, state->headbuf[i]); diff --git a/src/httpp/httpp.c b/src/httpp/httpp.c index 01f97624..b823046a 100644 --- a/src/httpp/httpp.c +++ b/src/httpp/httpp.c @@ -3,6 +3,8 @@ ** http parsing engine */ +#include + #include #include #include @@ -15,6 +17,8 @@ #define strcasecmp stricmp #endif +#define MAX_HEADERS 32 + /* internal functions */ /* misc */ @@ -48,7 +52,7 @@ void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults) int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len) { char *data, *tmp; - char *line[32]; /* limited to 32 lines, should be more than enough */ + char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */ int i, l, retlen; int lines; char *req_type = NULL; @@ -73,7 +77,7 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len) */ lines = 0; line[lines] = data; - for (i = 0; i < len; i++) { + for (i = 0; i < len && lines < MAX_HEADERS; i++) { if (data[i] == '\r') data[i] = '\0'; if (data[i] == '\n') { diff --git a/src/log/log.c b/src/log/log.c index 91e49808..e0e9184b 100644 --- a/src/log/log.c +++ b/src/log/log.c @@ -35,7 +35,7 @@ typedef struct log_tag char *filename; FILE *logfile; - char *buffer; + char *buffer; } log_t; log_t loglist[LOG_MAXLOGS]; @@ -170,7 +170,9 @@ void log_write(int log_id, int priority, const char *cat, const char *fmt, ...) va_list ap; if (log_id < 0) return; + if (log_id > LOG_MAXLOGS) return; /* Bad log number */ if (loglist[log_id].level < priority) return; + if (priority > 4) return; /* Bad priority */ va_start(ap, fmt); diff --git a/src/source.c b/src/source.c index 4bffbca6..4c8df193 100644 --- a/src/source.c +++ b/src/source.c @@ -147,7 +147,11 @@ void *source_main(void *arg) stats_event(source->mount, "description", s); while (global.running == ICE_RUNNING) { - refbuf = source->format->get_buffer(source->format, NULL, 0); + int ret = source->format->get_buffer(source->format, NULL, 0, &refbuf); + if(ret < 0) { + WARN0("Bad data from source"); + break; + } while (refbuf == NULL) { bytes = 0; while (bytes <= 0) { @@ -167,7 +171,11 @@ void *source_main(void *arg) if (bytes == 0 || (bytes < 0 && !sock_recoverable(sock_error()))) break; } if (bytes <= 0) break; - refbuf = source->format->get_buffer(source->format, buffer, bytes); + ret = source->format->get_buffer(source->format, buffer, bytes, &refbuf); + if(ret < 0) { + WARN0("Bad data from source"); + goto done; + } } if (bytes <= 0) { @@ -333,6 +341,8 @@ void *source_main(void *arg) avl_tree_unlock(source->client_tree); } +done: + printf("DEBUG: we're going down...\n"); /* we need to empty the client and pending trees */