id3v2.2 parser refactoring 88/279388/3 accepted/tizen/unified/20220810.135844 submit/tizen/20220809.032739
authorminje.ahn <minje.ahn@samsung.com>
Mon, 8 Aug 2022 09:31:19 +0000 (18:31 +0900)
committerMinje ahn <minje.ahn@samsung.com>
Mon, 8 Aug 2022 23:13:26 +0000 (23:13 +0000)
Change-Id: I5164f6c654757bbc71c44d0f94212ac5948b3135
Signed-off-by: minje.ahn <minje.ahn@samsung.com>
packaging/libmm-fileinfo.spec
utils/include/mm_file_utils.h
utils/mm_file_util_tag.c

index e8c406b..6ce2c5a 100644 (file)
@@ -1,6 +1,6 @@
 Name:      libmm-fileinfo
 Summary:    Media Fileinfo
-Version:    1.0.12
+Version:    1.0.13
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
index c4c1e3c..904ec2e 100755 (executable)
@@ -313,8 +313,8 @@ typedef enum {
 } AvID3TagList;
 
 typedef struct {
-       int             tagLen;
-       char    tagVersion;
+       int tagLen;
+       char tagVersion;
 } AvTagVer2AdditionalData;
 
 typedef struct {
index 29bad9a..e6bb27b 100644 (file)
@@ -2830,7 +2830,7 @@ bool mm_file_id3tag_parse_v110(AvFileContentInfo *pInfo, unsigned char *buffer)
        return true;
 }
 
-static AvID3TagList __get_tag_info_v222(const char *tag)
+static AvID3TagList __get_tag_info_v222(const unsigned char *tag)
 {
        unsigned int n = 0;
        int i = 0;
@@ -2877,125 +2877,105 @@ static AvID3TagList __get_tag_info_v223(const char *tag)
 
 bool mm_file_id3tag_parse_v222(AvFileContentInfo *pInfo, unsigned char *buffer, bool extract_artwork)
 {
-       unsigned long taglen = 0;
-       unsigned long needToloopv2taglen;
-       unsigned long oneFrameLen = 0;
-       unsigned long curPos = 0;
-       char CompTmp[4];
-       unsigned char *pExtContent = NULL;
-       unsigned long purelyFramelen = 0;
-       unsigned int encodingOffSet = 0;
-       int realCpyFrameNum = 0;
-       int textEncodingType = 0;
+       int curPos = MP3_TAGv2_HEADER_LEN;
+       int frameLen = 0;
+       int encOffset = 0;
+       int encType = 0;
        char **charset_array = NULL;
        AvID3TagList tag_id = AV_ID3TAG_MAX;
 
-       make_characterset_array(&charset_array);
+       if (pInfo->tagV2Info.tagLen <= 0)
+               return false;
 
+       make_characterset_array(&charset_array);
        init_content_info(pInfo);
 
-       taglen = pInfo->tagV2Info.tagLen;
-       needToloopv2taglen = taglen - MP3_TAGv2_HEADER_LEN;
-       curPos = MP3_TAGv2_HEADER_LEN;
-
        debug_msg(RELEASE, "ID3tag v222--------------------------------------------------------------");
 
-       while (needToloopv2taglen > MP3_TAGv2_22_TXT_HEADER_LEN) {
-               if (!g_ascii_isalnum(buffer[curPos]) ||
-                       !g_ascii_isalnum(buffer[curPos + 1]) ||
-                       !g_ascii_isalnum(buffer[curPos + 2]))
+       while (curPos + MP3_TAGv2_22_TXT_HEADER_LEN < pInfo->tagV2Info.tagLen) {
+               if (!g_ascii_isalnum(buffer[curPos]) || !g_ascii_isalnum(buffer[curPos + 1]) || !g_ascii_isalnum(buffer[curPos + 2]))
                        break;
 
-               memcpy(CompTmp, &buffer[curPos], 3);
-
-               CompTmp[3] = 0;
-               oneFrameLen = MP3_TAGv2_22_TXT_HEADER_LEN;
-               oneFrameLen += (unsigned long)buffer[3 + curPos] << 16 | (unsigned long)buffer[4 + curPos] << 8
-                                       | (unsigned long)buffer[5 + curPos];
-
-               if (oneFrameLen > taglen - curPos)
+               tag_id = __get_tag_info_v222(&buffer[curPos]);
+               frameLen = buffer[3 + curPos] << 16 | buffer[4 + curPos] << 8 | buffer[5 + curPos];
+               curPos += MP3_TAGv2_22_TXT_HEADER_LEN;
+               if (curPos + frameLen > pInfo->tagV2Info.tagLen)
                        break;
 
-               purelyFramelen = oneFrameLen - MP3_TAGv2_22_TXT_HEADER_LEN;
-               curPos += oneFrameLen;
-
-               tag_id = __get_tag_info_v222(CompTmp);
-               if (tag_id != AV_ID3TAG_MAX && !pInfo->tagInfo[tag_id].value && purelyFramelen > 0) {
-                       if (buffer[curPos - purelyFramelen] == 0x00) {
-                               encodingOffSet = 1;
-                               textEncodingType = AV_ID3V2_ISO_8859;
-                       } else if (buffer[curPos - purelyFramelen] == 0x01) {
-                               encodingOffSet = 1;
-                               textEncodingType = AV_ID3V2_UTF16;
-                       }
-
-                       /*in order to deliver valid string to MP */
-                       while ((buffer[curPos - purelyFramelen + encodingOffSet] < 0x20) && (encodingOffSet < purelyFramelen))
-                               encodingOffSet++;
-
-                       if (purelyFramelen <= encodingOffSet) {
-                               debug_warning(DEBUG, "warning: invalid frame length %lu %u", purelyFramelen, encodingOffSet);
-                               continue;
-                       }
-
-                       realCpyFrameNum = purelyFramelen - encodingOffSet;
-                       mmfile_free(pExtContent);
-                       pExtContent = g_malloc0(realCpyFrameNum + 3);
-
-                       memcpy(pExtContent, &buffer[curPos - purelyFramelen + encodingOffSet], purelyFramelen - encodingOffSet);
+               if (frameLen <= 0)
+                       continue;
 
-                       switch (tag_id) {
-                       case AV_ID3TAG_COMMENT:
-                               if (realCpyFrameNum <= 4) {
-                                       debug_msg(RELEASE, "Too small to parse realCpyFrameNum(%d)", realCpyFrameNum);
-                                       break;
-                               }
+               if (tag_id == AV_ID3TAG_MAX || pInfo->tagInfo[tag_id].value)
+                       goto NEXT;
 
-                               /*skip language data! */
-                               realCpyFrameNum -= 4;
+               if (buffer[curPos] == 0x00) {
+                       encOffset = 1;
+                       encType = AV_ID3V2_ISO_8859;
+               } else if (buffer[curPos] == 0x01) {
+                       encOffset = 1;
+                       encType = AV_ID3V2_UTF16;
+               }
 
-                               if (pExtContent[4] > 0x20 && (pExtContent[3] == 0x00 || pExtContent[3] == 0x01)) {
-                                       textEncodingType = __id3tag_get_text_encoding_v222(pExtContent, 4);
-                                       pInfo->tagInfo[tag_id].value = mmfile_convert_to_utf8((const char *)pExtContent, realCpyFrameNum, charset_array[textEncodingType]);
-                               } else {
-                                       debug_msg(RELEASE, "Failed to get tag: purelyFramelen - encodingOffSet(%lu)", purelyFramelen - encodingOffSet);
-                               }
+               /*in order to deliver valid string to MP */
+               while ((buffer[curPos + encOffset] < 0x20) && (encOffset < frameLen))
+                       encOffset++;
 
-                               break;
+               if (frameLen == encOffset) {
+                       debug_warning(DEBUG, "warning: invalid frame length %d %d", frameLen, encOffset);
+                       goto NEXT;
+               }
 
-                       case AV_ID3TAG_PICTURE:
-                               if (extract_artwork)
-                                       _mm_file_id3tag_parse_PIC(pInfo, pExtContent, realCpyFrameNum, (const char*)charset_array[textEncodingType]);
-                               break;
+               curPos += encOffset;
+               frameLen -= encOffset;
 
-                       default:
-                               pInfo->tagInfo[tag_id].value = mmfile_convert_to_utf8((const char *)pExtContent, realCpyFrameNum, charset_array[textEncodingType]);
+               switch (tag_id) {
+               case AV_ID3TAG_COMMENT:
+                       /*
+                       https://id3.org/id3v2-00
+                       Comment                   "COM"
+                       Frame size                $xx xx xx
+                       Text encoding             $xx
+                       Language                  $xx xx xx
+                       Short content description <textstring> $00 (00)
+                       The actual text           <textstring>
+                       */
+                       if (frameLen <= 4) {
+                               debug_msg(RELEASE, "Too small to parse frameLen(%d)", frameLen);
                                break;
                        }
 
-                       if (pInfo->tagInfo[tag_id].value)
-                               debug_msg(RELEASE, "[%d] returned = (%s)", tag_id, pInfo->tagInfo[tag_id].value);
-               }
-
-               mmfile_free(pExtContent);
-               memset(CompTmp, 0, 4);
+                       if (buffer[curPos + 4] > 0x20 && (buffer[curPos + 3] == 0x00 || buffer[curPos + 3] == 0x01)) {
+                               encType = __id3tag_get_text_encoding_v222(&buffer[curPos], 4);
+                               curPos += 4;
+                               frameLen -= 4;
+                               pInfo->tagInfo[tag_id].value = mmfile_convert_to_utf8((const char *)&buffer[curPos], frameLen, charset_array[encType]);
+                       } else {
+                               debug_msg(RELEASE, "Failed to get tag: frameLen(%d)", frameLen);
+                       }
 
-               if (curPos >= taglen)
                        break;
 
-               needToloopv2taglen -= oneFrameLen;
+               case AV_ID3TAG_PICTURE:
+                       if (extract_artwork)
+                               _mm_file_id3tag_parse_PIC(pInfo, &buffer[curPos], frameLen, charset_array[encType]);
+                       break;
 
-               oneFrameLen = 0;
-               encodingOffSet = 0;
-               realCpyFrameNum = 0;
-               textEncodingType = 0;
-               purelyFramelen = 0;
+               default:
+                       pInfo->tagInfo[tag_id].value = mmfile_convert_to_utf8((const char *)&buffer[curPos], frameLen, charset_array[encType]);
+                       break;
+               }
 
+               if (pInfo->tagInfo[tag_id].value)
+                       debug_msg(RELEASE, "[%d] returned = (%s)", tag_id, pInfo->tagInfo[tag_id].value);
+NEXT:
+               curPos += frameLen;
+               encOffset = 0;
+               encType = 0;
        }
 
        release_characterset_array(charset_array);
 
-       return (taglen > 0);
+       return true;
 }
 
 static void __get_v223_encoding_info(const unsigned char *buffer,