[vlc-commits] [Git][videolan/vlc][master] 3 commits: meta_engine: ID3: use enum for text encodings

Steve Lhomme (@robUx4) gitlab at videolan.org
Sat Oct 10 18:10:51 UTC 2026



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
5c14408c by Wassim Lalaoui at 2026-10-10T17:53:50+00:00
meta_engine: ID3: use enum for text encodings

- - - - -
53854dff by Wassim Lalaoui at 2026-10-10T17:53:50+00:00
meta_engine: ID3: fix the TXXX value offset with UTF-16 keys

Fix the offset of TXXX values, it was computed from the length of the key converted to UTF-8 instead of its length in the tag, so with UTF-16 keys the value was read from the middle of the key

- - - - -
650027d8 by Wassim Lalaoui at 2026-10-10T17:53:50+00:00
meta_engine: ID3: honour the BOM of UTF-16 text

Fix UTF-16 ID3 text ignoring its BOM: encoding 0x01 was always decoded as UTF-16LE while 0x01 should also support big-endian.

- - - - -


3 changed files:

- modules/demux/mpeg/es.c
- modules/meta_engine/ID3Meta.h
- modules/meta_engine/ID3Text.h


Changes:

=====================================
modules/demux/mpeg/es.c
=====================================
@@ -1515,7 +1515,8 @@ static int ID3TAG_Parse_Handler( uint32_t i_tag, const uint8_t *p_payload, size_
         const uint8_t *p = p_payload + 6;
         size_t i_remaining = i_payload - 6;
 
-        bool b_utf16 = (i_encoding == 0x01 || i_encoding == 0x02);
+        bool b_utf16 = (i_encoding == ID3_ENCODING_UTF16 ||
+                        i_encoding == ID3_ENCODING_UTF16BE);
 
         /* Skip content descriptor (null-terminated string) */
         if( b_utf16 ) /* UTF-16 */
@@ -1612,7 +1613,8 @@ static int ID3TAG_Parse_Handler( uint32_t i_tag, const uint8_t *p_payload, size_
         const uint8_t *p = p_payload + 4;
         size_t i_remaining = i_payload - 4;
 
-        bool b_utf16 = (i_encoding == 0x01 || i_encoding == 0x02);
+        bool b_utf16 = (i_encoding == ID3_ENCODING_UTF16 ||
+                        i_encoding == ID3_ENCODING_UTF16BE);
 
         if( b_utf16 )
         {


=====================================
modules/meta_engine/ID3Meta.h
=====================================
@@ -111,7 +111,11 @@ static bool ID3HandleTag( const uint8_t *p_buf, size_t i_buf,
         const char *psz_key = ID3TextConvert( p_buf, i_buf, &psz_key_alloc );
         if( psz_key )
         {
-            const size_t i_len = strlen( psz_key ) + 2;
+            /* The value follows the encoding byte and the key, whose size
+             * depends on the encoding, not on its UTF-8 conversion */
+            const ssize_t i_keylen = ID3TextLength( &p_buf[1], i_buf - 1, p_buf[0] );
+            const size_t i_len = i_keylen < 0 ? i_buf
+                               : 1 + (size_t) i_keylen + ID3TextTerminatorSize( p_buf[0] );
             if( i_len < i_buf )
             {
                 /* Only set those which are known as non binary */


=====================================
modules/meta_engine/ID3Text.h
=====================================
@@ -22,26 +22,35 @@
 
 #include <vlc_charset.h>
 
+/* Text encoding byte of the ID3v2 frames */
+enum
+{
+    ID3_ENCODING_ISO_8859_1 = 0x00, // ISO-8859-1
+    ID3_ENCODING_UTF16      = 0x01, // UTF-16 with BOM
+    ID3_ENCODING_UTF16BE    = 0x02, // UTF-16BE without BOM, ID3v2.4
+    ID3_ENCODING_UTF8       = 0x03, // UTF-8, ID3v2.4
+};
+
 static const char * ID3TextConv( const uint8_t *p_buf, size_t i_buf,
                                  uint8_t i_charset, char **ppsz_allocated )
 {
     char *p_alloc = NULL;
     const char *psz = p_alloc;
-    if( i_buf > 0 && i_charset < 0x04 )
+    if( i_buf > 0 && i_charset <= ID3_ENCODING_UTF8 )
     {
         switch( i_charset )
         {
-            case 0x00:
+            case ID3_ENCODING_ISO_8859_1:
                 psz = p_alloc = FromCharset( "ISO_8859-1", p_buf, i_buf );
                 break;
-            case 0x01:
-                psz = p_alloc = FromCharset( "UTF-16LE", p_buf, i_buf );
+            case ID3_ENCODING_UTF16:
+                psz = p_alloc = FromCharset( "UTF-16", p_buf, i_buf );
                 break;
-            case 0x02:
+            case ID3_ENCODING_UTF16BE:
                 psz = p_alloc = FromCharset( "UTF-16BE", p_buf, i_buf );
                 break;
             default:
-            case 0x03:
+            case ID3_ENCODING_UTF8:
                 if( p_buf[ i_buf - 1 ] != 0x00 )
                 {
                     psz = p_alloc = (char *) malloc( i_buf + 1 );
@@ -73,4 +82,29 @@ static inline const char * ID3TextConvert( const uint8_t *p_buf, size_t i_buf,
     return ID3TextConv( &p_buf[1], i_buf - 1, p_buf[0], ppsz_allocated );
 }
 
+/* Size in bytes of the terminator of a string: UTF-16 strings end with a
+ * null code unit */
+static inline size_t ID3TextTerminatorSize( uint8_t i_charset )
+{
+    return ( i_charset == ID3_ENCODING_UTF16 ||
+             i_charset == ID3_ENCODING_UTF16BE ) ? 2 : 1;
+}
+
+/* Length in bytes of the first string of the buffer, terminator excluded,
+ * or -1 if it is not terminated */
+static inline ssize_t ID3TextLength( const uint8_t *p_buf, size_t i_buf,
+                                     uint8_t i_charset )
+{
+    if( ID3TextTerminatorSize( i_charset ) == 2 )
+    {
+        for( size_t i = 0; i + 1 < i_buf; i += 2 )
+            if( GetWBE( &p_buf[i] ) == 0 )
+                return i;
+        return -1;
+    }
+
+    const size_t i_len = strnlen( (const char *) p_buf, i_buf );
+    return i_len < i_buf ? (ssize_t) i_len : -1;
+}
+
 #endif



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/00b15a008ae519b8fc97bd73e242819128013e1c...650027d820d417bb90e6cfeb5492483c3804d97f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/00b15a008ae519b8fc97bd73e242819128013e1c...650027d820d417bb90e6cfeb5492483c3804d97f
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list