From cabbd0b1deb99d2df43b92aa216654874e2c7414 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Wed, 14 Mar 2012 17:57:21 +0000 Subject: [PATCH] * Use an asprintf wrapper, to report errors and NULLify the result. --- metadata.c | 67 ++++++++++++++++++++--------------------- tagutils/tagutils-aac.c | 6 ++-- tagutils/tagutils-asf.c | 8 ++--- tagutils/tagutils-mp3.c | 2 +- tagutils/tagutils-pcm.c | 4 +-- tagutils/tagutils.c | 1 + tivo_commands.c | 16 +++++----- upnpsoap.c | 6 ++++ utils.c | 17 +++++++++++ utils.h | 3 ++ 10 files changed, 77 insertions(+), 53 deletions(-) diff --git a/metadata.c b/metadata.c index 523abf3..2ebcaa8 100644 --- a/metadata.c +++ b/metadata.c @@ -258,7 +258,7 @@ parse_nfo(const char * path, metadata_t * m) { val2 = GetValueFromNameValueList(&xml, "episodetitle"); if( val2 ) - asprintf(&m->title, "%s - %s", val, val2); + xasprintf(&m->title, "%s - %s", val, val2); else m->title = strdup(val); } @@ -419,8 +419,8 @@ GetAudioMetadata(const char * path, char * name) if( song.dlna_pn ) m.dlna_pn = strdup(song.dlna_pn); if( song.year ) - asprintf(&m.date, "%04d-01-01", song.year); - asprintf(&m.duration, "%d:%02d:%02d.%03d", + xasprintf(&m.date, "%04d-01-01", song.year); + xasprintf(&m.duration, "%d:%02d:%02d.%03d", (song.song_length/3600000), (song.song_length/60000%60), (song.song_length/1000%60), @@ -630,10 +630,7 @@ GetImageMetadata(const char * path, char * name) break; } if( rotate ) - { - if( asprintf(&m.rotation, "%d", rotate) < 0 ) - m.rotation = NULL; - } + xasprintf(&m.rotation, "%d", rotate); } if( ed->size ) @@ -691,7 +688,7 @@ no_exifdata: m.dlna_pn = strdup("JPEG_MED"); else if( (width <= 4096 && height <= 4096) || !(GETFLAG(DLNA_STRICT_MASK)) ) m.dlna_pn = strdup("JPEG_LRG"); - asprintf(&m.resolution, "%dx%d", width, height); + xasprintf(&m.resolution, "%dx%d", width, height); ret = sql_exec(db, "INSERT into DETAILS" " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION," @@ -881,13 +878,13 @@ GetVideoMetadata(const char * path, char * name) DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [0x%X]\n", ac->codec_id); break; } - asprintf(&m.frequency, "%u", ac->sample_rate); + xasprintf(&m.frequency, "%u", ac->sample_rate); #if LIBAVCODEC_VERSION_INT < (52<<16) - asprintf(&m.bps, "%u", ac->bits_per_sample); + xasprintf(&m.bps, "%u", ac->bits_per_sample); #else - asprintf(&m.bps, "%u", ac->bits_per_coded_sample); + xasprintf(&m.bps, "%u", ac->bits_per_coded_sample); #endif - asprintf(&m.channels, "%u", ac->channels); + xasprintf(&m.channels, "%u", ac->channels); } if( vc ) { @@ -895,23 +892,23 @@ GetVideoMetadata(const char * path, char * name) int duration, hours, min, sec, ms; ts_timestamp_t ts_timestamp = NONE; DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basepath); - asprintf(&m.resolution, "%dx%d", vc->width, vc->height); + xasprintf(&m.resolution, "%dx%d", vc->width, vc->height); if( ctx->bit_rate > 8 ) - asprintf(&m.bitrate, "%u", ctx->bit_rate / 8); + xasprintf(&m.bitrate, "%u", ctx->bit_rate / 8); if( ctx->duration > 0 ) { duration = (int)(ctx->duration / AV_TIME_BASE); hours = (int)(duration / 3600); min = (int)(duration / 60 % 60); sec = (int)(duration % 60); ms = (int)(ctx->duration / (AV_TIME_BASE/1000) % 1000); - asprintf(&m.duration, "%d:%02d:%02d.%03d", hours, min, sec, ms); + xasprintf(&m.duration, "%d:%02d:%02d.%03d", hours, min, sec, ms); } /* NOTE: The DLNA spec only provides for ASF (WMV), TS, PS, and MP4 containers. * Skip DLNA parsing for everything else. */ if( strcmp(ctx->iformat->name, "avi") == 0 ) { - asprintf(&m.mime, "video/x-msvideo"); + xasprintf(&m.mime, "video/x-msvideo"); if( vc->codec_id == CODEC_ID_MPEG4 ) { fourcc[0] = vc->codec_tag & 0xff; @@ -921,16 +918,16 @@ GetVideoMetadata(const char * path, char * name) if( memcmp(fourcc, "XVID", 4) == 0 || memcmp(fourcc, "DX50", 4) == 0 || memcmp(fourcc, "DIVX", 4) == 0 ) - asprintf(&m.creator, "DiVX"); + xasprintf(&m.creator, "DiVX"); } } else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 && ends_with(path, ".mov") ) - asprintf(&m.mime, "video/quicktime"); + xasprintf(&m.mime, "video/quicktime"); else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 ) - asprintf(&m.mime, "video/x-matroska"); + xasprintf(&m.mime, "video/x-matroska"); else if( strcmp(ctx->iformat->name, "flv") == 0 ) - asprintf(&m.mime, "video/x-flv"); + xasprintf(&m.mime, "video/x-flv"); if( m.mime ) goto video_no_dlna; @@ -944,7 +941,7 @@ GetVideoMetadata(const char * path, char * name) { m.dlna_pn = strdup("MPEG1"); } - asprintf(&m.mime, "video/mpeg"); + xasprintf(&m.mime, "video/mpeg"); } break; case CODEC_ID_MPEG2VIDEO: @@ -988,14 +985,14 @@ GetVideoMetadata(const char * path, char * name) switch( ts_timestamp ) { case NONE: - asprintf(&m.mime, "video/mpeg"); + xasprintf(&m.mime, "video/mpeg"); if( m.dlna_pn ) off += sprintf(m.dlna_pn+off, "_ISO"); break; case VALID: off += sprintf(m.dlna_pn+off, "_T"); case EMPTY: - asprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); + xasprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); default: break; } @@ -1010,7 +1007,7 @@ GetVideoMetadata(const char * path, char * name) off += sprintf(m.dlna_pn+off, "PAL"); else off += sprintf(m.dlna_pn+off, "NTSC"); - asprintf(&m.mime, "video/mpeg"); + xasprintf(&m.mime, "video/mpeg"); } else { @@ -1181,7 +1178,7 @@ GetVideoMetadata(const char * path, char * name) case VALID: off += sprintf(m.dlna_pn+off, "_T"); case EMPTY: - asprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); + xasprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); default: break; } @@ -1345,7 +1342,7 @@ GetVideoMetadata(const char * path, char * name) if( ends_with(path, ".3gp") ) { - asprintf(&m.mime, "video/3gpp"); + xasprintf(&m.mime, "video/3gpp"); switch( audio_profile ) { case PROFILE_AUDIO_AAC: @@ -1406,7 +1403,7 @@ GetVideoMetadata(const char * path, char * name) m.dlna_pn = malloc(64); off = sprintf(m.dlna_pn, "WMV"); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basepath); - asprintf(&m.mime, "video/x-ms-wmv"); + xasprintf(&m.mime, "video/x-ms-wmv"); if( (vc->width <= 176) && (vc->height <= 144) && (vc->level == 0) ) @@ -1497,7 +1494,7 @@ GetVideoMetadata(const char * path, char * name) } break; case CODEC_ID_MSMPEG4V3: - asprintf(&m.mime, "video/x-msvideo"); + xasprintf(&m.mime, "video/x-msvideo"); default: DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n", video_stream, basepath, m.resolution, vc->codec_id); @@ -1507,20 +1504,20 @@ GetVideoMetadata(const char * path, char * name) if( !m.mime ) { if( strcmp(ctx->iformat->name, "avi") == 0 ) - asprintf(&m.mime, "video/x-msvideo"); + xasprintf(&m.mime, "video/x-msvideo"); else if( strncmp(ctx->iformat->name, "mpeg", 4) == 0 ) - asprintf(&m.mime, "video/mpeg"); + xasprintf(&m.mime, "video/mpeg"); else if( strcmp(ctx->iformat->name, "asf") == 0 ) - asprintf(&m.mime, "video/x-ms-wmv"); + xasprintf(&m.mime, "video/x-ms-wmv"); else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 ) if( ends_with(path, ".mov") ) - asprintf(&m.mime, "video/quicktime"); + xasprintf(&m.mime, "video/quicktime"); else - asprintf(&m.mime, "video/mp4"); + xasprintf(&m.mime, "video/mp4"); else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 ) - asprintf(&m.mime, "video/x-matroska"); + xasprintf(&m.mime, "video/x-matroska"); else if( strcmp(ctx->iformat->name, "flv") == 0 ) - asprintf(&m.mime, "video/x-flv"); + xasprintf(&m.mime, "video/x-flv"); else DPRINTF(E_WARN, L_METADATA, "%s: Unhandled format: %s\n", path, ctx->iformat->name); } diff --git a/tagutils/tagutils-aac.c b/tagutils/tagutils-aac.c index 4224d5f..3f1590a 100644 --- a/tagutils/tagutils-aac.c +++ b/tagutils/tagutils-aac.c @@ -407,11 +407,11 @@ bad_esds: } /* AAC @ Level 1/2 */ if( psong->channels <= 2 && psong->bitrate <= 320000 ) - asprintf(&(psong->dlna_pn), "AAC_ISO_320"); + xasprintf(&(psong->dlna_pn), "AAC_ISO_320"); else if( psong->channels <= 2 && psong->bitrate <= 576000 ) - asprintf(&(psong->dlna_pn), "AAC_ISO"); + xasprintf(&(psong->dlna_pn), "AAC_ISO"); else if( psong->channels <= 6 && psong->bitrate <= 1440000 ) - asprintf(&(psong->dlna_pn), "AAC_MULT5_ISO"); + xasprintf(&(psong->dlna_pn), "AAC_MULT5_ISO"); else DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n", psong->channels, psong->bitrate); diff --git a/tagutils/tagutils-asf.c b/tagutils/tagutils-asf.c index 11da1ae..8ab5c07 100644 --- a/tagutils/tagutils-asf.c +++ b/tagutils/tagutils-asf.c @@ -47,15 +47,15 @@ _pick_dlna_profile(struct song_metadata *psong, uint16_t format) { case WMA: if( psong->max_bitrate < 193000 ) - asprintf(&(psong->dlna_pn), "WMABASE"); + xasprintf(&(psong->dlna_pn), "WMABASE"); else if( psong->max_bitrate < 385000 ) - asprintf(&(psong->dlna_pn), "WMAFULL"); + xasprintf(&(psong->dlna_pn), "WMAFULL"); break; case WMAPRO: - asprintf(&(psong->dlna_pn), "WMAPRO"); + xasprintf(&(psong->dlna_pn), "WMAPRO"); break; case WMALSL: - asprintf(&(psong->dlna_pn), "WMALSL%s", + xasprintf(&(psong->dlna_pn), "WMALSL%s", psong->channels > 2 ? "_MULT5" : ""); default: break; diff --git a/tagutils/tagutils-mp3.c b/tagutils/tagutils-mp3.c index 701bca1..c87a065 100644 --- a/tagutils/tagutils-mp3.c +++ b/tagutils/tagutils-mp3.c @@ -770,7 +770,7 @@ _get_mp3fileinfo(char *file, struct song_metadata *psong) //DEBUG DPRINTF(E_INFO, L_SCANNER, "Got fileinfo successfully for file=%s song_length=%d\n", file, psong->song_length); psong->blockalignment = 1; - asprintf(&(psong->dlna_pn), "MP3"); + xasprintf(&(psong->dlna_pn), "MP3"); return 0; } diff --git a/tagutils/tagutils-pcm.c b/tagutils/tagutils-pcm.c index ce64ed5..ed044ea 100644 --- a/tagutils/tagutils-pcm.c +++ b/tagutils/tagutils-pcm.c @@ -42,8 +42,8 @@ _get_pcmfileinfo(char *filename, struct song_metadata *psong) psong->song_length = (sec * 1000) + ms; psong->lossless = 1; - asprintf(&(psong->mime), "audio/L16;rate=%d;channels=%d", psong->samplerate, psong->channels); - asprintf(&(psong->dlna_pn), "LPCM"); + xasprintf(&(psong->mime), "audio/L16;rate=%d;channels=%d", psong->samplerate, psong->channels); + xasprintf(&(psong->dlna_pn), "LPCM"); return 0; } diff --git a/tagutils/tagutils.c b/tagutils/tagutils.c index 9813bfc..e86eb29 100644 --- a/tagutils/tagutils.c +++ b/tagutils/tagutils.c @@ -46,6 +46,7 @@ #include "misc.h" #include "textutils.h" #include "../metadata.h" +#include "../utils.h" #include "../log.h" struct id3header { diff --git a/tivo_commands.c b/tivo_commands.c index 95cb9f4..5d6723e 100644 --- a/tivo_commands.c +++ b/tivo_commands.c @@ -38,7 +38,7 @@ SendRootContainer(struct upnphttp * h) char * resp; int len; - len = asprintf(&resp, "\n" + len = xasprintf(&resp, "\n" "" "
" "x-container/tivo-server" @@ -291,7 +291,7 @@ SendItemDetails(struct upnphttp * h, sqlite_int64 item) str.off = sprintf(str.data, "\n"); args.str = &str; args.requested = 1; - asprintf(&sql, SELECT_COLUMNS + xasprintf(&sql, SELECT_COLUMNS "from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)" " where o.DETAIL_ID = %lld group by o.DETAIL_ID", item); DPRINTF(E_DEBUG, L_TIVO, "%s\n", sql); @@ -364,16 +364,16 @@ SendContainer(struct upnphttp * h, const char * objectID, int itemStart, int ite switch( *objectID ) { case '1': - asprintf(&title, "Music on %s", friendly_name); + xasprintf(&title, "Music on %s", friendly_name); break; case '2': - asprintf(&title, "Videos on %s", friendly_name); + xasprintf(&title, "Videos on %s", friendly_name); break; case '3': - asprintf(&title, "Pictures on %s", friendly_name); + xasprintf(&title, "Pictures on %s", friendly_name); break; default: - asprintf(&title, "Unknown on %s", friendly_name); + xasprintf(&title, "Unknown on %s", friendly_name); break; } } @@ -391,12 +391,12 @@ SendContainer(struct upnphttp * h, const char * objectID, int itemStart, int ite if( recurse ) { - asprintf(&which, "OBJECT_ID glob '%s$*'", objectID); + xasprintf(&which, "OBJECT_ID glob '%s$*'", objectID); strcpy(groupBy, "group by DETAIL_ID"); } else { - asprintf(&which, "PARENT_ID = '%s'", objectID); + xasprintf(&which, "PARENT_ID = '%s'", objectID); } if( sortOrder ) diff --git a/upnpsoap.c b/upnpsoap.c index 0e8dbee..3dc64d8 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -84,6 +84,12 @@ BuildSendAndCloseSoapResp(struct upnphttp * h, "" "\r\n"; + if (!body || bodylen < 0) + { + Send500(h); + return; + } + BuildHeader_upnphttp(h, 200, "OK", sizeof(beforebody) - 1 + sizeof(afterbody) - 1 + bodylen ); diff --git a/utils.c b/utils.c index 60d7146..de3d509 100644 --- a/utils.c +++ b/utils.c @@ -52,6 +52,23 @@ strncpyt(char *dst, const char *src, size_t len) dst[len-1] = '\0'; } +inline int +xasprintf(char **strp, char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = vasprintf(strp, fmt, args); + va_end(args); + if( ret < 0 ) + { + DPRINTF(E_WARN, L_GENERAL, "xasprintf: allocation failed\n"); + *strp = NULL; + } + return ret; +} + int ends_with(const char * haystack, const char * needle) { diff --git a/utils.h b/utils.h index 48954bc..4eb4d32 100644 --- a/utils.h +++ b/utils.h @@ -32,6 +32,9 @@ strcatf(struct string_s *str, char *fmt, ...); void strncpyt(char *dst, const char *src, size_t len); +inline int +xasprintf(char **strp, char *fmt, ...); + int ends_with(const char * haystack, const char * needle);