summaryrefslogtreecommitdiff
path: root/cflac.c
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2009-08-21 20:27:38 +0200
committerGravatar waker <wakeroid@gmail.com>2009-08-21 20:29:27 +0200
commit7c72461fcfa2271394e2f76abe9c361fd32e675c (patch)
treef3bc1e14cc945e5369d016b0be1c577be84a05f5 /cflac.c
parentd070a54d5af27de9ecf49084c287a3e8f584bad7 (diff)
better robustness in cflac (checking fLaC signutare, more failsafes, etc)
Diffstat (limited to 'cflac.c')
-rw-r--r--cflac.c136
1 files changed, 77 insertions, 59 deletions
diff --git a/cflac.c b/cflac.c
index a83e4a38..ad82df53 100644
--- a/cflac.c
+++ b/cflac.c
@@ -74,7 +74,15 @@ cflac_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMe
void
cflac_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) {
- fprintf(stderr, "cflac: got error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
+// fprintf(stderr, "cflac: got error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
+}
+
+static int cflac_init_stop_decoding;
+
+void
+cflac_init_error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) {
+// fprintf(stderr, "cflac: got error callback: %s\n", FLAC__StreamDecoderErrorStatusString[status]);
+ cflac_init_stop_decoding = 1;
}
void
@@ -82,10 +90,26 @@ cflac_free (void);
int
cflac_init (playItem_t *it) {
+ FILE *fp = fopen (it->fname, "rb");
+ if (!fp) {
+ return -1;
+ }
+ char sign[4];
+ if (fread (sign, 1, 4, fp) != 4) {
+ fclose (fp);
+ return -1;
+ }
+ if (strncmp (sign, "fLaC", 4)) {
+ fclose (fp);
+ return -1;
+ }
+ fclose (fp);
+ fp = NULL;
+
FLAC__StreamDecoderInitStatus status;
decoder = FLAC__stream_decoder_new();
if (!decoder) {
- printf ("FLAC__stream_decoder_new failed\n");
+// printf ("FLAC__stream_decoder_new failed\n");
return -1;
}
FLAC__stream_decoder_set_md5_checking(decoder, 0);
@@ -177,7 +201,7 @@ cflac_seek (float time) {
static FLAC__StreamDecoderWriteStatus
cflac_init_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const inputbuffer[], void *client_data) {
- if (frame->header.blocksize == 0) {
+ if (frame->header.blocksize == 0 || cflac_init_stop_decoding) {
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
@@ -194,6 +218,9 @@ typedef struct {
void
cflac_init_cue_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) {
+ if (cflac_init_stop_decoding) {
+ return;
+ }
cue_cb_data_t *cb = (cue_cb_data_t *)client_data;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
cb->samplerate = metadata->data.stream_info.sample_rate;
@@ -257,6 +284,10 @@ cflac_init_cue_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC_
}
void
cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) {
+ if (cflac_init_stop_decoding) {
+ printf ("error flag is set, ignoring init_metadata callback..\n");
+ return;
+ }
playItem_t *it = (playItem_t *)client_data;
//it->tracknum = 0;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
@@ -304,39 +335,49 @@ cflac_init_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__Str
playItem_t *
cflac_insert (playItem_t *after, const char *fname) {
+ playItem_t *it = NULL;
+ FLAC__StreamDecoder *decoder = NULL;
+ FILE *fp = fopen (fname, "rb");
+ if (!fp) {
+ goto cflac_insert_fail;
+ }
+ char sign[4];
+ if (fread (sign, 1, 4, fp) != 4) {
+ goto cflac_insert_fail;
+ }
+ if (strncmp (sign, "fLaC", 4)) {
+ goto cflac_insert_fail;
+ }
+ fclose (fp);
+ fp = NULL;
+ cflac_init_stop_decoding = 0;
//try embedded cue, and calculate duration
- FLAC__StreamDecoder *decoder = 0;
FLAC__StreamDecoderInitStatus status;
decoder = FLAC__stream_decoder_new();
if (!decoder) {
- printf ("FLAC__stream_decoder_new failed\n");
- return NULL;
+ goto cflac_insert_fail;
}
FLAC__stream_decoder_set_md5_checking(decoder, 0);
// try embedded cue
- //printf ("trying embedded cue\n");
cue_cb_data_t cb = {
.fname = fname,
.after = after,
.last = after
};
FLAC__stream_decoder_set_metadata_respond_all (decoder);
- status = FLAC__stream_decoder_init_file(decoder, fname, cflac_init_write_callback, cflac_init_cue_metadata_callback, cflac_error_callback, &cb);
- if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
- printf ("init_file failed\n");
- FLAC__stream_decoder_delete(decoder);
- return NULL;
+ status = FLAC__stream_decoder_init_file (decoder, fname, cflac_init_write_callback, cflac_init_cue_metadata_callback, cflac_init_error_callback, &cb);
+ if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK || cflac_init_stop_decoding) {
+ goto cflac_insert_fail;
}
- if (!FLAC__stream_decoder_process_until_end_of_metadata (decoder)) {
- printf ("process_until_end_of_metadata failed\n");
- FLAC__stream_decoder_delete(decoder);
- return NULL;
+ if (!FLAC__stream_decoder_process_until_end_of_metadata (decoder) || cflac_init_stop_decoding) {
+ goto cflac_insert_fail;
}
FLAC__stream_decoder_delete(decoder);
+ decoder = NULL;
if (cb.last != after) {
- //printf ("embedded cue found!\n");
+// printf ("embedded cue found!\n");
return cb.last;
}
@@ -347,67 +388,44 @@ cflac_insert (playItem_t *after, const char *fname) {
cue_after->duration = cue_after->timeend - cue_after->timestart;
return cue_after;
}
-#if 0
- char cuename[1024];
- snprintf (cuename, 1024, "%s.cue", fname);
- playItem_t *cue_after;
- if ((cue_after = pl_insert_cue (after, cuename, &cflac, "flac")) != NULL) {
- cue_after->timeend = cb.duration;
- cue_after->duration = cue_after->timeend - cue_after->timestart;
- return cue_after;
- }
- int n = strlen (fname) - 4;
- if (n > 0) {
- strncpy (cuename, fname, n);
- strcpy (cuename + n, "cue");
- // printf ("loading %s\n", cuename);
- if ((cue_after = pl_insert_cue (after, cuename, &cflac, "flac")) != NULL) {
- cue_after->timeend = cb.duration;
- cue_after->duration = cue_after->timeend - cue_after->timestart;
- return cue_after;
- }
- }
-#endif
- //printf ("adding flac without cue\n");
decoder = FLAC__stream_decoder_new();
if (!decoder) {
- printf ("FLAC__stream_decoder_new failed\n");
- return NULL;
+ goto cflac_insert_fail;
}
FLAC__stream_decoder_set_md5_checking(decoder, 0);
// try single FLAC file without cue
FLAC__stream_decoder_set_metadata_respond_all (decoder);
int samplerate = -1;
- playItem_t *it = malloc (sizeof (playItem_t));
+ it = malloc (sizeof (playItem_t));
memset (it, 0, sizeof (playItem_t));
it->codec = &cflac;
it->fname = strdup (fname);
it->tracknum = 0;
it->timestart = 0;
it->timeend = 0;
-// it->tracknum = -1;
- status = FLAC__stream_decoder_init_file(decoder, fname, cflac_init_write_callback, cflac_init_metadata_callback, cflac_error_callback, it);
- if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
- FLAC__stream_decoder_delete(decoder);
- pl_item_free (it);
- return NULL;
+ status = FLAC__stream_decoder_init_file (decoder, fname, cflac_init_write_callback, cflac_init_metadata_callback, cflac_init_error_callback, it);
+ if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK || cflac_init_stop_decoding) {
+ goto cflac_insert_fail;
}
- if (!FLAC__stream_decoder_process_until_end_of_metadata (decoder)) {
- FLAC__stream_decoder_delete(decoder);
- pl_item_free (it);
- return NULL;
+ if (!FLAC__stream_decoder_process_until_end_of_metadata (decoder) || cflac_init_stop_decoding) {
+ goto cflac_insert_fail;
}
-#if 0
- if (it->tracknum == -1) { // not a FLAC stream
- FLAC__stream_decoder_delete(decoder);
- pl_item_free (it);
- return NULL;
- }
-#endif
FLAC__stream_decoder_delete(decoder);
+ decoder = NULL;
it->filetype = "FLAC";
after = pl_insert_item (after, it);
return after;
+cflac_insert_fail:
+ if (it) {
+ pl_item_free (it);
+ }
+ if (decoder) {
+ FLAC__stream_decoder_delete(decoder);
+ }
+ if (fp) {
+ fclose (fp);
+ }
+ return NULL;
}
static const char * exts[]=