shithub: aacdec

Download patch

ref: d55294868ab65259c88f9f608165066b06cd810e
parent: f27df30594f3751d36c95f9d2e58a42a924b3413
parent: 623026a394cfb634788f8f238084b932674ede56
author: Krzysztof Nikiel <knik0@users.noreply.github.com>
date: Sat Dec 16 16:15:35 EST 2017

Merge pull request #4 from lordmulder/master

Fixed possible buffer overflow + various Win32/MSVC build fixes + Win32 Unicode support

--- a/frontend/audio.c
+++ b/frontend/audio.c
@@ -38,6 +38,7 @@
 #include <neaacdec.h>
 #include <stdint.h>
 
+#include "unicode_support.h"
 #include "audio.h"
 
 
@@ -74,13 +75,13 @@
     if(infile[0] == '-')
     {
 #ifdef _WIN32
-        setmode(fileno(stdout), O_BINARY);
+        _setmode(_fileno(stdout), O_BINARY);
 #endif
         aufile->sndfile = stdout;
         aufile->toStdio = 1;
     } else {
         aufile->toStdio = 0;
-        aufile->sndfile = fopen(infile, "wb");
+        aufile->sndfile = faad_fopen(infile, "wb");
     }
 
     if (aufile->sndfile == NULL)
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -35,6 +35,7 @@
 #ifdef _WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
+#include <io.h>
 #ifndef __MINGW32__
 #define off_t __int64
 #endif
@@ -51,6 +52,7 @@
 
 #include <neaacdec.h>
 
+#include "unicode_support.h"
 #include "audio.h"
 #include "mp4read.h"
 
@@ -68,6 +70,7 @@
 #define MAX_CHANNELS 6 /* make this higher to support files with
                           more channels */
 
+#define MAX_PERCENTS 384
 
 static int quiet = 0;
 
@@ -78,11 +81,16 @@
     if (!quiet)
     {
         va_start(ap, fmt);
-
         vfprintf(stream, fmt, ap);
-
         va_end(ap);
     }
+
+#ifdef _WIN32
+	if (!_isatty(_fileno(stream)))
+	{
+		fflush(stream); /*ensure real-time progress output on Win32*/
+	}
+#endif
 }
 
 /* FAAD file buffering routines */
@@ -462,7 +470,7 @@
     NeAACDecFrameInfo frameInfo;
     NeAACDecConfigurationPtr config;
 
-    char percents[200];
+    char percents[MAX_PERCENTS];
     int percent, old_percent = -1;
     int bread, fileread;
     int header_type = 0;
@@ -479,7 +487,7 @@
 
     if (adts_out)
     {
-        adtsFile = fopen(adts_fn, "wb");
+        adtsFile = faad_fopen(adts_fn, "wb");
         if (adtsFile == NULL)
         {
             faad_fprintf(stderr, "Error opening file: %s\n", adts_fn);
@@ -491,12 +499,12 @@
     {
 	b.infile = stdin;
 #ifdef _WIN32
-        setmode(fileno(stdin), O_BINARY);
+        _setmode(_fileno(stdin), O_BINARY);
 #endif
 
     } else
     {
-    	b.infile = fopen(aacfile, "rb");
+    	b.infile = faad_fopen(aacfile, "rb");
     	if (b.infile == NULL)
     	{
     	    /* unable to open file */
@@ -727,7 +735,7 @@
         if (percent > old_percent)
         {
             old_percent = percent;
-            sprintf(percents, "%d%% decoding %s.", percent, aacfile);
+            snprintf(percents, MAX_PERCENTS, "%d%% decoding %s.", percent, aacfile);
             faad_fprintf(stderr, "%s\r", percents);
 #ifdef _WIN32
             SetConsoleTitle(percents);
@@ -795,7 +803,7 @@
     NeAACDecFrameInfo frameInfo;
     mp4AudioSpecificConfig mp4ASC;
 
-    char percents[200];
+    char percents[MAX_PERCENTS];
     int percent, old_percent = -1;
 
     int first_time = 1;
@@ -833,7 +841,7 @@
 
     if (adts_out)
     {
-        adtsFile = fopen(adts_fn, "wb");
+        adtsFile = faad_fopen(adts_fn, "wb");
         if (adtsFile == NULL)
         {
             faad_fprintf(stderr, "Error opening file: %s\n", adts_fn);
@@ -953,7 +961,7 @@
                         outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
                 } else {
 #ifdef _WIN32
-                    setmode(fileno(stdout), O_BINARY);
+                    _setmode(_fileno(stdout), O_BINARY);
 #endif
                     aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
                         outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
@@ -972,7 +980,7 @@
         if (percent > old_percent)
         {
             old_percent = percent;
-            sprintf(percents, "%d%% decoding %s.", percent, mp4file);
+            snprintf(percents, MAX_PERCENTS, "%d%% decoding %s.", percent, mp4file);
             faad_fprintf(stderr, "%s\r", percents);
 #ifdef _WIN32
             SetConsoleTitle(percents);
@@ -1007,7 +1015,7 @@
     return frameInfo.error;
 }
 
-int main(int argc, char *argv[])
+static int faad_main(int argc, char *argv[])
 {
     int result;
     int infoOnly = 0;
@@ -1265,13 +1273,13 @@
 	readFromStdin = 1;
 	hMP4File  = stdin;
 #ifdef _WIN32
-        setmode(fileno(stdin), O_BINARY);
+        _setmode(_fileno(stdin), O_BINARY);
 #endif
 
     } else {
 
     	mp4file = 0;
-    	hMP4File = fopen(aacFileName, "rb");
+    	hMP4File = faad_fopen(aacFileName, "rb");
     	if (!hMP4File)
     	{
     	    faad_fprintf(stderr, "Error opening file: %s\n", aacFileName);
@@ -1338,3 +1346,19 @@
 
     return 0;
 }
+
+int main(int argc, char *argv[])
+{
+#ifdef _WIN32
+	int argc_utf8, exit_code;
+	char **argv_utf8;
+	init_console_utf8(stderr);
+	init_commandline_arguments_utf8(&argc_utf8, &argv_utf8);
+	exit_code = faad_main(argc_utf8, argv_utf8);
+	free_commandline_arguments_utf8(&argc_utf8, &argv_utf8);
+	uninit_console_utf8();
+	return exit_code;
+#else
+	return faad_main(argc, argv);
+#endif
+}
\ No newline at end of file
--- a/frontend/mp4read.c
+++ b/frontend/mp4read.c
@@ -24,6 +24,7 @@
 #include <time.h>
 #include <limits.h>
 
+#include "unicode_support.h"
 #include "mp4read.h"
 
 enum ATOM_TYPE
@@ -45,18 +46,30 @@
 
 static FILE *g_fin = NULL;
 
-static inline uint32_t bswap32(uint32_t u32)
+static inline uint32_t bswap32(const uint32_t u32)
 {
 #ifndef WORDS_BIGENDIAN
+#ifdef _MSC_VER
+	return _byteswap_ulong(u32);
+#else
     return __builtin_bswap32(u32);
 #endif
+#else
+	return u32;
+#endif
 }
 
-static inline uint16_t bswap16(uint16_t u16)
+static inline uint16_t bswap16(const uint16_t u16)
 {
 #ifndef WORDS_BIGENDIAN
-    return __builtin_bswap16(u16);
+#ifdef _MSC_VER
+	return _byteswap_ushort(u16);
+#else
+	return __builtin_bswap16(u16);
 #endif
+#else
+	return u16;
+#endif
 }
 
 enum {ERR_OK = 0, ERR_FAIL = -1, ERR_UNSUPPORTED = -2};
@@ -927,7 +940,7 @@
 
 static void mp4info(void)
 {
-    fprintf(stderr, "Modification Time:\t\%s", mp4time(mp4config.mtime));
+    fprintf(stderr, "Modification Time:\t\t%s", mp4time(mp4config.mtime));
     fprintf(stderr, "Samplerate:\t\t%d\n", mp4config.samplerate);
     fprintf(stderr, "Total samples:\t\t%d\n", mp4config.samples);
     fprintf(stderr, "Total channels:\t\t%d\n", mp4config.channels);
@@ -958,7 +971,7 @@
 
     mp4read_close();
 
-    g_fin = fopen(name, "rb");
+    g_fin = faad_fopen(name, "rb");
     if (!g_fin)
         return ERR_FAIL;
 
--- /dev/null
+++ b/frontend/unicode_support.c
@@ -1,0 +1,172 @@
+/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de>
+   File: unicode_support.c
+
+   This file was originally part of a patch included with LameXP,
+   released under the same license as the original audio tools.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
+
+#include "unicode_support.h"
+
+#include <windows.h>
+#include <io.h>
+
+static UINT g_old_output_cp = ((UINT)-1);
+
+char *utf16_to_utf8(const wchar_t *input)
+{
+	char *Buffer;
+	int BuffSize = 0, Result = 0;
+
+	BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL);
+	Buffer = (char*) malloc(sizeof(char) * BuffSize);
+	if(Buffer)
+	{
+		Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL);
+	}
+
+	return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
+}
+
+char *utf16_to_ansi(const wchar_t *input)
+{
+	char *Buffer;
+	int BuffSize = 0, Result = 0;
+
+	BuffSize = WideCharToMultiByte(CP_ACP, 0, input, -1, NULL, 0, NULL, NULL);
+	Buffer = (char*) malloc(sizeof(char) * BuffSize);
+	if(Buffer)
+	{
+		Result = WideCharToMultiByte(CP_ACP, 0, input, -1, Buffer, BuffSize, NULL, NULL);
+	}
+
+	return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
+}
+
+wchar_t *utf8_to_utf16(const char *input)
+{
+	wchar_t *Buffer;
+	int BuffSize = 0, Result = 0;
+
+	BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
+	Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize);
+	if(Buffer)
+	{
+		Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize);
+	}
+
+	return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
+}
+
+void init_commandline_arguments_utf8(int *argc, char ***argv)
+{
+	int i, nArgs;
+	LPWSTR *szArglist;
+
+	szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
+
+	if(NULL == szArglist)
+	{
+		fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n");
+		exit(-1);
+	}
+
+	*argv = (char**) malloc(sizeof(char*) * nArgs);
+	*argc = nArgs;
+
+	if(NULL == *argv)
+	{
+		fprintf(stderr, "\nFATAL: Malloc failed\n\n");
+		exit(-1);
+	}
+	
+	for(i = 0; i < nArgs; i++)
+	{
+		(*argv)[i] = utf16_to_utf8(szArglist[i]);
+		if(NULL == (*argv)[i])
+		{
+			fprintf(stderr, "\nFATAL: utf16_to_utf8 failed\n\n");
+			exit(-1);
+		}
+	}
+
+	LocalFree(szArglist);
+}
+
+void free_commandline_arguments_utf8(int *argc, char ***argv)
+{
+	int i = 0;
+	
+	if(*argv != NULL)
+	{
+		for(i = 0; i < *argc; i++)
+		{
+			if((*argv)[i] != NULL)
+			{
+				free((*argv)[i]);
+				(*argv)[i] = NULL;
+			}
+		}
+		free(*argv);
+		*argv = NULL;
+	}
+}
+
+FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8)
+{
+	FILE *ret = NULL;
+	wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8);
+	wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8);
+	
+	if(filename_utf16 && mode_utf16)
+	{
+		ret = _wfopen(filename_utf16, mode_utf16);
+	}
+
+	if(filename_utf16) free(filename_utf16);
+	if(mode_utf16) free(mode_utf16);
+
+	return ret;
+}
+
+void init_console_utf8(FILE *const stream)
+{
+	if (_isatty(_fileno(stream)))
+	{
+		g_old_output_cp = GetConsoleOutputCP();
+		SetConsoleOutputCP(CP_UTF8);
+	}
+}
+
+void uninit_console_utf8(void)
+{
+	if(g_old_output_cp != ((UINT)-1))
+	{
+		SetConsoleOutputCP(g_old_output_cp);
+	}
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/frontend/unicode_support.h
@@ -1,0 +1,49 @@
+/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de>
+   File: unicode_support.h
+
+   This file was originally part of a patch included with LameXP,
+   released under the same license as the original audio tools.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef UNICODE_SUPPORT_H_INCLUDED
+#define UNICODE_SUPPORT_H_INCLUDED
+
+#include <stdio.h>
+
+#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
+char *utf16_to_utf8(const wchar_t *input);
+char *utf16_to_ansi(const wchar_t *input);
+wchar_t *utf8_to_utf16(const char *input);
+void init_commandline_arguments_utf8(int *argc, char ***argv);
+void free_commandline_arguments_utf8(int *argc, char ***argv);
+FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8);
+void init_console_utf8(FILE *const stream);
+void uninit_console_utf8(void);
+#define faad_fopen(X,Y) fopen_utf8((X),(Y))
+#else
+#define faad_fopen(X,Y) fopen((X),(Y))
+#endif
+
+#endif //UNICODE_SUPPORT_H_INCLUDED