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;
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,