owntone / owntone-server

Linux/FreeBSD DAAP (iTunes) and MPD media server with support for AirPlay 1 and 2 speakers (multiroom), Apple Remote (and compatibles), Chromecast, Spotify and internet radio.
https://owntone.github.io/owntone-server
GNU General Public License v2.0
1.99k stars 227 forks source link

[scanner] Not retrieving the date field in the metadata of an audio file #1730

Closed hacketiwack closed 2 months ago

hacketiwack commented 2 months ago

Context I have a collection of audio files that are tagged with MusicBrainz Picard. When the album has a release date, the field date is populated by MusicBrainz Picard.

Current Situation However, this field (date) is then not visible in the date_released field of the database.

Below the dump of the ffprobe command on one of my audio file.

Input #0, mp3, from '1cbee2a6-2831-3812-86be-a1efe67483a6.mp3':
  Metadata:
    title           : The Ballad of Keenan Milton
    artist          : Devendra Banhart
    track           : 7/14
    album           : Mala
    disc            : 1/1
    genre           : Rock
    TMED            : CD
    MusicBrainz Release Group Id: af5aac96-5917-486a-8357-666ffe3b82f5
    TORY            : 2013
    MusicBrainz Release Track Id: 1cbee2a6-2831-3812-86be-a1efe67483a6
    publisher       : Nonesuch
    TSRC            : USNO11200497
    SCRIPT          : Latn
    album_artist    : Devendra Banhart
    ASIN            : B00B2QG42O
    TSO2            : Banhart, Devendra
    artist-sort     : Banhart, Devendra
    originalyear    : 2013
    CATALOGNUMBER   : 534452
    ARTISTS         : Devendra Banhart
    MusicBrainz Album Type: album
    MusicBrainz Album Status: official
    MusicBrainz Album Release Country: GB
    Acoustid Id     : e8c3e19d-8ef2-43ec-87d6-31083eff906e
    MusicBrainz Album Id: 89e5badb-7ef2-4d5f-899b-d3a195ce48f5
    MusicBrainz Artist Id: 0110e63e-0a9b-4818-af8e-41e180c20b9a
    MusicBrainz Album Artist Id: 0110e63e-0a9b-4818-af8e-41e180c20b9a
    date            : 2013-03-11
  Duration: 00:02:16.65, start: 0.025056, bitrate: 323 kb/s
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      encoder         : LAME3.99r
  Stream #0:1: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 500x435 [SAR 1:1 DAR 100:87], 90k tbr, 90k tbn (attached pic)
    Metadata:
      comment         : Cover (front)

Expected Situation The date field is populated in the date_released field of the database.

I hope I made myself clear.

ejurgensen commented 2 months ago

Seems to work ok for me, I get the expected result. Maybe something special about the file? Please send it to me.

hacketiwack commented 2 months ago

Thanks for your prompt reply @ejurgensen. I sent you an album having the issue.

ejurgensen commented 2 months ago

Still can't reproduce. The album you sent has date_released 2013-03-11, which looks to be correct.

hacketiwack commented 2 months ago

Thanks for trying out. Yes, that's the correct date. If I understand you correctly, when calling the API endpoint /api/library/albums/{album-id}, I should get the field date_released. I will try to rescan the library again.

ejurgensen commented 2 months ago

Instead of rescanning the entire lib you can use touch to force rescan of a particular file.

hacketiwack commented 2 months ago

Mmm... Still not working on my side.

I get the following result from the API:

{
  "id": "7907826001526965203",
  "name": "Mala",
  "name_sort": "Mala",
  "artist": "Devendra Banhart",
  "artist_id": "8892156411486014815",
  "track_count": 14,
  "length_ms": 2447248,
  "time_added": "2022-06-19T16:58:04Z",
  "in_progress": false,
  "media_kind": "music",
  "data_kind": "file",
  "year": 2013,
  "uri": "library:album:7907826001526965203",
  "artwork_url": "./artwork/group/37750"
}

If you have any other suggestion, please be my guest. But don't spend too much time on it for now.

ejurgensen commented 2 months ago

Weird. I get:

{ "id": "7907826001526965203", "name": "Mala", "name_sort": "Mala", "artist": "Devendra Banhart", "artist_id": "8892156411486014815", "track_count": 14, "length_ms": 2447248, "time_added": "2024-03-16T19:39:41Z", "in_progress": false, "media_kind": "music", "data_kind": "file", "date_released": "2013-03-11", "year": 2013, "uri": "library:album:7907826001526965203", "artwork_url": ".\/artwork\/group\/105" }

Did you check if the date is in the database?

hacketiwack commented 2 months ago

In the database, the information is not there. Each track of the album has the field date_released set to 0.

Then, I added the date_released manually with a SQL query to 1362960000.

Querying the API gives the following expected result:

{
  "id": "7907826001526965203",
  "name": "Mala",
  "name_sort": "Mala",
  "artist": "Devendra Banhart",
  "artist_id": "8892156411486014815",
  "track_count": 14,
  "length_ms": 2447248,
  "time_added": "2022-06-19T16:58:04Z",
  "in_progress": false,
  "media_kind": "music",
  "data_kind": "file",
  "date_released": "2013-03-11",
  "year": 2013,
  "uri": "library:album:7907826001526965203",
  "artwork_url": "./artwork/group/37750"
}

So there is definitely something weird during the scan.

Version of ffmpeg is:

ffmpeg version 6.0.1 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 12.2.1 (Alpine 12.2.1_git20220924-r10) 20220924

Not the latest though.

If I do probe the file with ffprobe I get the following, which sounds correct to me.

Input #0, mp3, from '1cbee2a6-2831-3812-86be-a1efe67483a6.mp3':
  Metadata:
    title           : The Ballad of Keenan Milton
    artist          : Devendra Banhart
    track           : 7/14
    album           : Mala
    disc            : 1/1
    genre           : Rock
    TMED            : CD
    MusicBrainz Release Group Id: af5aac96-5917-486a-8357-666ffe3b82f5
    TORY            : 2013
    MusicBrainz Release Track Id: 1cbee2a6-2831-3812-86be-a1efe67483a6
    publisher       : Nonesuch
    TSRC            : USNO11200497
    SCRIPT          : Latn
    album_artist    : Devendra Banhart
    ASIN            : B00B2QG42O
    TSO2            : Banhart, Devendra
    artist-sort     : Banhart, Devendra
    originalyear    : 2013
    CATALOGNUMBER   : 534452
    ARTISTS         : Devendra Banhart
    MusicBrainz Album Type: album
    MusicBrainz Album Status: official
    MusicBrainz Album Release Country: GB
    Acoustid Id     : e8c3e19d-8ef2-43ec-87d6-31083eff906e
    MusicBrainz Album Id: 89e5badb-7ef2-4d5f-899b-d3a195ce48f5
    MusicBrainz Artist Id: 0110e63e-0a9b-4818-af8e-41e180c20b9a
    MusicBrainz Album Artist Id: 0110e63e-0a9b-4818-af8e-41e180c20b9a
    date            : 2013-03-11
  Duration: 00:02:16.65, start: 0.025056, bitrate: 323 kb/s
  Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      encoder         : LAME3.99r
  Stream #0:1: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 500x435 [SAR 1:1 DAR 100:87], 90k tbr, 90k tbn (attached pic)
    Metadata:
      comment         : Cover (front)
ejurgensen commented 2 months ago

Try switching the if condition on line 334 to 1. Then all the metadata found should be dumped in the log.

ejurgensen commented 2 months ago

*Line 334 in filescanner_ffmpeg.c

hacketiwack commented 2 months ago

I will try that. Thanks. I'll keep you posted.

hacketiwack commented 2 months ago

Following your instructions, this is what I get in the logs:

[2024-03-19 09:40:16] [DEBUG]       db: Running query 'SELECT * FROM inotify WHERE wd = 3428;'
[2024-03-19 09:40:16] [DEBUG]     scan: File event: 0x00000004, cookie 0x00000000, wd 3428
[2024-03-19 09:40:16] [DEBUG]     scan: File attributes changed: /audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5/1cbee2a6-2831-3812-86be-a1efe67483a6.mp3
[2024-03-19 09:40:16] [DEBUG]       db: Running query 'SELECT f.id FROM files f WHERE f.path = '/audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5/1cbee2a6-2831-3812-86be-a1efe67483a6.mp3';'
[2024-03-19 09:40:16] [DEBUG]       db: Running query 'SELECT * FROM inotify WHERE wd = 3428;'
[2024-03-19 09:40:16] [DEBUG]     scan: File event: 0x00000008, cookie 0x00000000, wd 3428
[2024-03-19 09:40:16] [DEBUG]     scan: File closed: /audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5/1cbee2a6-2831-3812-86be-a1efe67483a6.mp3
[2024-03-19 09:40:16] [DEBUG]       db: Running query 'SELECT d.id FROM directories d WHERE d.virtual_path = '/file:/audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5';'
[2024-03-19 09:40:16] [DEBUG]       db: Running query 'UPDATE files SET db_timestamp = 1710841216, disabled = 0 WHERE path = '/audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5/1cbee2a6-2831-3812-86be-a1efe67483a6.mp3' AND db_timestamp >= 1710841216;'
[2024-03-19 09:40:16] [DEBUG]       db: Running query 'SELECT f.id FROM files f WHERE f.path = '/audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5/1cbee2a6-2831-3812-86be-a1efe67483a6.mp3';'
[2024-03-19 09:40:16] [DEBUG]   ffmpeg: Skipping 0 bytes of junk at 54083.
[2024-03-19 09:40:16] [DEBUG]     scan: File has 2 streams
[2024-03-19 09:40:16] [DEBUG]     scan: Found embedded artwork (stream 1)
[2024-03-19 09:40:16] [DEBUG]     scan: Duration 136646 ms, bitrate 323 kbps, samplerate 44100 channels 2
[2024-03-19 09:40:16] [DEBUG]     scan: MP3
[2024-03-19 09:40:16] [DEBUG]     scan:  -> title = The Ballad of Keenan Milton
[2024-03-19 09:40:16] [DEBUG]     scan:  -> artist = Devendra Banhart
[2024-03-19 09:40:16] [DEBUG]     scan:  -> track = 7/14
[2024-03-19 09:40:16] [DEBUG]     scan:  -> album = Mala
[2024-03-19 09:40:16] [DEBUG]     scan:  -> disc = 1/1
[2024-03-19 09:40:16] [DEBUG]     scan:  -> genre = Rock
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TMED = CD
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Release Group Id = af5aac96-5917-486a-8357-666ffe3b82f5
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TORY = 2013
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Release Track Id = 1cbee2a6-2831-3812-86be-a1efe67483a6
[2024-03-19 09:40:16] [DEBUG]     scan:  -> publisher = Nonesuch
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TSRC = USNO11200497
[2024-03-19 09:40:16] [DEBUG]     scan:  -> SCRIPT = Latn
[2024-03-19 09:40:16] [DEBUG]     scan:  -> album_artist = Devendra Banhart
[2024-03-19 09:40:16] [DEBUG]     scan:  -> ASIN = B00B2QG42O
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TSO2 = Banhart, Devendra
[2024-03-19 09:40:16] [DEBUG]     scan:  -> artist-sort = Banhart, Devendra
[2024-03-19 09:40:16] [DEBUG]     scan:  -> originalyear = 2013
[2024-03-19 09:40:16] [DEBUG]     scan:  -> CATALOGNUMBER = 534452
[2024-03-19 09:40:16] [DEBUG]     scan:  -> ARTISTS = Devendra Banhart
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Type = album
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Status = official
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Release Country = GB
[2024-03-19 09:40:16] [DEBUG]     scan:  -> Acoustid Id = e8c3e19d-8ef2-43ec-87d6-31083eff906e
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Id = 89e5badb-7ef2-4d5f-899b-d3a195ce48f5
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Artist Id = 0110e63e-0a9b-4818-af8e-41e180c20b9a
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Artist Id = 0110e63e-0a9b-4818-af8e-41e180c20b9a
[2024-03-19 09:40:16] [DEBUG]     scan:  -> date = 2013-03-11
[2024-03-19 09:40:16] [DEBUG]     scan: Picked up 1 tags from file metadata
[2024-03-19 09:40:16] [DEBUG]     scan: Picked up 0 tags from audio stream metadata
[2024-03-19 09:40:16] [DEBUG]     scan: Picked up 1 tags with extra md_map
[2024-03-19 09:40:16] [DEBUG]     scan:  -> title = The Ballad of Keenan Milton
[2024-03-19 09:40:16] [DEBUG]     scan:  -> artist = Devendra Banhart
[2024-03-19 09:40:16] [DEBUG]     scan:  -> track = 7/14
[2024-03-19 09:40:16] [DEBUG]     scan:  -> album = Mala
[2024-03-19 09:40:16] [DEBUG]     scan:  -> disc = 1/1
[2024-03-19 09:40:16] [DEBUG]     scan:  -> genre = Rock
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TMED = CD
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Release Group Id = af5aac96-5917-486a-8357-666ffe3b82f5
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TORY = 2013
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Release Track Id = 1cbee2a6-2831-3812-86be-a1efe67483a6
[2024-03-19 09:40:16] [DEBUG]     scan:  -> publisher = Nonesuch
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TSRC = USNO11200497
[2024-03-19 09:40:16] [DEBUG]     scan:  -> SCRIPT = Latn
[2024-03-19 09:40:16] [DEBUG]     scan:  -> album_artist = Devendra Banhart
[2024-03-19 09:40:16] [DEBUG]     scan:  -> ASIN = B00B2QG42O
[2024-03-19 09:40:16] [DEBUG]     scan:  -> TSO2 = Banhart, Devendra
[2024-03-19 09:40:16] [DEBUG]     scan:  -> artist-sort = Banhart, Devendra
[2024-03-19 09:40:16] [DEBUG]     scan:  -> originalyear = 2013
[2024-03-19 09:40:16] [DEBUG]     scan:  -> CATALOGNUMBER = 534452
[2024-03-19 09:40:16] [DEBUG]     scan:  -> ARTISTS = Devendra Banhart
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Type = album
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Status = official
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Release Country = GB
[2024-03-19 09:40:16] [DEBUG]     scan:  -> Acoustid Id = e8c3e19d-8ef2-43ec-87d6-31083eff906e
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Id = 89e5badb-7ef2-4d5f-899b-d3a195ce48f5
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Artist Id = 0110e63e-0a9b-4818-af8e-41e180c20b9a
[2024-03-19 09:40:16] [DEBUG]     scan:  -> MusicBrainz Album Artist Id = 0110e63e-0a9b-4818-af8e-41e180c20b9a
[2024-03-19 09:40:16] [DEBUG]     scan:  -> date = 2013-03-11
[2024-03-19 09:40:16] [DEBUG]     scan: Picked up 12 tags from file metadata
[2024-03-19 09:40:16] [DEBUG]     scan: Picked up 0 tags from audio stream metadata
[2024-03-19 09:40:16] [DEBUG]     scan: Picked up 12 tags with generic md_map, 13 tags total
[2024-03-19 09:40:16] [DEBUG]   ffmpeg: Statistics: 131072 bytes read, 0 seeks
[2024-03-19 09:40:16] [DEBUG]       db: Existing sort tag will be normalized: Banhart, Devendra
[2024-03-19 09:40:16] [DEBUG]       db: Existing sort tag will be normalized: Banhart, Devendra
[2024-03-19 09:40:16] [DEBUG]       db: Running query 'UPDATE files SET path = '/audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5/1cbee2a6-2831-3812-86be-a1efe67483a6.mp3', virtual_path = '/file:/audio/Music/8/9/89e5badb-7ef2-4d5f-899b-d3a195ce48f5/1cbee2a6-2831-3812-86be-a1efe67483a6.mp3', fname = '1cbee2a6-2831-3812-86be-a1efe67483a6.mp3', directory_id = 19963, title = 'The Ballad of Keenan Milton', artist = 'Devendra Banhart', album = 'Mala', album_artist = 'Devendra Banhart', genre = 'Rock', comment = NULL, type = 'mp3', composer = NULL, orchestra = NULL, conductor = NULL, grouping = NULL, url = NULL, bitrate = 323, samplerate = 44100, song_length = 136646, file_size = 5519944, year = 2013, date_released = 0, track = 7, total_tracks = 14, disc = 1, total_discs = 1, bpm = 0, compilation = 0, artwork = 2, rating = daap_no_zero(0, rating), play_count = daap_no_zero(0, play_count), skip_count = daap_no_zero(0, skip_count), seek = daap_no_zero(0, seek), data_kind = 0, media_kind = 1, item_kind = 2, description = 'MPEG audio file', db_timestamp = 1710841216, time_added = daap_no_zero(0, time_added), time_modified = 1710841216, time_played = daap_no_zero(0, time_played), time_skipped = daap_no_zero(0, time_skipped), disabled = 0, sample_count = 0, codectype = 'mpeg', idx = 0, has_video = 0, contentrating = 0, bits_per_sample = 32, tv_series_name = NULL, tv_episode_num_str = NULL, tv_network_name = NULL, tv_episode_sort = 0, tv_season_num = 0, songartistid = 8892156411486014815, songalbumid = 7907826001526965203, title_sort = 'Ballad of Keenan Milton', artist_sort = 'Banhart, Devendra', album_sort = 'Mala', album_artist_sort = 'Banhart, Devendra', composer_sort = NULL, channels = 2, usermark = 0, scan_kind = 1, lyrics = NULL WHERE id = 303268;'
[2024-03-19 09:40:21] [DEBUG]      lib: Database changed (1 changes)

It seems to be able to pick up the date, but then sets it to 0 in the update query. How is the string 2013-03-11 converted into an integer?

Thanks for your support.

ejurgensen commented 2 months ago

I wonder if it has something to do with locales. Can you try running this program? E.g. gcc -Wall -g parsedate.c -o parsedate && ./parsedate

#define _XOPEN_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <inttypes.h>
#include <limits.h>
#include <errno.h>
#include <time.h>

static int
safe_atou32(const char *str, uint32_t *val)
{
  char *end;
  unsigned long intval;

  if (str == NULL)
    return -1;

  errno = 0;
  intval = strtoul(str, &end, 10);

  if (((errno == ERANGE) && (intval == ULONG_MAX)) || ((errno != 0) && (intval == 0)))
    return -1;
  if (end == str)
    return -1;
  if (intval > UINT32_MAX)
    return -1;

  *val = (uint32_t)intval;
  return 0;
}

static int
parse_date(int64_t *date_released, uint32_t *year, const char *date_string)
{
  char year_string[32];
  struct tm tm = { 0 };
  int ret = 0;

  if ((*year == 0) && (safe_atou32(date_string, year) == 0))
    ret++;

  if ( strptime(date_string, "%FT%T%z", &tm) // ISO 8601, %F=%Y-%m-%d, %T=%H:%M:%S
       || strptime(date_string, "%F %T", &tm)
       || strptime(date_string, "%F %H:%M", &tm)
       || strptime(date_string, "%F", &tm)
     )
    {
      *date_released = mktime(&tm);
      ret++;
    }

  if ((*date_released == 0) && (*year != 0))
    {
      snprintf(year_string, sizeof(year_string), "%" PRIu32 "-01-01T12:00:00", *year);
      if (strptime(year_string, "%FT%T", &tm))
    {
      *date_released = mktime(&tm);
      ret++;
    }
    }

  return ret;
}

int
main()
{
  int64_t date_released = 0;
  uint32_t year = 0;
  int ret = parse_date(&date_released, &year, "2013-03-11");
  printf("ret = %d, date_released = %ld, year = %u\n", ret, date_released, year);

  return 0;
}
hacketiwack commented 2 months ago

Thanks for the small piece of code. Running parsedate returns ret = 1, date_released = 0, year = 2013.

Also, now that you're mentioning locale, what I've seen is that there is a message at the beginning of the build:

#7 9.258 * If you need ICU with non-English locales and legacy charset support, install
#7 9.258 * package icu-data-full.

Should I install icu-data-full in your opinion?

And as I'm looking at the build logs, I've got this message as well. Is that a potential problem for the future?

#7 76.60 library/filescanner_ffmpeg.c: In function 'extract_metadata_from_dict':
#7 76.60 library/filescanner_ffmpeg.c:336:15: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
#7 76.60   336 |   while ((mdt = av_dict_iterate(md, mdt)))
#7 76.60       |               ^
#7 76.62 library/filescanner_ffmpeg.c:336:17: warning: 'mdt' is used uninitialized [-Wuninitialized]
#7 76.62   336 |   while ((mdt = av_dict_iterate(md, mdt)))
#7 76.62       |                 ^~~~~~~~~~~~~~~~~~~~~~~~
#7 76.62 library/filescanner_ffmpeg.c:328:22: note: 'mdt' was declared here
#7 76.62   328 |   AVDictionaryEntry *mdt;
#7 76.62       |                      ^~~
ejurgensen commented 2 months ago

As far as I remember, ICU is an i8n library, and it's not used by the parser. As you can see, it just uses strptime and mktime. The result of your test strongly indicates that these function are affected by the locale, so you could try re-running the test program, but with the locale set to C or English. I'm don't remember precisely how to do that. Maybe try export LANG=C in a script that also runs the test program.

The other thing is just an error in the function you enabled to dump the tags. That wouldn't be causing the issue, but in any case I've fixed that now.

hacketiwack commented 2 months ago

I couldn't get the parsedate program to work. Even with export LANG=C.

However, I managed to get it work with a slightly different version of the code:

#define _XOPEN_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <inttypes.h>
#include <limits.h>
#include <errno.h>
#include <time.h>

static int
safe_atou32(const char *str, uint32_t *val)
{
  char *end;
  unsigned long intval;

  if (str == NULL)
    return -1;

  errno = 0;
  intval = strtoul(str, &end, 10);

  if (((errno == ERANGE) && (intval == ULONG_MAX)) || ((errno != 0) && (intval == 0)))
    return -1;
  if (end == str)
    return -1;
  if (intval > UINT32_MAX)
    return -1;

  *val = (uint32_t)intval;
  return 0;
}

int
parse_date(int64_t *date_released, uint32_t *year, const char *date_string)
{
  char year_string[32];
  struct tm tm = { 0 };
  int ret = 0;

  if ((*year == 0) && (safe_atou32(date_string, year) == 0))
    ret++;

  if (strptime(date_string, "%Y-%m-%d", &tm))
  {
    *date_released = mktime(&tm);
    ret++;
  }

  if ((*date_released == 0) && (*year != 0))
  {
    snprintf(year_string, sizeof(year_string), "%" PRIu32 "-01-01T12:00:00", *year);
    if (strptime(year_string, "%Y-%m-%dT%H:%M:%S", &tm))
    {
      *date_released = mktime(&tm);
      ret++;
    }
  }

  return ret;
}

int
main()
{
  int64_t date_released = 0;
  uint32_t year = 0;
  int ret = parse_date(&date_released, &year, "2013-03-11");
  printf("ret = %d, date_released = %ld, year = %u\n", ret, date_released, year);

  return 0;
}

Apparently, the strptime() function doesn't set all fields of the tm structure, so using mktime() on it might yield unexpected results.

ejurgensen commented 2 months ago

Apparently, the strptime() function doesn't set all fields of the tm structure, so using mktime() on it might yield unexpected results.

tm is zeroed in the declaration, so not sure how that can be a problem?

As you can see, date_released can be set in two ways (the two "if"), but since you have modified both ways it's ambiguous how your fix works. Can you isolate which change did the trick?

The docs for strptime say that for glibc "%F Equivalent to %Y-%m-%d, the ISO 8601 date format.", so I don't understand why the change you made of "%F" to "%Y-%m-%d" makes any difference. Unless your platform somehow isn't glibc and thus doesn't understand %F?

hacketiwack commented 2 months ago

Yes, you're right. I misinterpreted the code. I'll try to investigate further.

hacketiwack commented 2 months ago

Unless your platform somehow isn't glibc and thus doesn't understand %F?

You got the point here. As Alpine Linux is using musl, there is no %F available apparently. I will try to install gcompat to check if it corrects this incompatibility.

hacketiwack commented 2 months ago

Well, after thinking about it, installing gcompat won't work as I compile OwnTone in Alpine Linux and therefore, it is compiled with musl and not glibc. I guess, I'll have to compile glibc and compile OwnTone against it.

ejurgensen commented 2 months ago

No need for that, I'll just replace %F

hacketiwack commented 2 months ago

That's really nice of you. Thanks a lot.