[xiph-commits] r12553 - trunk/ezstream/src
moritz at svn.xiph.org
moritz at svn.xiph.org
Sat Feb 24 18:36:41 PST 2007
Author: moritz
Date: 2007-02-24 18:36:40 -0800 (Sat, 24 Feb 2007)
New Revision: 12553
Modified:
trunk/ezstream/src/ezstream.c
Log:
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.
Modified: trunk/ezstream/src/ezstream.c
===================================================================
--- trunk/ezstream/src/ezstream.c 2007-02-25 01:14:36 UTC (rev 12552)
+++ trunk/ezstream/src/ezstream.c 2007-02-25 02:36:40 UTC (rev 12553)
@@ -135,6 +135,9 @@
#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 @@
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);
+ 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();
}
- else {
- strcat(dest, p1);
- }
+ 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) {
More information about the commits
mailing list