Coverage Report

Created: 2026-03-14 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mpg123/src/libmpg123/id3.c
Line
Count
Source
1
/*
2
  id3: ID3v2.3 and ID3v2.4 parsing (a relevant subset)
3
4
  copyright 2006-2023 by the mpg123 project - free software under the terms of the LGPL 2.1
5
  see COPYING and AUTHORS files in distribution or http://mpg123.org
6
  initially written by Thomas Orgis
7
8
  WIP: Handling of multiple ID3 tags in a stream.
9
10
  1. With update flag: Add non-unique data, replace unique.
11
  - Only one TALB, TPE1, etc.
12
  - Only one TXXX with a certain description.
13
  - Only one COMM with certain language and description.
14
  - Only one APIC with certain type and description, generally only one
15
    of type 1 and 2 each.
16
  2. Without update flag: wipe whole data and only store new stuff.
17
18
  BIG BAD BUT: How to properly handle seeks in a stream that make
19
  the parser encounter the same tags again in random order? Is
20
  there even a correct way to handle that without storing an
21
  ordered list of all tags? I could simplify the code here and just
22
  communicate that a frame should be an update to previous, and
23
  at which stream position the frame was encountered. But since
24
  libmpg123 is driven by MPEG frames, there could be multiple
25
  ID3v2 tags in direct succession treated by the parser without
26
  the library user being able to interfere.
27
28
  This is severely fucked. All that complexity also doesn't matter
29
  in practice, as streams use ICY and individual files have just one
30
  ID3v2 tag (relevant for libmpg123).  It's an academic problem. But
31
  for seekable files, I could implement some jumping logic to find
32
  and parse all ID3v2 for once and then set a flag that only jumps
33
  the frames on seeks. That covers all local disk playback. For
34
  streams, seeking is no issue (seeking back, at least), so the
35
  update/replace logic works.
36
37
  Look at the standard:
38
39
------
40
5.   Tag location
41
42
   The default location of an ID3v2 tag is prepended to the audio so
43
   that players can benefit from the information when the data is
44
   streamed. It is however possible to append the tag, or make a
45
   prepend/append combination. When deciding upon where an unembedded
46
   tag should be located, the following order of preference SHOULD be
47
   considered.
48
   
49
     1. Prepend the tag.
50
51
     2. Prepend a tag with all vital information and add a second tag at 
52
        the end of the file, before tags from other tagging systems. The
53
        first tag is required to have a SEEK frame.
54
      
55
     3. Add a tag at the end of the file, before tags from other tagging
56
        systems.
57
      
58
   In case 2 and 3 the tag can simply be appended if no other known tags
59
   are present. The suggested method to find ID3v2 tags are:
60
   
61
     1. Look for a prepended tag using the pattern found in section 3.1.
62
63
     2. If a SEEK frame was found, use its values to guide further
64
        searching.
65
66
     3. Look for a tag footer, scanning from the back of the file.
67
68
   For every new tag that is found, the old tag should be discarded
69
   unless the update flag in the extended header (section 3.2) is set.
70
------
71
72
  For seekable streams, I simply need to implement explicit ID3v2 search along
73
  that recommendation and keep the complete information. Streams that continue
74
  growing during playback will not recognize added ID3v2 tags. So be it.
75
  For non-seekable streams, a tag is always parsed when encountered, assuming
76
  the order of update tags always matches.
77
78
  First step for the 1.26 release shall be the implementaton of the update
79
  logic and glossing over the theoretical problem of re-parsing update
80
  frames in the wrong order by ignoring it. They are not that relevant.
81
82
  TODO: Cave in and add the missing frames from the spec. Not that far to go.
83
  But need another data structure to communicate those ...
84
*/
85
86
#include "mpg123lib_intern.h"
87
#include "id3.h"
88
#include "../common/debug.h"
89
90
#ifndef NO_ID3V2 /* Only the main parsing routine will always be there. */
91
92
/* We know the usual text frames plus some specifics. */
93
59.3k
#define KNOWN_FRAMES 5
94
static const char frame_type[KNOWN_FRAMES][5] = { "COMM", "TXXX", "RVA2", "USLT", "APIC" };
95
enum frame_types { unknown = -2, text = -1, comment, extra, rva2, uslt, picture };
96
97
/* UTF support definitions */
98
99
typedef void (*text_converter)(mpg123_string *sb, const unsigned char* source, size_t len, const int noquiet);
100
101
static void convert_latin1  (mpg123_string *sb, const unsigned char* source, size_t len, const int noquiet);
102
static void convert_utf16bom(mpg123_string *sb, const unsigned char* source, size_t len, const int noquiet);
103
static void convert_utf8    (mpg123_string *sb, const unsigned char* source, size_t len, const int noquiet);
104
105
static const text_converter text_converters[4] =
106
{
107
  convert_latin1,
108
  /* We always check for (multiple) BOM in 16bit unicode. Without BOM, UTF16 BE is the default.
109
     Errors in encoding are detected anyway. */
110
  convert_utf16bom,
111
  convert_utf16bom,
112
  convert_utf8
113
};
114
115
static const unsigned int encoding_widths[4] = { 1, 2, 2, 1 };
116
117
/* the code starts here... */
118
119
static void null_id3_links(mpg123_handle *fr)
120
58.8k
{
121
58.8k
  fr->id3v2.title  = NULL;
122
58.8k
  fr->id3v2.artist = NULL;
123
58.8k
  fr->id3v2.album  = NULL;
124
58.8k
  fr->id3v2.year   = NULL;
125
58.8k
  fr->id3v2.genre  = NULL;
126
58.8k
  fr->id3v2.comment = NULL;
127
58.8k
}
128
129
void INT123_init_id3(mpg123_handle *fr)
130
58.8k
{
131
58.8k
  fr->id3v2.version = 0; /* nothing there */
132
58.8k
  null_id3_links(fr);
133
58.8k
  fr->id3v2.comments     = 0;
134
58.8k
  fr->id3v2.comment_list = NULL;
135
58.8k
  fr->id3v2.texts    = 0;
136
58.8k
  fr->id3v2.text     = NULL;
137
58.8k
  fr->id3v2.extras   = 0;
138
58.8k
  fr->id3v2.extra    = NULL;
139
58.8k
  fr->id3v2.pictures   = 0;
140
58.8k
  fr->id3v2.picture    = NULL;
141
58.8k
}
142
143
/* Managing of the text, comment and extra lists. */
144
145
/* Initialize one element. */
146
static void init_mpg123_text(mpg123_text *txt)
147
29.2k
{
148
29.2k
  mpg123_init_string(&txt->text);
149
29.2k
  mpg123_init_string(&txt->description);
150
29.2k
  txt->id[0] = 0;
151
29.2k
  txt->id[1] = 0;
152
29.2k
  txt->id[2] = 0;
153
29.2k
  txt->id[3] = 0;
154
29.2k
  txt->lang[0] = 0;
155
29.2k
  txt->lang[1] = 0;
156
29.2k
  txt->lang[2] = 0;
157
29.2k
}
158
159
static void init_mpg123_picture(mpg123_picture *pic)
160
0
{
161
0
  mpg123_init_string(&pic->mime_type);
162
0
  mpg123_init_string(&pic->description);
163
0
  pic->type = 0;
164
0
  pic->size = 0;
165
0
  pic->data = NULL;
166
0
}
167
168
/* Free memory of one element. */
169
static void free_mpg123_text(mpg123_text *txt)
170
27.7k
{
171
27.7k
  mpg123_free_string(&txt->text);
172
27.7k
  mpg123_free_string(&txt->description);
173
27.7k
}
174
175
static void free_mpg123_picture(mpg123_picture * pic)
176
0
{
177
0
  mpg123_free_string(&pic->mime_type);
178
0
  mpg123_free_string(&pic->description);
179
0
  if (pic->data != NULL)
180
0
    free(pic->data);
181
0
}
182
183
/* Free memory of whole list. */
184
58.8k
#define free_comment(mh) free_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments))
185
58.8k
#define free_text(mh)    free_id3_text(&((mh)->id3v2.text),         &((mh)->id3v2.texts))
186
58.8k
#define free_extra(mh)   free_id3_text(&((mh)->id3v2.extra),        &((mh)->id3v2.extras))
187
58.8k
#define free_picture(mh) free_id3_picture(&((mh)->id3v2.picture),   &((mh)->id3v2.pictures))
188
static void free_id3_text(mpg123_text **list, size_t *size)
189
176k
{
190
176k
  size_t i;
191
191k
  for(i=0; i<*size; ++i) free_mpg123_text(&((*list)[i]));
192
193
176k
  free(*list);
194
176k
  *list = NULL;
195
176k
  *size = 0;
196
176k
}
197
static void free_id3_picture(mpg123_picture **list, size_t *size)
198
58.8k
{
199
58.8k
  size_t i;
200
58.8k
  for(i=0; i<*size; ++i) free_mpg123_picture(&((*list)[i]));
201
202
58.8k
  free(*list);
203
58.8k
  *list = NULL;
204
58.8k
  *size = 0;
205
58.8k
}
206
207
/* Add items to the list. */
208
209
8.68k
#define add_comment(mh, l, d) add_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments), NULL,    l, d)
210
2.26k
#define add_text(mh, id)      add_id3_text(&((mh)->id3v2.text),         &((mh)->id3v2.texts),      id, NULL, NULL)
211
502
#define add_uslt(mh, l, d)    add_id3_text(&((mh)->id3v2.text),         &((mh)->id3v2.texts),      id, l, d)
212
8.69k
#define add_extra(mh, d)      add_id3_text(&((mh)->id3v2.extra),        &((mh)->id3v2.extras),   NULL, NULL, d)
213
0
#define add_picture(mh, t, d) add_id3_picture(&((mh)->id3v2.picture), &((mh)->id3v2.pictures), t, d)
214
static mpg123_text *add_id3_text( mpg123_text **list, size_t *size
215
, char id[4], char lang[3], mpg123_string *description )
216
15.5k
{
217
15.5k
  mdebug( "add_id3_text id=%s lang=%s, desc=%s"
218
15.5k
  , id ? (char[5]) { id[0], id[1], id[2], id[3], 0 } : "(nil)"
219
15.5k
  , lang ? (char[4]) { lang[0], lang[1], lang[2], 0 }  : "(nil)"
220
15.5k
  , description ? (description->fill ? description->p : "(empty)") : "(nil)" );
221
15.5k
  if(lang && !description)
222
0
    return NULL; // no lone language intended
223
15.5k
  if(id || description)
224
15.5k
  {
225
    // Look through list of existing texts and return an existing entry
226
    // if it should be overwritten.
227
19.8k
    for(size_t i=0; i<*size; ++i)
228
5.43k
    {
229
5.43k
      mpg123_text *entry = *list+i;
230
5.43k
      if(description)
231
3.92k
      { // Overwrite entry with same description and same ID and language.
232
3.92k
        if( (!id || !memcmp(id, entry->id, 4))
233
3.73k
          && (!lang || !memcmp(entry->lang, lang, 3))
234
2.88k
          && mpg123_same_string(&(entry->description), description)
235
3.92k
        )
236
847
        return entry;
237
3.92k
      } else if(id && !memcmp(id, entry->id, 4))
238
280
        return entry; // Just ovewrite because of same ID.
239
4.30k
      mdebug("add_id3_text: entry %zu was no match", i);
240
4.30k
    }
241
15.5k
  }
242
14.4k
  mdebug("add_id3_text: append to list of %zu", *size);
243
  // Nothing found, add new one.
244
14.4k
  mpg123_text *x = INT123_safe_realloc(*list, sizeof(mpg123_text)*(*size+1));
245
14.4k
  if(x == NULL) return NULL; /* bad */
246
247
14.4k
  *list  = x;
248
14.4k
  *size += 1;
249
14.4k
  init_mpg123_text(&((*list)[*size-1]));
250
251
14.4k
  return &((*list)[*size-1]); /* Return pointer to the added text. */
252
14.4k
}
253
254
255
static mpg123_picture *add_id3_picture(mpg123_picture **list, size_t *size, char type, mpg123_string *description)
256
0
{
257
0
  if(!description)
258
0
    return NULL;
259
260
  // Return entry to overwrite, if appropriate.
261
0
  for(size_t i=0; i<*size; ++i)
262
0
  {
263
0
    mpg123_picture *entry = *list+i;
264
0
    if(  type == entry->type
265
0
      && ( type == 1 || type == 2 ||
266
0
        mpg123_same_string(&entry->description, description)
267
0
      )
268
0
    )
269
0
      return entry;
270
0
  }
271
  // Append a new one.
272
0
  mpg123_picture *x = INT123_safe_realloc(*list, sizeof(mpg123_picture)*(*size+1));
273
0
  if(x == NULL) return NULL; /* bad */
274
275
0
  *list  = x;
276
0
  *size += 1;
277
0
  init_mpg123_picture(&((*list)[*size-1]));
278
279
0
  return &((*list)[*size-1]); /* Return pointer to the added picture. */
280
0
}
281
282
/* OK, back to the higher level functions. */
283
284
void INT123_exit_id3(mpg123_handle *fr)
285
58.8k
{
286
58.8k
  free_picture(fr);
287
58.8k
  free_comment(fr);
288
58.8k
  free_extra(fr);
289
58.8k
  free_text(fr);
290
58.8k
}
291
292
void INT123_reset_id3(mpg123_handle *fr)
293
52.2k
{
294
52.2k
  INT123_exit_id3(fr);
295
52.2k
  INT123_init_id3(fr);
296
52.2k
}
297
298
/* Set the id3v2.artist id3v2.title ... links to elements of the array. */
299
void INT123_id3_link(mpg123_handle *fr)
300
0
{
301
0
  size_t i;
302
0
  mpg123_id3v2 *v2 = &fr->id3v2;
303
0
  debug("linking ID3v2");
304
0
  null_id3_links(fr);
305
0
  for(i=0; i<v2->texts; ++i)
306
0
  {
307
0
    mpg123_text *entry = &v2->text[i];
308
0
    if     (!strncmp("TIT2", entry->id, 4)) v2->title  = &entry->text;
309
0
    else if(!strncmp("TALB", entry->id, 4)) v2->album  = &entry->text;
310
0
    else if(!strncmp("TPE1", entry->id, 4)) v2->artist = &entry->text;
311
0
    else if(!strncmp("TYER", entry->id, 4)) v2->year   = &entry->text;
312
0
    else if(!strncmp("TCON", entry->id, 4)) v2->genre  = &entry->text;
313
0
  }
314
0
  for(i=0; i<v2->comments; ++i)
315
0
  {
316
0
    mpg123_text *entry = &v2->comment_list[i];
317
0
    if(entry->description.fill == 0 || entry->description.p[0] == 0)
318
0
    v2->comment = &entry->text;
319
0
  }
320
  /* When no generic comment found, use the last non-generic one. */
321
0
  if(v2->comment == NULL && v2->comments > 0)
322
0
  v2->comment = &v2->comment_list[v2->comments-1].text;
323
0
}
324
325
/*
326
  Store ID3 text data in an mpg123_string; either verbatim copy or
327
  everything translated to UTF-8 encoding.
328
  Preserve the zero string separator (I don't need strlen for the total size).
329
330
  Since we can overwrite strings with ID3 update frames, don't free
331
  memory, just grow strings.
332
*/
333
static void store_id3_text(mpg123_string *sb, unsigned char encoding, unsigned char *source
334
, size_t source_size, const int noquiet, const int notranslate)
335
46.1k
{
336
46.1k
  if(sb) // Always overwrite, even with nothing.
337
46.1k
    sb->fill = 0;
338
46.1k
  if(!source_size)
339
1.24k
  {
340
1.24k
    debug("Empty id3 data!");
341
1.24k
    return;
342
1.24k
  }
343
344
  /* We shall just copy the data. Client wants to decode itself. */
345
44.9k
  if(notranslate)
346
0
  {
347
    /* Future: Add a path for ID3 errors. */
348
0
    if(!mpg123_grow_string(sb, source_size+1))
349
0
    {
350
0
      if(noquiet) error("Cannot resize target string, out of memory?");
351
0
      return;
352
0
    }
353
0
    sb->p[0] = (char)encoding;
354
0
    memcpy(sb->p+1, source, source_size);
355
0
    sb->fill = source_size+1;
356
0
    debug1("stored undecoded ID3 text of size %zu", source_size+1);
357
0
    return;
358
0
  }
359
360
44.9k
  if(encoding > mpg123_id3_enc_max)
361
381
  {
362
381
    if(noquiet)
363
381
      error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
364
381
    return;
365
381
  }
366
44.5k
  INT123_id3_to_utf8(sb, encoding, source, source_size, noquiet);
367
368
44.5k
  if(sb->fill) debug1("UTF-8 string (the first one): %s", sb->p);
369
0
  else if(noquiet) error("unable to convert string to UTF-8 (out of memory, junk input?)!");
370
44.5k
}
371
372
/* On error, sb->size is 0. */
373
/* Also, encoding has been checked already! */
374
void INT123_id3_to_utf8(mpg123_string *sb, unsigned char encoding, const unsigned char *source, size_t source_size, int noquiet)
375
44.5k
{
376
44.5k
  unsigned int bwidth;
377
44.5k
  if(sb)
378
44.5k
    sb->fill = 0;
379
44.5k
  debug1("encoding: %u", encoding);
380
  /* A note: ID3v2.3 uses UCS-2 non-variable 16bit encoding, v2.4 uses UTF16.
381
     UTF-16 uses a reserved/private range in UCS-2 to add the magic, so we just always treat it as UTF. */
382
44.5k
  bwidth = encoding_widths[encoding];
383
  /* Hack! I've seen a stray zero byte before BOM. Is that supposed to happen? */
384
44.5k
  if(encoding != mpg123_id3_utf16be) /* UTF16be _can_ beging with a null byte! */
385
57.2k
  while(source_size > bwidth && source[0] == 0)
386
15.5k
  {
387
15.5k
    --source_size;
388
15.5k
    ++source;
389
15.5k
    debug("skipped leading zero");
390
15.5k
  }
391
44.5k
  if(source_size % bwidth)
392
1.12k
  {
393
    /* When we need two bytes for a character, it's strange to have an uneven bytestream length. */
394
1.12k
    if(noquiet) warning2("Weird tag size %d for encoding %u - I will probably trim too early or something but I think the MP3 is broken.", (int)source_size, encoding);
395
1.12k
    source_size -= source_size % bwidth;
396
1.12k
  }
397
44.5k
  text_converters[encoding](sb, source, source_size, noquiet);
398
44.5k
}
399
400
/* You have checked encoding to be in the range already. */
401
static unsigned char *next_text(unsigned char* prev, unsigned char encoding, size_t limit)
402
14.9k
{
403
14.9k
  unsigned char *text = prev;
404
14.9k
  size_t width = encoding_widths[encoding];
405
406
14.9k
  if(limit > PTRDIFF_MAX)
407
0
    return NULL;
408
409
  /* So I go lengths to find zero or double zero...
410
     Remember bug 2834636: Only check for aligned NULLs! */
411
183k
  while(text-prev < (ptrdiff_t)limit)
412
182k
  {
413
182k
    if(text[0] == 0)
414
16.3k
    {
415
16.3k
      if(width <= limit-(text-prev))
416
15.9k
      {
417
15.9k
        size_t i = 1;
418
17.3k
        for(; i<width; ++i) if(text[i] != 0) break;
419
420
15.9k
        if(i == width) /* found a null wide enough! */
421
13.5k
        {
422
13.5k
          text += width;
423
13.5k
          break;
424
13.5k
        }
425
15.9k
      }
426
393
      else return NULL; /* No full character left? This text is broken */
427
16.3k
    }
428
429
168k
    text += width;
430
168k
  }
431
14.5k
  if((size_t)(text-prev) >= limit) text = NULL;
432
433
14.5k
  return text;
434
14.9k
}
435
436
static const char *enc_name(unsigned char enc)
437
0
{
438
0
  switch(enc)
439
0
  {
440
0
    case 0:  return "Latin 1";
441
0
    case 1:  return "UTF-16 BOM";
442
0
    case 2:  return "UTF-16 BE";
443
0
    case 3:  return "UTF-8";
444
0
    default: return "unknown!";
445
0
  }
446
0
}
447
448
static void process_text(mpg123_handle *fr, unsigned char *realdata, size_t realsize, char *id)
449
2.26k
{
450
  /* Text encoding          $xx */
451
  /* The text (encoded) ... */
452
2.26k
  if(realsize < 1)
453
0
  {
454
0
    if(NOQUIET) error("Not even an encoding byte?");
455
0
    return;
456
0
  }
457
2.26k
  mpg123_text *t = add_text(fr, id);
458
2.26k
  if(VERBOSE4) fprintf(stderr, "Note: Storing text from %s encoding\n", enc_name(realdata[0]));
459
2.26k
  if(t == NULL)
460
0
  {
461
0
    if(NOQUIET) error("Unable to attach new text!");
462
0
    return;
463
0
  }
464
2.26k
  mdebug("process_text: (over)writing entry with ID %s", t->id[0]
465
2.26k
  ? (char[5]) { t->id[0], t->id[1], t->id[2], t->id[3], 0 }
466
2.26k
  : "(nil)" );
467
2.26k
  memcpy(t->id, id, 4);
468
2.26k
  store_id3_text( &t->text, realdata[0], realdata+1, realsize-1
469
2.26k
  , NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT );
470
2.26k
  if(VERBOSE4) // Do not print unsanitized text to terminals!
471
0
    fprintf(stderr, "Note: ID3v2 %c%c%c%c text frame stored\n", id[0], id[1], id[2], id[3]);
472
2.26k
}
473
474
static void process_picture(mpg123_handle *fr, unsigned char *realdata, size_t realsize)
475
0
{
476
0
  unsigned char encoding;
477
0
  mpg123_picture *i = NULL;
478
0
  unsigned char* workpoint = NULL;
479
0
  mpg123_string mime; mpg123_init_string(&mime);
480
0
  unsigned char image_type = 0;
481
0
  mpg123_string description;  mpg123_init_string(&description);
482
0
  unsigned char *image_data = NULL;
483
0
  if(realsize < 1)
484
0
  {
485
0
    debug("Empty id3 data!");
486
0
    return;
487
0
  }
488
0
  encoding = realdata[0];
489
0
  realdata++; realsize--;
490
0
  if(encoding > mpg123_id3_enc_max)
491
0
  {
492
0
    if(NOQUIET)
493
0
      error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
494
0
    return;
495
0
  }
496
0
  if(VERBOSE4) fprintf(stderr, "Note: Storing picture from APIC frame.\n");
497
498
  /* get mime type (encoding is always latin-1) */
499
0
  workpoint = next_text(realdata, 0, realsize);
500
0
  if(!workpoint)
501
0
  {
502
0
    if(NOQUIET)
503
0
      error("Unable to get mime type for picture; skipping picture.");
504
0
    return;
505
0
  }
506
0
  INT123_id3_to_utf8(&mime, 0, realdata, workpoint - realdata, NOQUIET);
507
0
  realsize -= workpoint - realdata;
508
0
  realdata = workpoint;
509
  /* get picture type */
510
0
  image_type = realdata[0];
511
0
  realdata++; realsize--;
512
  /* get description (encoding is encoding) */
513
0
  workpoint = next_text(realdata, encoding, realsize);
514
0
  if(!workpoint)
515
0
  {
516
0
    if(NOQUIET)
517
0
      error("Unable to get description for picture; skipping picture.");
518
0
    mpg123_free_string(&mime);
519
0
    return;
520
0
  }
521
0
  INT123_id3_to_utf8(&description, encoding, realdata, workpoint - realdata, NOQUIET);
522
0
  realsize -= workpoint - realdata;
523
0
  if(realsize)
524
0
    image_data = (unsigned char*)malloc(realsize);
525
0
  if(!realsize || !image_data) {
526
0
    if(NOQUIET)
527
0
      error("No picture data or malloc failure; skipping picture.");
528
0
    mpg123_free_string(&description);
529
0
    mpg123_free_string(&mime);
530
0
    return;
531
0
  }
532
0
  memcpy(image_data, workpoint, realsize);
533
534
  // All data ready now, append to/replace in list.
535
0
  i = add_picture(fr, image_type, &description);
536
0
  if(!i)
537
0
  {
538
0
    if(NOQUIET)
539
0
      error("Unable to attach new picture!");
540
0
    free(image_data);
541
0
    mpg123_free_string(&description);
542
0
    mpg123_free_string(&mime);
543
0
    return;
544
0
  }
545
546
  // Either this is a fresh image, or one to be replaced.
547
  // We hand over memory, so old storage needs to be freed.
548
0
  free_mpg123_picture(i);
549
0
  i->type = image_type;
550
0
  i->size = realsize;
551
0
  i->data = image_data;
552
0
  mpg123_move_string(&mime, &i->mime_type);
553
0
  mpg123_move_string(&description, &i->description);
554
0
  if(VERBOSE4)
555
0
    fprintf(stderr, "Note: ID3v2 APIC picture frame of type: %d\n", i->type);
556
0
}
557
558
/* Store a new comment that perhaps is a RVA / RVA_ALBUM/AUDIOPHILE / RVA_MIX/RADIO one
559
   Special gimmik: It also stores USLT to the texts. Stucture is the same as for comments. */
560
static void process_comment(mpg123_handle *fr, enum frame_types tt, unsigned char *realdata, size_t realsize, int rva_level, char *id)
561
6.10k
{
562
  /* Text encoding          $xx */
563
  /* Language               $xx xx xx */
564
  /* Short description (encoded!)      <text> $00 (00) */
565
  /* Then the comment text (encoded) ... */
566
6.10k
  unsigned char  encoding = realdata[0];
567
6.10k
  char lang[3]; // realdata + 1
568
6.10k
  unsigned char *descr    = realdata+4;
569
6.10k
  unsigned char *text     = NULL;
570
6.10k
  mpg123_text *xcom = NULL;
571
6.10k
  mpg123_text localcom; // UTF-8 variant for local processing, remember to clean up!
572
6.10k
  init_mpg123_text(&localcom);
573
574
6.10k
  if(realsize < (size_t)(descr-realdata))
575
386
  {
576
386
    if(NOQUIET) error1("Invalid frame size of %zu (too small for anything).", realsize);
577
386
    return;
578
386
  }
579
5.71k
  if(encoding > mpg123_id3_enc_max)
580
317
  {
581
317
    if(NOQUIET)
582
317
      error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
583
317
    return;
584
317
  }
585
5.39k
  memcpy(lang, realdata+1, 3);
586
  /* Be careful with finding the end of description, I have to honor encoding here. */
587
5.39k
  text = next_text(descr, encoding, realsize-(descr-realdata));
588
5.39k
  if(text == NULL)
589
805
  {
590
805
    if(NOQUIET)
591
805
      error("No comment text / valid description?");
592
805
    return;
593
805
  }
594
4.59k
  { // just vor variable scope
595
4.59k
    mpg123_string description;
596
4.59k
    mpg123_init_string(&description);
597
    // Store the text, with desired encoding, but for comments always a local copy in UTF-8.
598
4.59k
    store_id3_text( &description, encoding, descr, text-descr
599
4.59k
    , NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT );
600
4.59k
    if(tt == comment)
601
4.09k
      store_id3_text( &localcom.description, encoding, descr, text-descr
602
4.09k
      , NOQUIET, 0 );
603
4.59k
    if(VERBOSE4)
604
0
      fprintf( stderr, "Note: Storing comment from %s encoding\n"
605
0
      , enc_name(encoding) );
606
4.59k
    xcom = tt == uslt
607
4.59k
    ?  add_uslt(fr, lang, &description)
608
4.59k
    : add_comment(fr, lang, &description);
609
4.59k
    if(xcom == NULL)
610
0
    {
611
0
      if(NOQUIET)
612
0
        error("Unable to attach new comment!");
613
0
      mpg123_free_string(&description);
614
0
      free_mpg123_text(&localcom);
615
0
      return;
616
0
    }
617
4.59k
    memcpy(xcom->id, id, 4);
618
4.59k
    memcpy(xcom->lang, lang, 3);
619
    // That takes over the description allocation.
620
4.59k
    mpg123_move_string(&description, &xcom->description);
621
4.59k
  }
622
623
0
  store_id3_text( &xcom->text, encoding, text, realsize-(text-realdata)
624
4.59k
  , NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT );
625
  /* Remember: I will probably decode the above (again) for rva comment checking. So no messing around, please. */
626
627
4.59k
  if(VERBOSE4) /* Do _not_ print the verbatim text: The encoding might be funny! */
628
0
  {
629
0
    fprintf(stderr, "Note: ID3 comm/uslt desc of length %zu.\n", xcom->description.fill);
630
0
    fprintf(stderr, "Note: ID3 comm/uslt text of length %zu.\n", xcom->text.fill);
631
0
  }
632
  /* Look out for RVA info only when we really deal with a straight comment. */
633
4.59k
  if(tt == comment && localcom.description.fill > 0)
634
4.09k
  {
635
4.09k
    int rva_mode = -1; /* mix / album */
636
4.09k
    if(    !strcasecmp(localcom.description.p, "rva")
637
3.66k
       || !strcasecmp(localcom.description.p, "rva_mix")
638
3.45k
       || !strcasecmp(localcom.description.p, "rva_track")
639
2.86k
       || !strcasecmp(localcom.description.p, "rva_radio") )
640
1.61k
    rva_mode = 0;
641
2.47k
    else if(    !strcasecmp(localcom.description.p, "rva_album")
642
2.28k
             || !strcasecmp(localcom.description.p, "rva_audiophile")
643
2.07k
             || !strcasecmp(localcom.description.p, "rva_user") )
644
618
    rva_mode = 1;
645
4.09k
    if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
646
1.62k
    {
647
      /* Only translate the contents in here where we really need them. */
648
1.62k
      store_id3_text( &localcom.text, encoding, text, realsize-(text-realdata)
649
1.62k
      , NOQUIET, 0 );
650
1.62k
      if(localcom.text.fill > 0)
651
1.62k
      {
652
1.62k
        fr->rva.gain[rva_mode] = (float) atof(localcom.text.p);
653
1.62k
        if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
654
1.62k
        fr->rva.peak[rva_mode] = 0;
655
1.62k
        fr->rva.level[rva_mode] = rva_level;
656
1.62k
      }
657
1.62k
    }
658
4.09k
  }
659
  /* Make sure to free the local memory... */
660
4.59k
  free_mpg123_text(&localcom);
661
4.59k
}
662
663
static void process_extra(mpg123_handle *fr, unsigned char* realdata, size_t realsize, int rva_level, char *id)
664
9.88k
{
665
  /* Text encoding          $xx */
666
  /* Description        ... $00 (00) */
667
  /* Text ... */
668
9.88k
  unsigned char encoding = realdata[0];
669
9.88k
  unsigned char *descr   = realdata+1; /* remember, the encoding is descr[-1] */
670
9.88k
  unsigned char *text;
671
9.88k
  mpg123_text *xex;
672
9.88k
  mpg123_text localex;
673
674
9.88k
  if((int)realsize < descr-realdata)
675
0
  {
676
0
    if(NOQUIET) error1("Invalid frame size of %lu (too small for anything).", (unsigned long)realsize);
677
0
    return;
678
0
  }
679
9.88k
  if(encoding > mpg123_id3_enc_max)
680
293
  {
681
293
    if(NOQUIET)
682
293
      error1("Unknown text encoding %u, I take no chances, sorry!", encoding);
683
293
    return;
684
293
  }
685
9.59k
  text = next_text(descr, encoding, realsize-(descr-realdata));
686
9.59k
  if(VERBOSE4) fprintf(stderr, "Note: Storing extra from %s encoding\n", enc_name(realdata[0]));
687
9.59k
  if(text == NULL)
688
898
  {
689
898
    if(NOQUIET) error("No extra frame text / valid description?");
690
898
    return;
691
898
  }
692
8.69k
  { // just vor variable scope
693
8.69k
    mpg123_string description;
694
8.69k
    mpg123_init_string(&description);
695
    /* The outside storage gets reencoded to UTF-8 only if not requested otherwise.
696
       Remember that we really need the -1 here to hand in the encoding byte!*/
697
8.69k
    store_id3_text( &description, encoding, descr, text-descr
698
8.69k
    , NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT );
699
8.69k
    xex = add_extra(fr, &description);
700
8.69k
    if(xex)
701
8.69k
      mpg123_move_string(&description, &xex->description);
702
0
    else
703
0
      mpg123_free_string(&description);
704
8.69k
  }
705
8.69k
  if(xex == NULL)
706
0
  {
707
0
    if(NOQUIET) error("Unable to attach new extra text!");
708
0
    return;
709
0
  }
710
8.69k
  memcpy(xex->id, id, 4);
711
8.69k
  init_mpg123_text(&localex); /* For our local copy. */
712
713
  /* Our local copy is always stored in UTF-8! */
714
8.69k
  store_id3_text(&localex.description, encoding, descr, text-descr, NOQUIET, 0);
715
  /* At first, only store the outside copy of the payload. We may not need the local copy. */
716
8.69k
  store_id3_text( &xex->text, encoding, text, realsize-(text-realdata)
717
8.69k
  , NOQUIET, fr->p.flags & MPG123_PLAIN_ID3TEXT );
718
719
  /* Now check if we would like to interpret this extra info for RVA. */
720
8.69k
  if(localex.description.fill > 0)
721
8.69k
  {
722
8.69k
    int is_peak = 0;
723
8.69k
    int rva_mode = -1; /* mix / album */
724
725
8.69k
    if(!strncasecmp(localex.description.p, "replaygain_track_",17))
726
2.92k
    {
727
2.92k
      if(VERBOSE3) fprintf(stderr, "Note: RVA ReplayGain track gain/peak\n");
728
729
2.92k
      rva_mode = 0;
730
2.92k
      if(!strcasecmp(localex.description.p, "replaygain_track_peak")) is_peak = 1;
731
1.96k
      else if(strcasecmp(localex.description.p, "replaygain_track_gain")) rva_mode = -1;
732
2.92k
    }
733
5.77k
    else
734
5.77k
    if(!strncasecmp(localex.description.p, "replaygain_album_",17))
735
980
    {
736
980
      if(VERBOSE3) fprintf(stderr, "Note: RVA ReplayGain album gain/peak\n");
737
738
980
      rva_mode = 1;
739
980
      if(!strcasecmp(localex.description.p, "replaygain_album_peak")) is_peak = 1;
740
693
      else if(strcasecmp(localex.description.p, "replaygain_album_gain")) rva_mode = -1;
741
980
    }
742
8.69k
    if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
743
2.89k
    {
744
      /* Now we need the translated copy of the data. */
745
2.89k
      store_id3_text( &localex.text, encoding, text, realsize-(text-realdata)
746
2.89k
      , NOQUIET, 0 );
747
2.89k
      if(localex.text.fill > 0)
748
2.89k
      {
749
2.89k
        if(is_peak)
750
1.05k
        {
751
1.05k
          fr->rva.peak[rva_mode] = (float) atof(localex.text.p);
752
1.05k
          if(VERBOSE3) fprintf(stderr, "Note: RVA peak %f\n", fr->rva.peak[rva_mode]);
753
1.05k
        }
754
1.83k
        else
755
1.83k
        {
756
1.83k
          fr->rva.gain[rva_mode] = (float) atof(localex.text.p);
757
1.83k
          if(VERBOSE3) fprintf(stderr, "Note: RVA gain %fdB\n", fr->rva.gain[rva_mode]);
758
1.83k
        }
759
2.89k
        fr->rva.level[rva_mode] = rva_level;
760
2.89k
      }
761
2.89k
    }
762
8.69k
  }
763
764
8.69k
  free_mpg123_text(&localex);
765
8.69k
}
766
767
/* Make a ID3v2.3+ 4-byte ID from a ID3v2.2 3-byte ID
768
   Note that not all frames survived to 2.4; the mapping goes to 2.3 .
769
   A notable miss is the old RVA frame, which is very unspecific anyway.
770
   This function returns -1 when a not known 3 char ID was encountered, 0 otherwise. */
771
static int promote_framename(mpg123_handle *fr, char *id) /* fr because of VERBOSE macros */
772
14.6k
{
773
14.6k
  size_t i;
774
14.6k
  char *old[] =
775
14.6k
  {
776
14.6k
    "COM",  "TAL",  "TBP",  "TCM",  "TCO",  "TCR",  "TDA",  "TDY",  "TEN",  "TFT",
777
14.6k
    "TIM",  "TKE",  "TLA",  "TLE",  "TMT",  "TOA",  "TOF",  "TOL",  "TOR",  "TOT",
778
14.6k
    "TP1",  "TP2",  "TP3",  "TP4",  "TPA",  "TPB",  "TRC",  "TDA",  "TRK",  "TSI",
779
14.6k
    "TSS",  "TT1",  "TT2",  "TT3",  "TXT",  "TXX",  "TYE"
780
14.6k
  };
781
14.6k
  char *new[] =
782
14.6k
  {
783
14.6k
    "COMM", "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDAT", "TDLY", "TENC", "TFLT",
784
14.6k
    "TIME", "TKEY", "TLAN", "TLEN", "TMED", "TOPE", "TOFN", "TOLY", "TORY", "TOAL",
785
14.6k
    "TPE1", "TPE2", "TPE3", "TPE4", "TPOS", "TPUB", "TSRC", "TRDA", "TRCK", "TSIZ",
786
14.6k
    "TSSE", "TIT1", "TIT2", "TIT3", "TEXT", "TXXX", "TYER"
787
14.6k
  };
788
332k
  for(i=0; i<sizeof(old)/sizeof(char*); ++i)
789
332k
  {
790
332k
    if(!strncmp(id, old[i], 3))
791
14.3k
    {
792
14.3k
      memcpy(id, new[i], 4);
793
14.3k
      if(VERBOSE3) fprintf(stderr, "Translated ID3v2.2 frame %s to %s\n", old[i], new[i]);
794
14.3k
      return 0;
795
14.3k
    }
796
332k
  }
797
319
  if(VERBOSE3) fprintf(stderr, "Ignoring untranslated ID3v2.2 frame %c%c%c\n", id[0], id[1], id[2]);
798
319
  return -1;
799
14.6k
}
800
801
#endif /* NO_ID3V2 */
802
803
static int store_id3v2( mpg123_handle *fr
804
, unsigned long first4bytes, unsigned char buf[6], unsigned long length )
805
32.7k
{
806
32.7k
  int ret = 1;
807
32.7k
  int64_t ret2;
808
32.7k
  unsigned long fullen = 10+length;
809
32.7k
  if(fr->id3v2_raw)
810
0
    free(fr->id3v2_raw);
811
32.7k
  fr->id3v2_size = 0;
812
  /* Allocate one byte more for a closing zero as safety catch for strlen(). */
813
32.7k
  fr->id3v2_raw = malloc(fullen+1);
814
32.7k
  if(!fr->id3v2_raw)
815
0
  {
816
0
    fr->err = MPG123_OUT_OF_MEM;
817
0
    if(NOQUIET)
818
0
      error1("ID3v2: Arrg! Unable to allocate %lu bytes"
819
0
        " for ID3v2 data - trying to skip instead.", length+1);
820
0
    if((ret2=fr->rd->skip_bytes(fr,length)) < 0)
821
0
      ret = ret2;
822
0
    else
823
0
      ret = 0;
824
0
  }
825
32.7k
  else
826
32.7k
  {
827
32.7k
    fr->id3v2_raw[0] = (first4bytes>>24) & 0xff;
828
32.7k
    fr->id3v2_raw[1] = (first4bytes>>16) & 0xff;
829
32.7k
    fr->id3v2_raw[2] = (first4bytes>>8)  & 0xff;
830
32.7k
    fr->id3v2_raw[3] =  first4bytes      & 0xff;
831
32.7k
    memcpy(fr->id3v2_raw+4, buf, 6);
832
32.7k
    if((ret2=fr->rd->read_frame_body(fr, fr->id3v2_raw+10, length)) < 0)
833
11.4k
    {
834
11.4k
      ret=ret2;
835
11.4k
      free(fr->id3v2_raw);
836
11.4k
      fr->id3v2_raw = NULL;
837
11.4k
    }
838
21.3k
    else
839
21.3k
    { /* Closing with a zero for paranoia. */
840
21.3k
      fr->id3v2_raw[fullen] = 0;
841
21.3k
      fr->id3v2_size = fullen;
842
21.3k
    }
843
32.7k
  }
844
32.7k
  return ret;
845
32.7k
}
846
847
/*
848
  trying to parse ID3v2.3 and ID3v2.4 tags...
849
850
  returns:  0: bad or just unparseable tag
851
            1: good, (possibly) new tag info
852
           <0: reader error (may need more data feed, try again)
853
*/
854
int INT123_parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
855
46.7k
{
856
46.7k
  #define UNSYNC_FLAG 128
857
46.7k
  #define EXTHEAD_FLAG 64  /* ID3v2.3+ */
858
46.7k
  #define COMPRESS_FLAG 64 /* ID3v2.2 */
859
46.7k
  #define EXP_FLAG 32
860
46.7k
  #define FOOTER_FLAG 16
861
46.7k
  #define EXT_UPDATE_FLAG 64 /* ID3v2.4 only: extended header update flag */
862
46.7k
  #define UNKNOWN_FLAGS 15 /* 00001111*/
863
46.7k
  unsigned char buf[6];
864
46.7k
  unsigned long length=0;
865
46.7k
  unsigned char flags = 0;
866
46.7k
  int ret = 1;
867
46.7k
  int64_t ret2;
868
46.7k
  int storetag = 0;
869
46.7k
  unsigned int footlen = 0;
870
46.7k
#ifndef NO_ID3V2
871
46.7k
  int skiptag = 0;
872
46.7k
#endif
873
46.7k
  unsigned char major = first4bytes & 0xff;
874
46.7k
  debug1("ID3v2: major tag version: %i", major);
875
876
46.7k
  if(major == 0xff) return 0; /* Invalid... */
877
45.9k
  if((ret2 = fr->rd->read_frame_body(fr, buf, 6)) < 0) /* read more header information */
878
474
  return ret2;
879
880
45.4k
  if(buf[0] == 0xff) return 0; /* Revision, will never be 0xff. */
881
882
44.6k
  if(fr->p.flags & MPG123_STORE_RAW_ID3)
883
0
    storetag = 1;
884
  /* second new byte are some nice flags, if these are invalid skip the whole thing */
885
44.6k
  flags = buf[1];
886
44.6k
  debug1("ID3v2: flags 0x%08x", flags);
887
  /* use 4 bytes from buf to construct 28bit uint value and return 1; return 0 if bytes are not synchsafe */
888
44.6k
  #define synchsafe_to_long(buf,res) \
889
56.8k
  ( \
890
56.8k
    (((buf)[0]|(buf)[1]|(buf)[2]|(buf)[3]) & 0x80) ? 0 : \
891
56.8k
    (res =  (((unsigned long) (buf)[0]) << 21) \
892
54.4k
         | (((unsigned long) (buf)[1]) << 14) \
893
54.4k
         | (((unsigned long) (buf)[2]) << 7) \
894
54.4k
         |  ((unsigned long) (buf)[3]) \
895
54.4k
    ,1) \
896
56.8k
  )
897
  /* id3v2.3 does not store synchsafe frame sizes, but synchsafe tag size - doh! */
898
  /* Remember: bytes_to_long() can yield ULONG_MAX on 32 bit platforms! */
899
44.6k
  #define bytes_to_long(buf,res) \
900
44.6k
  ( \
901
18.6k
    major == 3 ? \
902
18.6k
    (res =  (((unsigned long) (buf)[0]) << 24) \
903
2.16k
         | (((unsigned long) (buf)[1]) << 16) \
904
2.16k
         | (((unsigned long) (buf)[2]) << 8) \
905
2.16k
         |  ((unsigned long) (buf)[3]) \
906
12.1k
    ,1) : synchsafe_to_long(buf,res) \
907
18.6k
  )
908
  /* for id3v2.2 only */
909
44.6k
  #define threebytes_to_long(buf,res) \
910
44.6k
  ( \
911
15.0k
    res =  (((unsigned long) (buf)[0]) << 16) \
912
15.0k
         | (((unsigned long) (buf)[1]) << 8) \
913
15.0k
         |  ((unsigned long) (buf)[2]) \
914
15.0k
  )
915
916
  /* length-10 or length-20 (footer present); 4 synchsafe integers == 28 bit number  */
917
  /* we have already read 10 bytes, so left are length or length+10 bytes belonging to tag */
918
  /* Note: This is an 28 bit value in 32 bit storage, plenty of space for */
919
  /* length+x for reasonable x. */
920
44.6k
  if(!synchsafe_to_long(buf+2,length))
921
1.45k
  {
922
1.45k
    if(NOQUIET) error4("Bad tag length (not synchsafe): 0x%02x%02x%02x%02x; You got a bad ID3 tag here.", buf[2],buf[3],buf[4],buf[5]);
923
1.45k
    return 0;
924
1.45k
  }
925
43.1k
  if(flags & FOOTER_FLAG)
926
1.89k
    footlen = 10;
927
43.1k
  debug1("ID3v2: tag data length %lu", length);
928
43.1k
#ifndef NO_ID3V2
929
43.1k
  if(VERBOSE2) fprintf(stderr,"Note: ID3v2.%i rev %i tag of %lu bytes\n", major, buf[0], length);
930
  /* skip if unknown version/scary flags, parse otherwise */
931
43.1k
  if(fr->p.flags & MPG123_SKIP_ID3V2)
932
0
  {
933
0
    if(VERBOSE3)
934
0
      fprintf(stderr, "Note: Skipping ID3v2 tag per user request.\n");
935
0
    skiptag = 1;
936
0
  }
937
43.1k
  if((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2))
938
8.15k
  {
939
8.15k
    if(NOQUIET)
940
8.15k
      warning2( "ID3v2: Won't parse the ID3v2 tag with major version"
941
8.15k
        " %u and flags 0x%xu - some extra code may be needed"
942
8.15k
      , major, flags );
943
8.15k
    skiptag = 1;
944
8.15k
  }
945
  // Standard says that compressed tags should be ignored as there isn't an agreed
946
  // compressoion scheme.
947
43.1k
  if(major == 2 && flags & COMPRESS_FLAG)
948
455
  {
949
455
    if(NOQUIET)
950
455
      warning("ID3v2: ignoring compressed ID3v2.2 tag");
951
455
    skiptag = 1;
952
455
  }
953
43.1k
  if(length < 10)
954
6.94k
  {
955
6.94k
    if(NOQUIET)
956
6.94k
      warning1("ID3v2: unrealistic small tag lengh %lu, skipping", length);
957
6.94k
    skiptag = 1;
958
6.94k
  }
959
43.1k
  if(!skiptag)
960
32.7k
    storetag = 1;
961
43.1k
#endif
962
43.1k
  if(storetag)
963
32.7k
  {
964
    /* Stores whole tag with footer and an additonal trailing zero. */
965
32.7k
    if((ret2 = store_id3v2(fr, first4bytes, buf, length+footlen)) <= 0)
966
11.4k
      return ret2;
967
32.7k
  }
968
31.7k
#ifndef NO_ID3V2
969
31.7k
  if(skiptag)
970
10.4k
  {
971
10.4k
    if(VERBOSE3)
972
0
      fprintf(stderr, "Note: skipped tag clearing possibly existing ID3v2 data");
973
10.4k
    INT123_reset_id3(fr); // Old data is invalid.
974
10.4k
#endif
975
10.4k
    if(!storetag && (ret2=fr->rd->skip_bytes(fr,length+footlen))<0)
976
3.83k
      ret=ret2;
977
10.4k
#ifndef NO_ID3V2
978
10.4k
  }
979
21.3k
  else
980
21.3k
  {
981
21.3k
    unsigned char* tagdata = fr->id3v2_raw+10;
982
    /* try to interpret that beast */
983
21.3k
    debug("ID3v2: analysing frames...");
984
21.3k
    if(length > 0)
985
21.3k
    {
986
21.3k
      unsigned char extflags = 0;
987
21.3k
      unsigned long tagpos = 0;
988
      /* bytes of frame title and of framesize value */
989
21.3k
      unsigned int head_part = major > 2 ? 4 : 3;
990
21.3k
      unsigned int flag_part = major > 2 ? 2 : 0;
991
      /* The amount of bytes that are unconditionally read for each frame: */
992
      /* ID, size, flags. */
993
21.3k
      unsigned int framebegin = head_part+head_part+flag_part;
994
21.3k
      debug1("ID3v2: have read at all %lu bytes for the tag now", (unsigned long)length+6);
995
21.3k
      if(flags & EXTHEAD_FLAG)
996
1.45k
      {
997
1.45k
        debug("ID3v2: extended header");
998
1.45k
        if(!bytes_to_long(tagdata, tagpos) || tagpos >= length)
999
642
        {
1000
642
          ret = 0;
1001
642
          if(NOQUIET)
1002
642
            error4( "Bad (non-synchsafe/too large) tag offset from extended header:"
1003
642
              "0x%02x%02x%02x%02x"
1004
642
            , tagdata[0], tagdata[1], tagdata[2], tagdata[3] );
1005
814
        } else if(tagpos < 6)
1006
206
        {
1007
206
          ret = 0;
1008
206
          if(NOQUIET)
1009
206
            merror("Extended header too small (%lu).", tagpos);
1010
206
        }
1011
1.45k
        if(major == 3)
1012
459
        {
1013
459
          tagpos += 4; // The size itself is not included.
1014
459
          if(tagpos >= length)
1015
255
          {
1016
255
            ret = 0;
1017
255
            if(NOQUIET)
1018
255
              error("Too much extended v2.3 header.");
1019
255
          }
1020
997
        } else if(ret) // v2.4 and at least got my 6 bytes of ext header
1021
595
        {
1022
          // Only v4 knows update frames, check for that.
1023
          // Need to step back. Header is 4 bytes length, one byte flag size,
1024
          // one byte flags. Flag size has to be 1!
1025
595
          if(tagdata[4] == 1 && tagdata[5] & EXT_UPDATE_FLAG)
1026
195
          {
1027
195
            if(VERBOSE3)
1028
0
              fprintf(stderr, "Note: ID3v2.4 update tag\n");
1029
195
            extflags |= EXT_UPDATE_FLAG;
1030
195
          }
1031
595
        }
1032
1.45k
      }
1033
21.3k
      if(!(extflags & EXT_UPDATE_FLAG))
1034
21.1k
      {
1035
21.1k
        if(VERBOSE3)
1036
0
          fprintf(stderr, "Note: non-update tag replacing existing ID3v2 data\n");
1037
21.1k
        INT123_reset_id3(fr);
1038
21.1k
      }
1039
21.3k
      if(ret > 0)
1040
20.4k
      {
1041
20.4k
        char id[5];
1042
20.4k
        unsigned long framesize;
1043
20.4k
        unsigned long fflags; /* need 16 bits, actually */
1044
20.4k
        id[4] = 0;
1045
20.4k
        fr->id3v2.version = major;
1046
        /* Pos now advanced after ext head, now a frame has to follow. */
1047
        /* Note: tagpos <= length, which is 28 bit integer, so both */
1048
        /* far away from overflow for adding known small values. */
1049
        /* I want to read at least one full header now. */
1050
44.1k
        while(length >= tagpos+framebegin)
1051
28.9k
        {
1052
28.9k
          int i = 0;
1053
28.9k
          unsigned long pos = tagpos;
1054
          /* level 1,2,3 - 0 is info from lame/info tag! */
1055
          /* rva tags with ascending significance, then general frames */
1056
28.9k
          enum frame_types tt = unknown;
1057
          /* we may have entered the padding zone or any other strangeness: check if we have valid frame id characters */
1058
115k
          for(i=0; i< head_part; ++i)
1059
90.3k
          if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
1060
83.6k
             || ((tagdata[tagpos+i] > 64) && (tagdata[tagpos+i] < 91)) ) )
1061
3.89k
          {
1062
3.89k
            debug5("ID3v2: real tag data apparently ended after %lu bytes with 0x%02x%02x%02x%02x", tagpos, tagdata[tagpos], tagdata[tagpos+1], tagdata[tagpos+2], tagdata[tagpos+3]);
1063
            /* This is no hard error... let's just hope that we got something meaningful already (ret==1 in that case). */
1064
3.89k
            goto tagparse_cleanup; /* Need to escape two loops here. */
1065
3.89k
          }
1066
25.0k
          if(ret > 0)
1067
25.0k
          {
1068
            /* 4 or 3 bytes id */
1069
25.0k
            strncpy(id, (char*) tagdata+pos, head_part);
1070
25.0k
            id[head_part] = 0; /* terminate for 3 or 4 bytes */
1071
25.0k
            pos += head_part;
1072
25.0k
            tagpos += head_part;
1073
            /* size as 32 bits or 28 bits */
1074
25.0k
            if(fr->id3v2.version == 2) threebytes_to_long(tagdata+pos, framesize);
1075
9.97k
            else
1076
9.97k
            if(!bytes_to_long(tagdata+pos, framesize))
1077
350
            {
1078
              /* Just assume that up to now there was some good data. */
1079
350
              if(NOQUIET) error1("ID3v2: non-syncsafe size of %s frame, skipping the remainder of tag", id);
1080
350
              break;
1081
350
            }
1082
24.7k
            if(VERBOSE3) fprintf(stderr, "Note: ID3v2 %s frame of size %lu\n", id, framesize);
1083
24.7k
            tagpos += head_part;
1084
24.7k
            pos += head_part;
1085
24.7k
            if(fr->id3v2.version > 2)
1086
9.62k
            {
1087
9.62k
              fflags  = (((unsigned long) tagdata[pos]) << 8) | ((unsigned long) tagdata[pos+1]);
1088
9.62k
              pos    += 2;
1089
9.62k
              tagpos += 2;
1090
9.62k
            }
1091
15.0k
            else fflags = 0;
1092
1093
24.7k
            if(length - tagpos < framesize)
1094
1.01k
            {
1095
1.01k
              if(NOQUIET) error("Whoa! ID3v2 frame claims to be larger than the whole rest of the tag.");
1096
1.01k
              break;
1097
1.01k
            }
1098
23.6k
            tagpos += framesize; /* the important advancement in whole tag */
1099
            /* for sanity, after full parsing tagpos should be == pos */
1100
            /* debug4("ID3v2: found %s frame, size %lu (as bytes: 0x%08lx), flags 0x%016lx", id, framesize, framesize, fflags); */
1101
            /* v2.4: %0abc0000 %0h00kmnp */
1102
            /* v2.3: %abc00000 %ijk00000 */
1103
            /* v2.2: just zero */
1104
126k
            #define V3 (major == 3)
1105
23.6k
            #define BAD_FFLAGS      (unsigned long) (V3 ? 7967 : 36784)
1106
23.6k
            #define PRES_TAG_FFLAG  (unsigned long) (V3 ? 32768 : 16384)
1107
23.6k
            #define PRES_FILE_FFLAG (unsigned long) (V3 ? 16384 : 8192)
1108
23.6k
            #define READ_ONLY_FFLAG (unsigned long) (V3 ? 8192 : 4096)
1109
23.6k
            #define GROUP_FFLAG     (unsigned long) (V3 ? 32 : 64)
1110
23.6k
            #define COMPR_FFLAG     (unsigned long) (V3 ? 128 : 8)
1111
23.6k
            #define ENCR_FFLAG      (unsigned long) (V3 ? 64 : 4)
1112
23.6k
            #define UNSYNC_FFLAG    (unsigned long) (V3 ? 0 : 2)
1113
23.6k
            #define DATLEN_FFLAG    (unsigned long) (V3 ? 0 : 1)
1114
23.6k
            if(head_part < 4 && promote_framename(fr, id) != 0) continue;
1115
1116
            /* shall not or want not handle these */
1117
23.3k
            if(fflags & (BAD_FFLAGS | COMPR_FFLAG | ENCR_FFLAG))
1118
425
            {
1119
425
              if(NOQUIET) warning("ID3v2: skipping invalid/unsupported frame");
1120
425
              continue;
1121
425
            }
1122
1123
59.3k
            for(i = 0; i < KNOWN_FRAMES; ++i)
1124
55.9k
            if(!strncmp(frame_type[i], id, 4)){ tt = i; break; }
1125
1126
22.9k
            if(id[0] == 'T' && tt != extra) tt = text;
1127
1128
22.9k
            if(tt != unknown)
1129
22.5k
            {
1130
22.5k
              int rva_mode = -1; /* mix / album */
1131
22.5k
              unsigned long realsize = framesize;
1132
22.5k
              unsigned char* realdata = tagdata+pos;
1133
22.5k
              unsigned char* unsyncbuffer = NULL;
1134
22.5k
              if(((flags & UNSYNC_FLAG) || (fflags & UNSYNC_FFLAG)) && framesize > 0)
1135
11.1k
              {
1136
11.1k
                unsigned long ipos = 0;
1137
11.1k
                unsigned long opos = 0;
1138
11.1k
                debug("Id3v2: going to de-unsync the frame data");
1139
                /* de-unsync: FF00 -> FF; real FF00 is simply represented as FF0000 ... */
1140
                /* damn, that means I have to delete bytes from withing the data block... thus need temporal storage */
1141
                /* standard mandates that de-unsync should always be safe if flag is set */
1142
11.1k
                realdata = unsyncbuffer = malloc(framesize+1); /* will need <= bytes, plus a safety zero */
1143
11.1k
                if(realdata == NULL)
1144
0
                {
1145
0
                  if(NOQUIET) error("ID3v2: unable to allocate working buffer for de-unsync");
1146
0
                  continue;
1147
0
                }
1148
                /* now going byte per byte through the data... */
1149
11.1k
                realdata[0] = tagdata[pos];
1150
11.1k
                opos = 1;
1151
33.2M
                for(ipos = pos+1; ipos < pos+framesize; ++ipos)
1152
33.2M
                {
1153
33.2M
                  if(!((tagdata[ipos] == 0) && (tagdata[ipos-1] == 0xff)))
1154
32.9M
                  {
1155
32.9M
                    realdata[opos++] = tagdata[ipos];
1156
32.9M
                  }
1157
33.2M
                }
1158
11.1k
                realsize = opos;
1159
                /* Append a zero to keep strlen() safe. */
1160
11.1k
                realdata[realsize] = 0;
1161
11.1k
                debug2("ID3v2: de-unsync made %lu out of %lu bytes", realsize, framesize);
1162
11.1k
              }
1163
              // The spec says there is a group byte, without explicitly saying that it is
1164
              // the first thing following the header. I just assume so, because of the
1165
              // ordering of the flags.
1166
22.5k
              if(fflags & GROUP_FFLAG)
1167
926
              { // Just skip group byte.
1168
926
                if(realsize)
1169
731
                {
1170
731
                  if(VERBOSE3)
1171
0
                    fprintf(stderr, "Note: frame of group %d\n", realdata[0]);
1172
731
                  --realsize;
1173
731
                  ++realdata;
1174
731
                } else if(NOQUIET)
1175
0
                  error("Grouped frame without group byte, even.");
1176
926
              }
1177
22.5k
              if(fflags & DATLEN_FFLAG)
1178
3.29k
              {
1179
                // Spec says the original (without compression or unsync) data length follows,
1180
                // so it should match de-unsynced data now.
1181
3.29k
                if(realsize >= 4)
1182
2.89k
                {
1183
2.89k
                  unsigned long datlen;
1184
2.89k
                  if(bytes_to_long(realdata, datlen) && datlen == realsize-4)
1185
1.89k
                  {
1186
1.89k
                    realsize  -= 4;
1187
1.89k
                    realdata  += 4;
1188
1.89k
                  } else
1189
999
                  {
1190
999
                    if(NOQUIET)
1191
999
                      error("frame data length bad, skipping");
1192
999
                    realsize = 0;
1193
999
                  }
1194
2.89k
                } else
1195
398
                {
1196
398
                  realsize = 0;
1197
398
                  if(NOQUIET)
1198
398
                    error("frame truncated at frame data length, skipping");
1199
398
                }
1200
3.29k
              }
1201
22.5k
              pos = 0; /* now at the beginning again... */
1202
              /* Avoid reading over boundary, even if there is a */
1203
              /* zero byte of padding for safety. */
1204
22.5k
              if(realsize) switch(tt)
1205
20.6k
              {
1206
5.35k
                case comment:
1207
6.10k
                case uslt:
1208
6.10k
                  process_comment(fr, tt, realdata, realsize, comment+1, id);
1209
6.10k
                break;
1210
9.88k
                case extra: /* perhaps foobar2000's work */
1211
9.88k
                  process_extra(fr, realdata, realsize, extra+1, id);
1212
9.88k
                break;
1213
2.17k
                case rva2: /* "the" RVA tag */
1214
2.17k
                {
1215
                  /* starts with null-terminated identification */
1216
2.17k
                  if(VERBOSE3) fprintf(stderr, "Note: RVA2 identification \"%s\"\n", realdata);
1217
                  /* default: some individual value, mix mode */
1218
2.17k
                  rva_mode = 0;
1219
2.17k
                  if( !strncasecmp((char*)realdata, "album", 5)
1220
1.97k
                     || !strncasecmp((char*)realdata, "audiophile", 10)
1221
1.38k
                     || !strncasecmp((char*)realdata, "user", 4))
1222
983
                  rva_mode = 1;
1223
2.17k
                  if(fr->rva.level[rva_mode] <= rva2+1)
1224
2.17k
                  {
1225
2.17k
                    pos += strlen((char*) realdata) + 1;
1226
2.17k
                    debug2("got my pos: %lu - %lu", realsize, pos);
1227
                    // channel and two bytes for RVA value
1228
                    // pos possibly just past the safety zero, so one more than realsize
1229
2.17k
                    if(pos > realsize || realsize-pos < 3)
1230
1.11k
                    {
1231
1.11k
                      if(NOQUIET)
1232
1.11k
                        error("bad RVA2 tag (truncated?)");
1233
1.11k
                    }
1234
1.06k
                    else if(realdata[pos] == 1)
1235
227
                    {
1236
227
                      ++pos;
1237
                      /* only handle master channel */
1238
227
                      debug("ID3v2: it is for the master channel");
1239
                      /* two bytes adjustment, one byte for bits representing peak - n bytes, eh bits, for peak */
1240
                      /* 16 bit signed integer = dB * 512. Do not shift signed integers! Multiply instead.
1241
                         Also no implementation-defined casting. Reinterpret the pointer to signed char, then do
1242
                         proper casting. */
1243
227
                      fr->rva.gain[rva_mode] = (float) (
1244
227
                        ((short)((signed char*)realdata)[pos]) * 256 + (short)realdata[pos+1] ) / 512;
1245
227
                      pos += 2;
1246
227
                      if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
1247
                      /* heh, the peak value is represented by a number of bits - but in what manner? Skipping that part */
1248
227
                      fr->rva.peak[rva_mode] = 0;
1249
227
                      fr->rva.level[rva_mode] = rva2+1;
1250
227
                    }
1251
2.17k
                  }
1252
2.17k
                }
1253
2.17k
                break;
1254
                /* non-rva metainfo, simply store... */
1255
2.26k
                case text:
1256
2.26k
                  process_text(fr, realdata, realsize, id);
1257
2.26k
                break;
1258
194
                case picture:
1259
194
                  if (fr->p.flags & MPG123_PICTURE)
1260
0
                  process_picture(fr, realdata, realsize);
1261
1262
194
                  break;
1263
0
                default: if(NOQUIET) error1("ID3v2: unknown frame type %i", tt);
1264
20.6k
              }
1265
22.5k
              if(unsyncbuffer)
1266
11.1k
                free(unsyncbuffer);
1267
22.5k
            }
1268
22.9k
            #undef V3
1269
22.9k
            #undef BAD_FFLAGS
1270
22.9k
            #undef PRES_TAG_FFLAG
1271
22.9k
            #undef PRES_FILE_FFLAG
1272
22.9k
            #undef READ_ONLY_FFLAG
1273
22.9k
            #undef GROUP_FFLAG
1274
22.9k
            #undef COMPR_FFLAG
1275
22.9k
            #undef ENCR_FFLAG
1276
22.9k
            #undef UNSYNC_FFLAG
1277
22.9k
            #undef DATLEN_FFLAG
1278
22.9k
          }
1279
0
          else break;
1280
25.0k
          #undef KNOWN_FRAMES
1281
25.0k
        }
1282
20.4k
      } else
1283
852
      {
1284
852
        if(VERBOSE3)
1285
0
          fprintf(stderr, "Note: faulty ID3v2 tag still clearing old data\n");
1286
852
        INT123_reset_id3(fr);
1287
852
      }
1288
21.3k
    } else // No new data, but still there was a tag that invalidates old data.
1289
0
    {
1290
0
      if(VERBOSE3)
1291
0
        fprintf(stderr, "Note: empty ID3v2 clearing old data\n");
1292
0
      INT123_reset_id3(fr);
1293
0
    }
1294
21.3k
tagparse_cleanup:
1295
    /* Get rid of stored raw data that should not be kept. */
1296
21.3k
    if(!(fr->p.flags & MPG123_STORE_RAW_ID3))
1297
21.3k
    {
1298
21.3k
      free(fr->id3v2_raw);
1299
21.3k
      fr->id3v2_raw = NULL;
1300
21.3k
      fr->id3v2_size = 0;
1301
21.3k
    }
1302
21.3k
  }
1303
31.7k
#endif /* NO_ID3V2 */
1304
31.7k
  return ret;
1305
31.7k
  #undef UNSYNC_FLAG
1306
31.7k
  #undef EXTHEAD_FLAG
1307
31.7k
  #undef COMPRESS_FLAG
1308
31.7k
  #undef EXP_FLAG
1309
31.7k
  #undef FOOTER_FLAG
1310
31.7k
  #undef EXT_UPDATE_FLAG
1311
31.7k
  #undef UNKOWN_FLAGS
1312
31.7k
}
1313
1314
#ifndef NO_ID3V2 /* Disabling all the rest... */
1315
1316
static void convert_latin1(mpg123_string *sb, const unsigned char* s, size_t l, const int noquiet)
1317
36.2k
{
1318
36.2k
  size_t length = l;
1319
36.2k
  size_t i;
1320
36.2k
  unsigned char *p;
1321
  /* determine real length, a latin1 character can at most take 2  in UTF8 */
1322
28.3M
  for(i=0; i<l; ++i)
1323
28.3M
  if(s[i] >= 0x80) ++length;
1324
1325
36.2k
  debug1("UTF-8 length: %lu", (unsigned long)length);
1326
  /* one extra zero byte for paranoia */
1327
36.2k
  if(!mpg123_grow_string(sb, length+1))
1328
0
    return;
1329
1330
36.2k
  p = (unsigned char*) sb->p; /* Signedness doesn't matter but it shows I thought about the non-issue */
1331
28.3M
  for(i=0; i<l; ++i)
1332
28.3M
  if(s[i] < 0x80){ *p = s[i]; ++p; }
1333
11.0M
  else /* two-byte encoding */
1334
11.0M
  {
1335
11.0M
    *p     = 0xc0 | (s[i]>>6);
1336
11.0M
    *(p+1) = 0x80 | (s[i] & 0x3f);
1337
11.0M
    p+=2;
1338
11.0M
  }
1339
1340
36.2k
  sb->p[length] = 0;
1341
36.2k
  sb->fill = length+1;
1342
36.2k
}
1343
1344
/*
1345
  Check if we have a byte oder mark(s) there, return:
1346
  -1: little endian
1347
   0: no BOM
1348
   1: big endian
1349
1350
  This modifies source and len to indicate the data _after_ the BOM(s).
1351
  Note on nasty data: The last encountered BOM determines the endianness.
1352
  I have seen data with multiple BOMS, namely from "the" id3v2 program.
1353
  Not nice, but what should I do?
1354
*/
1355
static int check_bom(const unsigned char** source, size_t *len)
1356
4.53k
{
1357
4.53k
  int last_bom = 0;
1358
1359
5.78k
  while(*len >= 2)
1360
4.88k
  {
1361
4.88k
    int this_bom = 0;
1362
4.88k
    if((*source)[0] == 0xff && (*source)[1] == 0xfe)
1363
915
      this_bom = -1;
1364
4.88k
    if((*source)[0] == 0xfe && (*source)[1] == 0xff)
1365
341
      this_bom = 1;
1366
4.88k
    if(this_bom == 0)
1367
3.62k
      break;
1368
    /* Skip the detected BOM. */
1369
1.25k
    last_bom = this_bom;
1370
1.25k
    *source += 2;
1371
1.25k
    *len    -= 2;
1372
1.25k
  }
1373
4.53k
  return last_bom;
1374
4.53k
}
1375
1376
1.03k
#define FULLPOINT(f,s) ( (((f)&0x3ff)<<10) + ((s)&0x3ff) + 0x10000 )
1377
/* Remember: There's a limit at 0x1ffff. */
1378
396k
#define UTF8LEN(x) ( (x)<0x80 ? 1 : ((x)<0x800 ? 2 : ((x)<0x10000 ? 3 : 4)))
1379
static void convert_utf16bom(mpg123_string *sb, const unsigned char* s, size_t l, const int noquiet)
1380
4.53k
{
1381
4.53k
  size_t i;
1382
4.53k
  size_t n; /* number bytes that make up full pairs */
1383
4.53k
  unsigned char *p;
1384
4.53k
  size_t length = 0; /* the resulting UTF-8 length */
1385
  /* Determine real length... extreme case can be more than utf-16 length. */
1386
4.53k
  size_t high = 0;
1387
4.53k
  size_t low  = 1;
1388
4.53k
  int bom_endian;
1389
1390
4.53k
  debug1("convert_utf16 with length %lu", (unsigned long)l);
1391
1392
4.53k
  bom_endian = check_bom(&s, &l);
1393
4.53k
  debug1("UTF16 endianness check: %i", bom_endian);
1394
1395
4.53k
  if(bom_endian == -1) /* little-endian */
1396
638
  {
1397
638
    high = 1; /* The second byte is the high byte. */
1398
638
    low  = 0; /* The first byte is the low byte. */
1399
638
  }
1400
1401
4.53k
  n = (l/2)*2; /* number bytes that make up full pairs */
1402
1403
  /* first: get length, check for errors -- stop at first one */
1404
401k
  for(i=0; i < n; i+=2)
1405
397k
  {
1406
397k
    unsigned long point = ((unsigned long) s[i+high]<<8) + s[i+low];
1407
397k
    if((point & 0xfc00) == 0xd800) /* lead surrogate */
1408
932
    {
1409
932
      unsigned short second = (i+3 < l) ? (s[i+2+high]<<8) + s[i+2+low] : 0;
1410
932
      if((second & 0xfc00) == 0xdc00) /* good... */
1411
516
      {
1412
516
        point = FULLPOINT(point,second);
1413
516
        length += UTF8LEN(point); /* possibly 4 bytes */
1414
516
        i+=2; /* We overstepped one word. */
1415
516
      }
1416
416
      else /* if no valid pair, break here */
1417
416
      {
1418
416
        if(noquiet) error2("Invalid UTF16 surrogate pair at %li (0x%04lx).", (unsigned long)i, point);
1419
416
        n = i; /* Forget the half pair, END! */
1420
416
        break;
1421
416
      }
1422
932
    }
1423
396k
    else length += UTF8LEN(point); /* 1,2 or 3 bytes */
1424
397k
  }
1425
1426
4.53k
  if(!mpg123_grow_string(sb, length+1))
1427
0
    return;
1428
1429
  /* Now really convert, skip checks as these have been done just before. */
1430
4.53k
  p = (unsigned char*) sb->p; /* Signedness doesn't matter but it shows I thought about the non-issue */
1431
401k
  for(i=0; i < n; i+=2)
1432
396k
  {
1433
396k
    unsigned long codepoint = ((unsigned long) s[i+high]<<8) + s[i+low];
1434
396k
    if((codepoint & 0xfc00) == 0xd800) /* lead surrogate */
1435
516
    {
1436
516
      unsigned short second = (s[i+2+high]<<8) + s[i+2+low];
1437
516
      codepoint = FULLPOINT(codepoint,second);
1438
516
      i+=2; /* We overstepped one word. */
1439
516
    }
1440
396k
    if(codepoint < 0x80) *p++ = (unsigned char) codepoint;
1441
219k
    else if(codepoint < 0x800)
1442
28.0k
    {
1443
28.0k
      *p++ = (unsigned char) (0xc0 | (codepoint>>6));
1444
28.0k
      *p++ = (unsigned char) (0x80 | (codepoint & 0x3f));
1445
28.0k
    }
1446
191k
    else if(codepoint < 0x10000)
1447
190k
    {
1448
190k
      *p++ = (unsigned char) (0xe0 | (codepoint>>12));
1449
190k
      *p++ = 0x80 | ((codepoint>>6) & 0x3f);
1450
190k
      *p++ = 0x80 | (codepoint & 0x3f);
1451
190k
    }
1452
516
    else if (codepoint < 0x200000)
1453
516
    {
1454
516
      *p++ = (unsigned char) (0xf0 | codepoint>>18);
1455
516
      *p++ = (unsigned char) (0x80 | ((codepoint>>12) & 0x3f));
1456
516
      *p++ = (unsigned char) (0x80 | ((codepoint>>6) & 0x3f));
1457
516
      *p++ = (unsigned char) (0x80 | (codepoint & 0x3f));
1458
516
    } /* ignore bigger ones (that are not possible here anyway) */
1459
396k
  }
1460
4.53k
  sb->p[sb->size-1] = 0; /* paranoia... */
1461
4.53k
  sb->fill = sb->size;
1462
4.53k
}
1463
#undef UTF8LEN
1464
#undef FULLPOINT
1465
1466
static void convert_utf8(mpg123_string *sb, const unsigned char* source, size_t len, const int noquiet)
1467
3.70k
{
1468
3.70k
  if(mpg123_grow_string(sb, len+1))
1469
3.70k
  {
1470
3.70k
    memcpy(sb->p, source, len);
1471
3.70k
    sb->p[len] = 0;
1472
3.70k
    sb->fill = len+1;
1473
3.70k
  }
1474
3.70k
}
1475
1476
#endif