1
0
mirror of https://gitlab.xiph.org/xiph/ezstream.git synced 2024-11-03 04:17:18 -05:00

Merge changes to replaceString() and buildCommandString(), and do the formatting

nitpickery to setMetadata(). Changes in replaceString():
 * Fix a heap overflow. replaceString() would happily replace multiple '@T@'
   and '@M@' placeholders and write into *dest until things blow up. Fix this
   by using safe string functions. Then completely prevent it by ensuring that
   it replaces only one placeholder per call (adjusting buildCommandString()
   accordingly) and already complaining to the user in parseConfig() about
   illegal, multiple placeholders in their command lines. (That parseConfig()
   change was missing from the commit log earlier.)
In buildCommandString():
 * Use xcalloc() instead of malloc() and get rid of the now redundant memset()
   calls.
 * Allow decoder command lines to contain the '@M@' metadata placeholder.
   Useful for combined de-/encoders like ffmpeg2theora.
 * Tweak message about "unsupported" format, which used to be false in the case
   of Ogg Theora streams.
 * Plug several memory leaks.
 * Don't print the "Executing command 'foo'" message in this function.


git-svn-id: https://svn.xiph.org/trunk/ezstream@12553 0101bb08-14d6-0310-b084-bc0e0c8e3800
This commit is contained in:
moritz 2007-02-25 02:36:40 +00:00
parent 710570627d
commit d657af0b8a

View File

@ -135,6 +135,9 @@ char * basename(const char *);
#endif
int strrcmp(const char *, const char *);
int urlParse(const char *, char **, int *, char **);
void replaceString(const char *, char *, size_t, const char *, const char *);
void setMetadata(shout_t *, const char *);
char * buildCommandString(const char *, const char *, const char *);
int streamPlaylist(shout_t *, const char *);
char * getProgname(const char *);
void usage(void);
@ -204,87 +207,103 @@ urlParse(const char *url, char **hostname, int *port, char **mountname)
return (1);
}
void replaceString(char *source, char *dest, char *from, char *to)
void
replaceString(const char *source, char *dest, size_t size,
const char *from, const char *to)
{
char *p2 = (char *)1;
char *p1 = source;
while (p2) {
p2 = strstr(p1, from);
if (p2) {
strncat(dest, p1, p2-p1);
strcat(dest, to);
p1 = p2 + strlen(from);
}
else {
strcat(dest, p1);
char *p1 = (char *)source;
char *p2;
p2 = strstr(p1, from);
if (p2 != NULL) {
if (p2 - p1 >= size) {
printf("%s: replaceString(): Internal error: p2 - p1 >= size\n",
__progname);
abort();
}
strncat(dest, p1, p2 - p1);
strlcat(dest, to, size);
p1 = p2 + strlen(from);
}
strlcat(dest, p1, size);
}
void setMetadata(shout_t *shout, char *metadata)
void
setMetadata(shout_t *shout, const char *metadata)
{
shout_metadata_t *shoutMetadata = shout_metadata_new();
shout_metadata_add(shoutMetadata, "song", metadata);
shout_set_metadata(shout, shoutMetadata);
shout_metadata_free(shoutMetadata);
}
char* buildCommandString(char *extension, char *fileName, char *metadata)
char*
buildCommandString(const char *extension, const char *fileName,
const char *metadata)
{
char *commandString = NULL;
char *encoder = NULL;
char *decoder = NULL;
int newDecoderLen = 0;
char *newDecoder = NULL;
char *newEncoder = NULL;
int newEncoderLen = 0;
int commandStringLen = 0;
size_t commandStringLen = 0;
char *encoder = NULL;
char *decoder = NULL;
char *newDecoder = NULL;
size_t newDecoderLen = 0;
char *newEncoder = NULL;
size_t newEncoderLen = 0;
decoder = strdup(getFormatDecoder(extension));
decoder = xstrdup(getFormatDecoder(extension));
if (strlen(decoder) == 0) {
printf("Unknown extension %s, cannot decode\n", extension);
return commandString;
printf("%s: Unknown extension '%s', cannot decode '%s'.\n",
__progname, extension, fileName);
xfree(decoder);
return (NULL);
}
newDecoderLen = strlen(decoder) + strlen(fileName) + 1;
newDecoder = (char *)malloc(newDecoderLen);
memset(newDecoder, '\000', newDecoderLen);
replaceString(decoder, newDecoder, "@T@", fileName);
newDecoder = xcalloc(1, newDecoderLen);
replaceString(decoder, newDecoder, newDecoderLen, TRACK_PLACEHOLDER,
fileName);
if (strstr(decoder, METADATA_PLACEHOLDER) != NULL) {
size_t tmpLen = strlen(newDecoder) + strlen(metadata) + 1;
char *tmpStr = xcalloc(1, tmpLen);
replaceString(newDecoder, tmpStr, tmpLen, METADATA_PLACEHOLDER,
metadata);
xfree(newDecoder);
newDecoder = tmpStr;
}
encoder = strdup(getFormatEncoder(pezConfig->format));
encoder = xstrdup(getFormatEncoder(pezConfig->format));
if (strlen(encoder) == 0) {
printf("Unknown format %s, passing right on through!\n", pezConfig->format);
if (vFlag)
printf("%s: Passing through%s%s data from the decoder\n",
__progname,
(strcmp(pezConfig->format, THEORA_FORMAT) != 0) ? " (unsupported) " : " ",
pezConfig->format);
commandStringLen = strlen(newDecoder) + 1;
commandString = (char *)malloc(commandStringLen);
memset(commandString, '\000', commandStringLen);
sprintf(commandString, "%s", newDecoder);
if (decoder) {
free(decoder);
}
if (encoder) {
free(encoder);
}
return commandString;
commandString = xcalloc(1, commandStringLen);
strlcpy(commandString, newDecoder, commandStringLen);
xfree(decoder);
xfree(encoder);
xfree(newDecoder);
return (commandString);
}
else {
newEncoderLen = strlen(encoder) + strlen(metadata) + 1;
newEncoder = (char *)malloc(newEncoderLen);
memset(newEncoder, '\000', newEncoderLen);
replaceString(encoder, newEncoder, "@M@", metadata);
newEncoderLen = strlen(encoder) + strlen(metadata) + 1;
newEncoder = xcalloc(1, newEncoderLen);
replaceString(encoder, newEncoder, newEncoderLen, METADATA_PLACEHOLDER,
metadata);
commandStringLen = strlen(newDecoder) + strlen(" | ") + strlen(newEncoder) + 1;
commandString = (char *)malloc(commandStringLen);
memset(commandString, '\000', commandStringLen);
sprintf(commandString, "%s | %s", newDecoder, newEncoder);
}
if (decoder) {
free(decoder);
}
if (encoder) {
free(encoder);
}
printf("Going to execute (%s)\n", commandString);
return(commandString);
commandStringLen = strlen(newDecoder) + strlen(" | ") +
strlen(newEncoder) + 1;
commandString = xcalloc(1, commandStringLen);
snprintf(commandString, commandStringLen, "%s | %s", newDecoder,
newEncoder);
xfree(decoder);
xfree(encoder);
xfree(newDecoder);
xfree(newEncoder);
return (commandString);
}
char * processMetadata(shout_t *shout, char *extension, char *fileName) {