Add to check junk data 96/119996/1 accepted/tizen_common accepted/tizen_ivi accepted/tizen_mobile accepted/tizen_tv accepted/tizen_wearable accepted/tizen/common/20170322.153633 accepted/tizen/ivi/20170322.235545 accepted/tizen/mobile/20170322.235514 accepted/tizen/tv/20170322.235528 accepted/tizen/unified/20170322.235559 accepted/tizen/wearable/20170322.235539 submit/tizen/20170322.011031
authorJiyong Min <jiyong.min@samsung.com>
Mon, 20 Mar 2017 07:43:04 +0000 (16:43 +0900)
committerJiyong Min <jiyong.min@samsung.com>
Tue, 21 Mar 2017 05:25:43 +0000 (14:25 +0900)
 [Problem] It is too long to read mpeg header when it was broken.
- When read tag from the file with the junk data, read whole file to find tag
because of wrong offset of box.
If the offset of box was wrong, add to check the moov data has already found at first.
After reading moov data is done, it check junk data for 1000 times.

Change-Id: I7ff67e7076870c6af43a1f3a98565c2b5cea856c
Signed-off-by: jiyong.min <jiyong.min@samsung.com>
Conflicts:
packaging/libmm-fileinfo.spec

Change-Id: I4ad0f2ff2000a8b8a784665a852a1e6f767c74d3
Signed-off-by: jiyong.min <jiyong.min@samsung.com>
configure.ac
mm_file_config.ini [new file with mode: 0644]
packaging/libmm-fileinfo.spec
utils/Makefile.am
utils/include/mm_file_utils.h
utils/mm_file_util_tag.c

index ab417f6..db9a9a6 100755 (executable)
@@ -67,6 +67,9 @@ PKG_CHECK_MODULES(GTK, gtk+-2.0, [HAVE_GTK=yes], [HAVE_GTK=no])
 AC_SUBST(GTK_CFLAGS)
 AC_SUBST(GTK_LIBS)
 
+PKG_CHECK_MODULES(INIPARSER, iniparser)
+AC_SUBST(INIPARSER_CFLAGS)
+AC_SUBST(INIPARSER_LIBS)
 
 PKG_CHECK_MODULES(AVCODEC, libavcodec)
 AC_SUBST(AVCODEC_CFLAGS)
diff --git a/mm_file_config.ini b/mm_file_config.ini
new file mode 100644 (file)
index 0000000..86f51bc
--- /dev/null
@@ -0,0 +1,4 @@
+;junk_counter_limit
+; limit loop count for junk-data in mpeg4
+[mm-file-config]
+junk_counter_limit=1000
index 9ea708e..cb9a9d1 100755 (executable)
@@ -1,6 +1,6 @@
 Name:      libmm-fileinfo
 Summary:    Media Fileinfo
-Version:    0.6.57
+Version:    0.6.58
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
@@ -13,6 +13,7 @@ BuildRequires: pkgconfig(mm-common)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(libswscale)
 BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(iniparser)
 BuildRequires: pkgconfig(libavcodec)
 BuildRequires: pkgconfig(libavutil)
 BuildRequires: pkgconfig(libavformat)
@@ -57,6 +58,9 @@ CFLAGS="${CFLAGS} -D_MM_PROJECT_FLOATER -DEXPORT_API=\"__attribute__((visibility
 %install
 %make_install
 
+mkdir -p %{buildroot}%{_sysconfdir}/multimedia
+cp -rf %{_builddir}/%{name}-%{version}/mm_file_config.ini %{buildroot}%{_sysconfdir}/multimedia/mm_file_config.ini
+
 %post -p /sbin/ldconfig
 
 %postun -p /sbin/ldconfig
@@ -71,6 +75,7 @@ CFLAGS="${CFLAGS} -D_MM_PROJECT_FLOATER -DEXPORT_API=\"__attribute__((visibility
 %{_libdir}/libmmfile_codecs.so
 %{_libdir}/libmmfile_formats.so
 %{_libdir}/libmmfile_utils.so
+%{_sysconfdir}/multimedia/mm_file_config.ini
 %license LICENSE.APLv2.0
 
 %files tool
index 9b71a5a..652d46c 100755 (executable)
@@ -21,14 +21,16 @@ libmmfile_utils_la_CFLAGS = -I$(srcdir)/include \
                       -D_LARGEFILE64_SOURCE \
                       -D_FILE_OFFSET_BITS=64 \
                       $(ICU_CFLAGS) \
-                      $(VCONF_CFLAGS)
+                      $(VCONF_CFLAGS) \
+                       $(INIPARSER_CFLAGS)
 if USE_TESTMODE
 libmmfile_utils_la_CFLAGS += -D__MMFILE_TEST_MODE__
 endif
 
 libmmfile_utils_la_LIBADD = $(MMCOMMON_LIBS) \
                            $(ICU_LIBS) \
-                           $(VCONF_LIBS)
+                           $(VCONF_LIBS) \
+                            $(INIPARSER_LIBS)
 
 libmmfile_utils_la_CFLAGS += $(DLOG_CFLAGS)
 libmmfile_utils_la_LIBADD += $(DLOG_LIBS)
index 2fb1e19..41da0e2 100755 (executable)
@@ -53,6 +53,8 @@ extern "C" {
 #define FALSE  (!TRUE)
 #endif
 
+#define MM_FILE_INI_PATH       "/etc/multimedia/mm_file_config.ini"
+
 
 /*////////////////////////////////////////////////////////////////////// */
 /*                     ENDIAN UTIL API                                // */
index 8c5efd6..86a8d18 100755 (executable)
@@ -25,6 +25,7 @@
 #include <ctype.h>
 #include <vconf.h>
 #include <glib.h>
+#include <iniparser.h>
 
 #include "mm_file.h"
 #include "mm_file_debug.h"
@@ -170,6 +171,8 @@ static const char *MpegAudio_Genre[GENRE_COUNT] = {"Blues", "Classic Rock", "Cou
 static unsigned char gTagJPEGHeader[] = {0xff, 0xd8, 0xff };
 static unsigned char gTagPNGHeader[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
 
+static int GetJunkCounterLimit(void);
+
 static int GetStringFromTextTagBox(MMFileFormatContext *formatContext, MMFileIOHandle *fp, MMFILE_MP4_BASIC_BOX_HEADER *basic_header, eMMFILE_3GP_TEXT_TAG eTag)
 {
        int ret = MMFILE_UTIL_FAIL;    /*fail*/
@@ -1238,6 +1241,25 @@ exception:
        return MMFILE_UTIL_FAIL;
 }
 
+static int g_junk_counter_limit = 0;
+static int GetJunkCounterLimit(void)
+{
+       dictionary *dict = NULL;
+       int data = 0;
+
+       dict = iniparser_load(MM_FILE_INI_PATH);
+       if (!dict) {
+               debug_error(DEBUG, "%s load failed", MM_FILE_INI_PATH);
+               return -1;
+       }
+
+       data = iniparser_getint(dict, "mm-file-config:junk_counter_limit", 0);
+       debug_msg(DEBUG, "mm-file-config:junk_counter_limit= %u", data);
+
+       iniparser_freedict(dict);
+
+       return data;
+}
 
 #define BIG_CONTENT_BOX_SIZE_LEN 8
 EXPORT_API int MMFileUtilGetMetaDataFromMP4(MMFileFormatContext *formatContext)
@@ -1246,6 +1268,7 @@ EXPORT_API int MMFileUtilGetMetaDataFromMP4(MMFileFormatContext *formatContext)
        int ret = 0;
        int readed;
        unsigned long long chunk_size = 0;
+       long long moov_end = 0;
 
        ret = mmfile_open(&fp, formatContext->uriFileName, MMFILE_RDONLY);
        if (ret == MMFILE_UTIL_FAIL) {
@@ -1256,7 +1279,11 @@ EXPORT_API int MMFileUtilGetMetaDataFromMP4(MMFileFormatContext *formatContext)
        MMFILE_MP4_BASIC_BOX_HEADER basic_header = {0, };
        basic_header.start_offset = mmfile_tell(fp);
 
-       while ((ret != MMFILE_UTIL_FAIL) && ((readed = mmfile_read(fp, (unsigned char *)&basic_header, MMFILE_MP4_BASIC_BOX_HEADER_LEN)) > 0)) {
+       int junk_counter = 0;
+       if (g_junk_counter_limit == 0)
+               g_junk_counter_limit = GetJunkCounterLimit();
+
+       while ((ret != MMFILE_UTIL_FAIL) && ((readed = mmfile_read(fp, (unsigned char *)&basic_header, MMFILE_MP4_BASIC_BOX_HEADER_LEN)) == MMFILE_MP4_BASIC_BOX_HEADER_LEN)) {
                basic_header.size = mmfile_io_be_uint32(basic_header.size);
                basic_header.type = mmfile_io_le_uint32(basic_header.type);
 
@@ -1265,6 +1292,20 @@ EXPORT_API int MMFileUtilGetMetaDataFromMP4(MMFileFormatContext *formatContext)
                        basic_header.size = readed;
                        basic_header.type = 0;
                        chunk_size = basic_header.size;
+
+                       if ((moov_end != 0) && (moov_end < basic_header.start_offset))
+                       {
+                               debug_msg(DEBUG, "found junk data but moov data already was extracted, so junk counter will be increase: %d", junk_counter);
+                               junk_counter++;
+
+                               /* stop the loop for junk case. */
+                               if ((g_junk_counter_limit > 0) && (junk_counter > g_junk_counter_limit))
+                               {
+                                       debug_msg(DEBUG, "stop the loop by junk-data checker");
+                                       ret = MMFILE_UTIL_FAIL;
+                                       continue;
+                               }
+                       }
                } else if (basic_header.size == 1) {
                        int i = 0;
                        unsigned char temp[BIG_CONTENT_BOX_SIZE_LEN] = {0, };
@@ -1275,13 +1316,16 @@ EXPORT_API int MMFileUtilGetMetaDataFromMP4(MMFileFormatContext *formatContext)
                        for(i = 0; i < BIG_CONTENT_BOX_SIZE_LEN; i++)
                                size |= (unsigned long long)temp[i] << (BIG_CONTENT_BOX_SIZE_LEN - 1 - i) * BIG_CONTENT_BOX_SIZE_LEN;
                        chunk_size = size;
+                       junk_counter = 0;
                } else {
                        chunk_size = basic_header.size;
+                       junk_counter = 0;
                }
 
                switch (basic_header.type) {
                        case FOURCC('m', 'o', 'o', 'v'): {
                                        debug_msg(RELEASE, "MPEG4: [moov] SIZE: [%lld]Byte\n", chunk_size);
+                                       moov_end = basic_header.start_offset + chunk_size;
                                        break;
                                }
                        case FOURCC('u', 'd', 't', 'a'): {