[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