From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 4375C4B9AB for ; Sat, 1 Mar 2025 23:57:47 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 90C8768E215; Sun, 2 Mar 2025 01:57:43 +0200 (EET) Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id EB8F868E0C0 for ; Sun, 2 Mar 2025 01:57:36 +0200 (EET) Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-22113560c57so63449635ad.2 for ; Sat, 01 Mar 2025 15:57:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740873455; x=1741478255; darn=ffmpeg.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :message-id:from:from:to:cc:subject:date:message-id:reply-to; bh=ACGmaBxsike0p2M5inRKL/pZ3qIV1PL26KHkA3730jM=; b=KCy9s7/wyFW2ut/Co7NLWcqeri7gkntFKebk9mJPaZA3cWDU/qKaprFjPcbXaAAXp1 qlgC7gt/mSWaYzD5hMDUoYCQbxdCUgw+Q6fzO6hO7wwojTKm8wmgBkOJ1j/9BDWnnkXy ZBxfl82N9KELBvkLPO+H7MTBEzYBpmvPBqrtyP5v9XWhk3cjVYWKr5KuAn5Pe+TU/O/B hPPwa5+KadTC7Uw7c3JqX5hIMtEUKrAw2wO+ANYXG4U36XDDGlOl/naah3vJyvMryBwF W0B8S6NYuzSN0Os4aXFEp7qCmAoLy+VaIV4nidSUAdxsnx6lYovp/pyvsm0nwug86pCT pLUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740873455; x=1741478255; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :message-id:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ACGmaBxsike0p2M5inRKL/pZ3qIV1PL26KHkA3730jM=; b=exhVm1x9kq0ddoTSxGdNq9Izkys94re5bMo6SwQQhqyqt1wxEII5Z8VdM1vYyD4m9t qgEkRI+9E1y/IfZxUo1MNUx5sDD+bH+xBK4rMFf/EdKYGmFQiADFSl161C2pXCCNnpG0 qX/oRme6o7YI+2jBSJK01UPz8j8juAsfOPA/T+3+xT7oEbW4iqgWIvYKoiTJrxu28fZ2 PDba6PixtiP1qTpcdRO6nWkHWEI/1IRp1Npwg+HMaqil45nkak+bvinomHP7YJnS0Zh3 AEk4tU/s92/yEdgD8oXGY6rCZz7XGm+KbRWy+FGDj19FRxil6RpMRftWmU561wRq9ZP5 UUjQ== X-Gm-Message-State: AOJu0YwztG83XN4wubCBgGVPDLEU3ksA1R7KtlQCUIn9tS4shm8wJ/ae 6hl615M94UWJZFA51PjmthUqS0Nbu3HKs/8SuJRVQIU/k20AGhhRtwEjujv4 X-Gm-Gg: ASbGncuGlSvd8XB8RD3Co2txhtVyA+W5jUQKquq5SrRSPd86i1ol8NuuzdmatQzyn08 Ah9dSIBmrn6tX7YSMGhjgQ3iL54+dFkN+f36aEkavbK16FAcYQxqMhQ2/zSf7B+2WRldP3BoY6B Yw6coR1FdGZVSaHCvrPF1CU7Zvs5ZQ0tEu55eee+uyB0I6ywBiSFVmF5LKBbrO5EJJjq6dk/rOS U35TmcMhyqjljP6gEiO8iyKDWteA5jF99GWK/xoA3ab/m67a7Q2krf1RPKmCOep0EAL9T7P+ALQ HqqlUMMYtaAJac/Vs70xa4gdP93RuP3xmVlkE8AwFg23gljaFFumbpw6GfI40J8= X-Google-Smtp-Source: AGHT+IEPu5/1yJ+xuIEe2qf0VxidEzvc4pHAysQkmgJBv75bz9MWt42+xzK8JSFeD9AFAQ9/DJsz/A== X-Received: by 2002:a05:6a00:448b:b0:735:7bc0:dcda with SMTP id d2e1a72fcca58-7357bc0df07mr9349463b3a.5.1740873455069; Sat, 01 Mar 2025 15:57:35 -0800 (PST) Received: from [127.0.0.1] (master.gitmailbox.com. [34.83.118.50]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-734a0040091sm6283333b3a.147.2025.03.01.15.57.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 01 Mar 2025 15:57:34 -0800 (PST) From: softworkz X-Google-Original-From: softworkz Message-Id: Date: Sat, 01 Mar 2025 23:57:29 +0000 Fcc: Sent MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH] avformat/id3v2: Support null-separated multi-value properties X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: softworkz Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: From: softworkz Fixes Trac ticket https://trac.ffmpeg.org/ticket/6949 Signed-off-by: softworkz --- avformat/id3v2: Support null-separated multi-value properties Fixes Trac ticket https://trac.ffmpeg.org/ticket/6949 Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-54%2Fsoftworkz%2Fsubmit_id3v2-v1 Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-54/softworkz/submit_id3v2-v1 Pull-Request: https://github.com/ffstaging/FFmpeg/pull/54 libavformat/id3v2.c | 65 ++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 29ee59e1f4..cebb4acd75 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -327,39 +327,55 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, AVDictionary **metadata, const char *key) { uint8_t *dst; - int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL; + int encoding, nb_values = 0; unsigned genre; + AVDictionaryEntry *tag = NULL; if (taglen < 1) return; + tag = av_dict_get(*metadata, key, NULL, 0); + if (tag) + return; + encoding = avio_r8(pb); taglen--; /* account for encoding type byte */ - if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { - av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); - return; - } + /* Read all null-terminated values */ + while (taglen > 0) { + int n = 0, dict_flags = AV_DICT_APPEND | AV_DICT_DONT_STRDUP_VAL; - if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && - (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) && - genre <= ID3v1_GENRE_MAX) { - av_freep(&dst); - dst = av_strdup(ff_id3v1_genre_str[genre]); - } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { - /* dst now contains the key, need to get value */ - key = dst; if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); - av_freep(&key); return; } - dict_flags |= AV_DICT_DONT_STRDUP_KEY; - } else if (!*dst) - av_freep(&dst); - if (dst) - av_dict_set(metadata, key, dst, dict_flags); + if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && + (sscanf(dst, "(%d)", &genre) == 1 || (sscanf(dst, "%d%n", &genre, &n) == 1 && n == strlen(dst))) && + genre <= ID3v1_GENRE_MAX) { + av_freep(&dst); + dst = av_strdup(ff_id3v1_genre_str[genre]); + } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { + /* dst now contains the key, need to get value */ + key = dst; + if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { + av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); + av_freep(&key); + return; + } + } else if (!*dst) { + av_freep(&dst); + return; + } + + if (dst) { + if (nb_values > 0) + av_dict_set(metadata, key, ";", dict_flags & ~AV_DICT_DONT_STRDUP_VAL); + + av_dict_set(metadata, key, dst, dict_flags); + nb_values++; + } + } } static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, @@ -372,7 +388,7 @@ static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, int encoding; int ok = 0; - if (taglen < 4) + if (taglen < 1) goto error; encoding = avio_r8(pb); @@ -383,10 +399,10 @@ static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, lang[3] = '\0'; taglen -= 3; - if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0 || taglen < 0) + if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0) goto error; - if (decode_str(s, pb, encoding, &text, &taglen) < 0 || taglen < 0) + if (decode_str(s, pb, encoding, &text, &taglen) < 0) goto error; // FFmpeg does not support hierarchical metadata, so concatenate the keys. @@ -1003,7 +1019,8 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, t++; } - ffio_init_read_context(&pb_local, buffer, b - buffer); + ffio_init_context(&pb_local, buffer, b - buffer, 0, NULL, NULL, NULL, + NULL); tlen = b - buffer; pbx = &pb_local.pub; // read from sync buffer } @@ -1039,7 +1056,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err); goto seek; } - ffio_init_read_context(&pb_local, uncompressed_buffer, dlen); + ffio_init_context(&pb_local, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL); tlen = dlen; pbx = &pb_local.pub; // read from sync buffer } base-commit: 0e7c2a6287f977c30e08e2a211385c6a80614fe8 -- ffmpeg-codebot _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".