diff --git a/src/libFLAC/metadata_iterators.c b/src/libFLAC/metadata_iterators.c index 4527878..4b11965 100644 --- a/src/libFLAC/metadata_iterators.c +++ b/src/libFLAC/metadata_iterators.c @@ -3281,7 +3281,8 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix local_snprintf(*tempfilename, dest_len, "%s/%s%s", tempfile_path_prefix, p, tempfile_suffix); } - if(0 == (*tempfile = flac_fopen(*tempfilename, "w+b"))) { + (void)unlink(*tempfilename); + if(0 == (*tempfile = fopen(*tempfilename, "w+bx"))) { *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; return false; } @@ -3297,9 +3298,24 @@ FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tem FLAC__ASSERT(0 != tempfilename); FLAC__ASSERT(0 != *tempfilename); FLAC__ASSERT(0 != status); + int tempfd; - (void)fclose(*tempfile); - *tempfile = 0; + tempfd = fileno(*tempfile); + /* Oddly enough, fflush seems to set fileno to 0! */ +#if 0 + fprintf(stderr, "transport_tempfile_: tempfile=%p *tempfile=%p fileno(*tempfile)=%d tempfilename=%s\n", + tempfile, *tempfile, tempfd, tempfilename); +#endif + if ((fflush(*tempfile) == EOF) || + (fsync(tempfd) == -1) || + (fclose(*tempfile) == EOF)) { + *tempfile = 0; + cleanup_tempfile_(tempfile, tempfilename); + *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + return false; + } + + *tempfile = 0; #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ || defined __EMX__ /* on some flavors of windows, flac_rename() will fail if the destination already exists */ diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index 6380ce6..e095f9e 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -39,6 +39,7 @@ #include /* for malloc() */ #include /* for memcpy() */ #include /* for off_t */ +#include #include "share/compat.h" #include "FLAC/assert.h" #include "FLAC/stream_decoder.h" @@ -1494,8 +1495,14 @@ FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) } if(0 != encoder->private_->file) { - if(encoder->private_->file != stdout) - fclose(encoder->private_->file); + if(encoder->private_->file != stdout) { + if (fflush(encoder->private_->file) == EOF) + error = true; + if (fsync(fileno(encoder->private_->file)) == -1) + error = true; + if (fclose(encoder->private_->file) == EOF) + error = true; + } encoder->private_->file = 0; } diff --git a/src/plugin_common/dither.c b/src/plugin_common/dither.c index f83a75a..018fde9 100644 --- a/src/plugin_common/dither.c +++ b/src/plugin_common/dither.c @@ -37,15 +37,29 @@ #define FLaC__INLINE #endif +#define ROTATE(v,n) (((v) << (n)) | ((v) >> (32 - (n)))) + +#define __jhash_mix(a, b, c) \ +{ \ + a -= b; a -= c; a ^= (ROTATE(c,19)); \ + b -= c; b -= a; b ^= (ROTATE(a,8)); \ + c -= a; c -= b; c ^= (ROTATE(b,19)); \ + a -= b; a -= c; a ^= (ROTATE(c,20)); \ + b -= c; b -= a; b ^= (ROTATE(a,16)); \ + c -= a; c -= b; c ^= (ROTATE(b,27)); \ + a -= b; a -= c; a ^= (ROTATE(c,29)); \ + b -= c; b -= a; b ^= (ROTATE(a,10)); \ + c -= a; c -= b; c ^= (ROTATE(b,17)); \ +} /* 32-bit pseudo-random number generator - * - * @@@ According to Miroslav, this one is poor quality, the one from the - * @@@ original replaygain code is much better */ static FLaC__INLINE FLAC__uint32 prng(FLAC__uint32 state) { - return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL; + FLAC__uint32 a = 42, b = 69, c = state; + + __jhash_mix(a,b,c); + return c; } /* dither routine derived from MAD winamp plugin */ diff --git a/src/test_libFLAC++/metadata_manip.cpp b/src/test_libFLAC++/metadata_manip.cpp index 336fdd7..2586a8e 100644 --- a/src/test_libFLAC++/metadata_manip.cpp +++ b/src/test_libFLAC++/metadata_manip.cpp @@ -210,7 +210,8 @@ bool open_tempfile_(const char *filename, FILE **tempfile, char **tempfilename) return false; flac_snprintf(*tempfilename, destlen, "%s%s", filename, tempfile_suffix); - if(0 == (*tempfile = flac_fopen(*tempfilename, "wb"))) + (void)unlink(*tempfilename); + if(0 == (*tempfile = fopen(*tempfilename, "wbx"))) return false; return true; --- flac-1.3.1/src/flac/decode.c.safari 2014-11-27 03:19:47.036800240 +0200 +++ flac-1.3.1/src/flac/decode.c 2015-08-03 23:13:02.291616592 +0300 @@ -99,7 +99,7 @@ static FLAC__bool is_big_endian_host_; * local routines */ static FLAC__bool DecoderSession_construct(DecoderSession *d, FLAC__bool is_ogg, FLAC__bool use_first_serial_number, long serial_number, FileFormat format, FLAC__bool treat_warnings_as_errors, FLAC__bool continue_through_decode_errors, FLAC__bool channel_map_none, replaygain_synthesis_spec_t replaygain_synthesis_spec, FLAC__bool analysis_mode, analysis_options aopts, utils__SkipUntilSpecification *skip_specification, utils__SkipUntilSpecification *until_specification, utils__CueSpecification *cue_specification, foreign_metadata_t *foreign_metadata, const char *infilename, const char *outfilename); -static void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred); +static FLAC__bool DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred); static FLAC__bool DecoderSession_init_decoder(DecoderSession *d, const char *infilename); static FLAC__bool DecoderSession_process(DecoderSession *d); static int DecoderSession_finish_ok(DecoderSession *d); @@ -260,30 +260,29 @@ FLAC__bool DecoderSession_construct(Deco return true; } -void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred) +/* Success: true, Fail: false */ +FLAC__bool DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred) { if(0 != d->fout && d->fout != stdout) { -#ifdef _WIN32 - if(!error_occurred) { - FLAC__off_t written_size = ftello(d->fout); - if(written_size > 0) { - HANDLE fh = CreateFile_utf8(d->outfilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if(fh != INVALID_HANDLE_VALUE) { - if(GetFileType(fh) == FILE_TYPE_DISK) { - LARGE_INTEGER size; - size.QuadPart = written_size; - if(SetFilePointerEx(fh, size, NULL, FILE_CURRENT)) /* correct the file size */ - SetEndOfFile(fh); - } - CloseHandle(fh); - } + if (!error_occurred) { + if (fflush(d->fout) == EOF) { + fclose(d->fout); + return false; } - } -#endif - fclose(d->fout); - if(error_occurred) + if (fsync(fileno(d->fout)) == -1) { + fclose(d->fout); + return false; + } + if (fclose(d->fout) == EOF) { + return false; + } + } else { + fclose(d->fout); flac_unlink(d->outfilename); + return false; + } } + return true; } FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, const char *infilename) @@ -496,7 +495,9 @@ int DecoderSession_finish_ok(DecoderSess stats_print_name(2, d->inbasefilename); flac__utils_printf(stderr, 2, "%s \n", d->test_only? "ok ":d->analysis_mode?"done ":"done"); } - DecoderSession_destroy(d, /*error_occurred=*/!ok); + if (DecoderSession_destroy(d, /*error_occurred=*/!ok) == false) + ok = 0; + if(!d->analysis_mode && !d->test_only && d->format != FORMAT_RAW) { if(d->iff_headers_need_fixup || (!d->got_stream_info && strcmp(d->outfilename, "-"))) { if(!fixup_iff_headers(d))