* Use an asprintf wrapper, to report errors and NULLify the result.

This commit is contained in:
Justin Maggard 2012-03-14 17:57:21 +00:00
parent c9d979886b
commit cabbd0b1de
10 changed files with 77 additions and 53 deletions

View File

@ -258,7 +258,7 @@ parse_nfo(const char * path, metadata_t * m)
{ {
val2 = GetValueFromNameValueList(&xml, "episodetitle"); val2 = GetValueFromNameValueList(&xml, "episodetitle");
if( val2 ) if( val2 )
asprintf(&m->title, "%s - %s", val, val2); xasprintf(&m->title, "%s - %s", val, val2);
else else
m->title = strdup(val); m->title = strdup(val);
} }
@ -419,8 +419,8 @@ GetAudioMetadata(const char * path, char * name)
if( song.dlna_pn ) if( song.dlna_pn )
m.dlna_pn = strdup(song.dlna_pn); m.dlna_pn = strdup(song.dlna_pn);
if( song.year ) if( song.year )
asprintf(&m.date, "%04d-01-01", song.year); xasprintf(&m.date, "%04d-01-01", song.year);
asprintf(&m.duration, "%d:%02d:%02d.%03d", xasprintf(&m.duration, "%d:%02d:%02d.%03d",
(song.song_length/3600000), (song.song_length/3600000),
(song.song_length/60000%60), (song.song_length/60000%60),
(song.song_length/1000%60), (song.song_length/1000%60),
@ -630,10 +630,7 @@ GetImageMetadata(const char * path, char * name)
break; break;
} }
if( rotate ) if( rotate )
{ xasprintf(&m.rotation, "%d", rotate);
if( asprintf(&m.rotation, "%d", rotate) < 0 )
m.rotation = NULL;
}
} }
if( ed->size ) if( ed->size )
@ -691,7 +688,7 @@ no_exifdata:
m.dlna_pn = strdup("JPEG_MED"); m.dlna_pn = strdup("JPEG_MED");
else if( (width <= 4096 && height <= 4096) || !(GETFLAG(DLNA_STRICT_MASK)) ) else if( (width <= 4096 && height <= 4096) || !(GETFLAG(DLNA_STRICT_MASK)) )
m.dlna_pn = strdup("JPEG_LRG"); 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" ret = sql_exec(db, "INSERT into DETAILS"
" (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION," " (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); DPRINTF(E_DEBUG, L_METADATA, "Unhandled audio codec [0x%X]\n", ac->codec_id);
break; break;
} }
asprintf(&m.frequency, "%u", ac->sample_rate); xasprintf(&m.frequency, "%u", ac->sample_rate);
#if LIBAVCODEC_VERSION_INT < (52<<16) #if LIBAVCODEC_VERSION_INT < (52<<16)
asprintf(&m.bps, "%u", ac->bits_per_sample); xasprintf(&m.bps, "%u", ac->bits_per_sample);
#else #else
asprintf(&m.bps, "%u", ac->bits_per_coded_sample); xasprintf(&m.bps, "%u", ac->bits_per_coded_sample);
#endif #endif
asprintf(&m.channels, "%u", ac->channels); xasprintf(&m.channels, "%u", ac->channels);
} }
if( vc ) if( vc )
{ {
@ -895,23 +892,23 @@ GetVideoMetadata(const char * path, char * name)
int duration, hours, min, sec, ms; int duration, hours, min, sec, ms;
ts_timestamp_t ts_timestamp = NONE; ts_timestamp_t ts_timestamp = NONE;
DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basepath); 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 ) 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 ) { if( ctx->duration > 0 ) {
duration = (int)(ctx->duration / AV_TIME_BASE); duration = (int)(ctx->duration / AV_TIME_BASE);
hours = (int)(duration / 3600); hours = (int)(duration / 3600);
min = (int)(duration / 60 % 60); min = (int)(duration / 60 % 60);
sec = (int)(duration % 60); sec = (int)(duration % 60);
ms = (int)(ctx->duration / (AV_TIME_BASE/1000) % 1000); 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. /* NOTE: The DLNA spec only provides for ASF (WMV), TS, PS, and MP4 containers.
* Skip DLNA parsing for everything else. */ * Skip DLNA parsing for everything else. */
if( strcmp(ctx->iformat->name, "avi") == 0 ) 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 ) if( vc->codec_id == CODEC_ID_MPEG4 )
{ {
fourcc[0] = vc->codec_tag & 0xff; fourcc[0] = vc->codec_tag & 0xff;
@ -921,16 +918,16 @@ GetVideoMetadata(const char * path, char * name)
if( memcmp(fourcc, "XVID", 4) == 0 || if( memcmp(fourcc, "XVID", 4) == 0 ||
memcmp(fourcc, "DX50", 4) == 0 || memcmp(fourcc, "DX50", 4) == 0 ||
memcmp(fourcc, "DIVX", 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 && else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 &&
ends_with(path, ".mov") ) ends_with(path, ".mov") )
asprintf(&m.mime, "video/quicktime"); xasprintf(&m.mime, "video/quicktime");
else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 ) 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 ) else if( strcmp(ctx->iformat->name, "flv") == 0 )
asprintf(&m.mime, "video/x-flv"); xasprintf(&m.mime, "video/x-flv");
if( m.mime ) if( m.mime )
goto video_no_dlna; goto video_no_dlna;
@ -944,7 +941,7 @@ GetVideoMetadata(const char * path, char * name)
{ {
m.dlna_pn = strdup("MPEG1"); m.dlna_pn = strdup("MPEG1");
} }
asprintf(&m.mime, "video/mpeg"); xasprintf(&m.mime, "video/mpeg");
} }
break; break;
case CODEC_ID_MPEG2VIDEO: case CODEC_ID_MPEG2VIDEO:
@ -988,14 +985,14 @@ GetVideoMetadata(const char * path, char * name)
switch( ts_timestamp ) switch( ts_timestamp )
{ {
case NONE: case NONE:
asprintf(&m.mime, "video/mpeg"); xasprintf(&m.mime, "video/mpeg");
if( m.dlna_pn ) if( m.dlna_pn )
off += sprintf(m.dlna_pn+off, "_ISO"); off += sprintf(m.dlna_pn+off, "_ISO");
break; break;
case VALID: case VALID:
off += sprintf(m.dlna_pn+off, "_T"); off += sprintf(m.dlna_pn+off, "_T");
case EMPTY: case EMPTY:
asprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); xasprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
default: default:
break; break;
} }
@ -1010,7 +1007,7 @@ GetVideoMetadata(const char * path, char * name)
off += sprintf(m.dlna_pn+off, "PAL"); off += sprintf(m.dlna_pn+off, "PAL");
else else
off += sprintf(m.dlna_pn+off, "NTSC"); off += sprintf(m.dlna_pn+off, "NTSC");
asprintf(&m.mime, "video/mpeg"); xasprintf(&m.mime, "video/mpeg");
} }
else else
{ {
@ -1181,7 +1178,7 @@ GetVideoMetadata(const char * path, char * name)
case VALID: case VALID:
off += sprintf(m.dlna_pn+off, "_T"); off += sprintf(m.dlna_pn+off, "_T");
case EMPTY: case EMPTY:
asprintf(&m.mime, "video/vnd.dlna.mpeg-tts"); xasprintf(&m.mime, "video/vnd.dlna.mpeg-tts");
default: default:
break; break;
} }
@ -1345,7 +1342,7 @@ GetVideoMetadata(const char * path, char * name)
if( ends_with(path, ".3gp") ) if( ends_with(path, ".3gp") )
{ {
asprintf(&m.mime, "video/3gpp"); xasprintf(&m.mime, "video/3gpp");
switch( audio_profile ) switch( audio_profile )
{ {
case PROFILE_AUDIO_AAC: case PROFILE_AUDIO_AAC:
@ -1406,7 +1403,7 @@ GetVideoMetadata(const char * path, char * name)
m.dlna_pn = malloc(64); m.dlna_pn = malloc(64);
off = sprintf(m.dlna_pn, "WMV"); off = sprintf(m.dlna_pn, "WMV");
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basepath); 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) && if( (vc->width <= 176) &&
(vc->height <= 144) && (vc->height <= 144) &&
(vc->level == 0) ) (vc->level == 0) )
@ -1497,7 +1494,7 @@ GetVideoMetadata(const char * path, char * name)
} }
break; break;
case CODEC_ID_MSMPEG4V3: case CODEC_ID_MSMPEG4V3:
asprintf(&m.mime, "video/x-msvideo"); xasprintf(&m.mime, "video/x-msvideo");
default: default:
DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n", DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n",
video_stream, basepath, m.resolution, vc->codec_id); video_stream, basepath, m.resolution, vc->codec_id);
@ -1507,20 +1504,20 @@ GetVideoMetadata(const char * path, char * name)
if( !m.mime ) if( !m.mime )
{ {
if( strcmp(ctx->iformat->name, "avi") == 0 ) 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 ) 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 ) 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 ) else if( strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 )
if( ends_with(path, ".mov") ) if( ends_with(path, ".mov") )
asprintf(&m.mime, "video/quicktime"); xasprintf(&m.mime, "video/quicktime");
else else
asprintf(&m.mime, "video/mp4"); xasprintf(&m.mime, "video/mp4");
else if( strncmp(ctx->iformat->name, "matroska", 8) == 0 ) 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 ) else if( strcmp(ctx->iformat->name, "flv") == 0 )
asprintf(&m.mime, "video/x-flv"); xasprintf(&m.mime, "video/x-flv");
else else
DPRINTF(E_WARN, L_METADATA, "%s: Unhandled format: %s\n", path, ctx->iformat->name); DPRINTF(E_WARN, L_METADATA, "%s: Unhandled format: %s\n", path, ctx->iformat->name);
} }

View File

@ -407,11 +407,11 @@ bad_esds:
} }
/* AAC @ Level 1/2 */ /* AAC @ Level 1/2 */
if( psong->channels <= 2 && psong->bitrate <= 320000 ) 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 ) 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 ) else if( psong->channels <= 6 && psong->bitrate <= 1440000 )
asprintf(&(psong->dlna_pn), "AAC_MULT5_ISO"); xasprintf(&(psong->dlna_pn), "AAC_MULT5_ISO");
else else
DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n", DPRINTF(E_DEBUG, L_METADATA, "Unhandled AAC: %d channels, %d bitrate\n",
psong->channels, psong->bitrate); psong->channels, psong->bitrate);

View File

@ -47,15 +47,15 @@ _pick_dlna_profile(struct song_metadata *psong, uint16_t format)
{ {
case WMA: case WMA:
if( psong->max_bitrate < 193000 ) if( psong->max_bitrate < 193000 )
asprintf(&(psong->dlna_pn), "WMABASE"); xasprintf(&(psong->dlna_pn), "WMABASE");
else if( psong->max_bitrate < 385000 ) else if( psong->max_bitrate < 385000 )
asprintf(&(psong->dlna_pn), "WMAFULL"); xasprintf(&(psong->dlna_pn), "WMAFULL");
break; break;
case WMAPRO: case WMAPRO:
asprintf(&(psong->dlna_pn), "WMAPRO"); xasprintf(&(psong->dlna_pn), "WMAPRO");
break; break;
case WMALSL: case WMALSL:
asprintf(&(psong->dlna_pn), "WMALSL%s", xasprintf(&(psong->dlna_pn), "WMALSL%s",
psong->channels > 2 ? "_MULT5" : ""); psong->channels > 2 ? "_MULT5" : "");
default: default:
break; break;

View File

@ -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); //DEBUG DPRINTF(E_INFO, L_SCANNER, "Got fileinfo successfully for file=%s song_length=%d\n", file, psong->song_length);
psong->blockalignment = 1; psong->blockalignment = 1;
asprintf(&(psong->dlna_pn), "MP3"); xasprintf(&(psong->dlna_pn), "MP3");
return 0; return 0;
} }

View File

@ -42,8 +42,8 @@ _get_pcmfileinfo(char *filename, struct song_metadata *psong)
psong->song_length = (sec * 1000) + ms; psong->song_length = (sec * 1000) + ms;
psong->lossless = 1; psong->lossless = 1;
asprintf(&(psong->mime), "audio/L16;rate=%d;channels=%d", psong->samplerate, psong->channels); xasprintf(&(psong->mime), "audio/L16;rate=%d;channels=%d", psong->samplerate, psong->channels);
asprintf(&(psong->dlna_pn), "LPCM"); xasprintf(&(psong->dlna_pn), "LPCM");
return 0; return 0;
} }

View File

@ -46,6 +46,7 @@
#include "misc.h" #include "misc.h"
#include "textutils.h" #include "textutils.h"
#include "../metadata.h" #include "../metadata.h"
#include "../utils.h"
#include "../log.h" #include "../log.h"
struct id3header { struct id3header {

View File

@ -38,7 +38,7 @@ SendRootContainer(struct upnphttp * h)
char * resp; char * resp;
int len; int len;
len = asprintf(&resp, "<?xml version='1.0' encoding='UTF-8' ?>\n" len = xasprintf(&resp, "<?xml version='1.0' encoding='UTF-8' ?>\n"
"<TiVoContainer>" "<TiVoContainer>"
"<Details>" "<Details>"
"<ContentType>x-container/tivo-server</ContentType>" "<ContentType>x-container/tivo-server</ContentType>"
@ -291,7 +291,7 @@ SendItemDetails(struct upnphttp * h, sqlite_int64 item)
str.off = sprintf(str.data, "<?xml version='1.0' encoding='UTF-8' ?>\n<TiVoItem>"); str.off = sprintf(str.data, "<?xml version='1.0' encoding='UTF-8' ?>\n<TiVoItem>");
args.str = &str; args.str = &str;
args.requested = 1; args.requested = 1;
asprintf(&sql, SELECT_COLUMNS xasprintf(&sql, SELECT_COLUMNS
"from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)" "from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)"
" where o.DETAIL_ID = %lld group by o.DETAIL_ID", item); " where o.DETAIL_ID = %lld group by o.DETAIL_ID", item);
DPRINTF(E_DEBUG, L_TIVO, "%s\n", sql); 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 ) switch( *objectID )
{ {
case '1': case '1':
asprintf(&title, "Music on %s", friendly_name); xasprintf(&title, "Music on %s", friendly_name);
break; break;
case '2': case '2':
asprintf(&title, "Videos on %s", friendly_name); xasprintf(&title, "Videos on %s", friendly_name);
break; break;
case '3': case '3':
asprintf(&title, "Pictures on %s", friendly_name); xasprintf(&title, "Pictures on %s", friendly_name);
break; break;
default: default:
asprintf(&title, "Unknown on %s", friendly_name); xasprintf(&title, "Unknown on %s", friendly_name);
break; break;
} }
} }
@ -391,12 +391,12 @@ SendContainer(struct upnphttp * h, const char * objectID, int itemStart, int ite
if( recurse ) if( recurse )
{ {
asprintf(&which, "OBJECT_ID glob '%s$*'", objectID); xasprintf(&which, "OBJECT_ID glob '%s$*'", objectID);
strcpy(groupBy, "group by DETAIL_ID"); strcpy(groupBy, "group by DETAIL_ID");
} }
else else
{ {
asprintf(&which, "PARENT_ID = '%s'", objectID); xasprintf(&which, "PARENT_ID = '%s'", objectID);
} }
if( sortOrder ) if( sortOrder )

View File

@ -84,6 +84,12 @@ BuildSendAndCloseSoapResp(struct upnphttp * h,
"</s:Body>" "</s:Body>"
"</s:Envelope>\r\n"; "</s:Envelope>\r\n";
if (!body || bodylen < 0)
{
Send500(h);
return;
}
BuildHeader_upnphttp(h, 200, "OK", sizeof(beforebody) - 1 BuildHeader_upnphttp(h, 200, "OK", sizeof(beforebody) - 1
+ sizeof(afterbody) - 1 + bodylen ); + sizeof(afterbody) - 1 + bodylen );

17
utils.c
View File

@ -52,6 +52,23 @@ strncpyt(char *dst, const char *src, size_t len)
dst[len-1] = '\0'; 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 int
ends_with(const char * haystack, const char * needle) ends_with(const char * haystack, const char * needle)
{ {

View File

@ -32,6 +32,9 @@ strcatf(struct string_s *str, char *fmt, ...);
void void
strncpyt(char *dst, const char *src, size_t len); strncpyt(char *dst, const char *src, size_t len);
inline int
xasprintf(char **strp, char *fmt, ...);
int int
ends_with(const char * haystack, const char * needle); ends_with(const char * haystack, const char * needle);