[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/emms 0fe6100 28/80: Improve id3v2 error handling
From: |
Stefan Monnier |
Subject: |
[elpa] externals/emms 0fe6100 28/80: Improve id3v2 error handling |
Date: |
Wed, 17 Mar 2021 18:42:24 -0400 (EDT) |
branch: externals/emms
commit 0fe61009c5e00790a180e13021050f92b0916cd0
Author: Petteri Hintsanen <petterih@iki.fi>
Commit: Petteri Hintsanen <petterih@iki.fi>
Improve id3v2 error handling
- Allow zero-sized frames; in practice they mean start of padding.
- Do not try to read frame headers going over tag boundary. These
cases also mean start of padding in practice.
- Return nil from emms-info-native--decode-id3v2 in case of
errors *or* if there were no useful metadata.
---
emms-info-native.el | 92 +++++++++++++++++++++++++++++------------------------
1 file changed, 51 insertions(+), 41 deletions(-)
diff --git a/emms-info-native.el b/emms-info-native.el
index ab5b6c0..039738c 100644
--- a/emms-info-native.el
+++ b/emms-info-native.el
@@ -564,20 +564,26 @@ outside itself.")
(defun emms-info-native--decode-id3v2 (filename)
"Read and decode id3v2 metadata from FILENAME.
-Return metadata in a list of (FIELD . VALUE) cons cells."
- (let* (emms-info-native--id3v2-version
- (header (emms-info-native--decode-id3v2-header filename))
- (tag-size (bindat-get-field header 'size))
- (unsync (memq 7 (bindat-get-field header 'flags)))
- (offset 10))
- (when (memq 6 (bindat-get-field header 'flags))
- ;; Skip the extended header.
- (cl-incf offset
- (emms-info-native--decode-id3v2-ext-header-size filename)))
- (emms-info-native--decode-id3v2-frames filename
- offset
- (+ tag-size 10)
- unsync)))
+Return metadata in a list of (FIELD . VALUE) cons cells, or nil
+in case of errors or if there were no known fields in FILENAME.
+
+See ‘emms-info-native--id3v2-frame-to-info’ for recognized
+fields."
+ (condition-case-unless-debug nil
+ (let* (emms-info-native--id3v2-version
+ (header (emms-info-native--decode-id3v2-header filename))
+ (tag-size (bindat-get-field header 'size))
+ (unsync (memq 7 (bindat-get-field header 'flags)))
+ (offset 10))
+ (when (memq 6 (bindat-get-field header 'flags))
+ ;; Skip the extended header.
+ (cl-incf offset
+ (emms-info-native--decode-id3v2-ext-header-size filename)))
+ (emms-info-native--decode-id3v2-frames filename
+ offset
+ (+ tag-size 10)
+ unsync))
+ (error nil)))
(defun emms-info-native--decode-id3v2-header (filename)
"Read and decode id3v2 header from FILENAME."
@@ -594,7 +600,7 @@ Return the size. Signal an error if the size exceeds
(with-temp-buffer
(set-buffer-multibyte nil)
(insert-file-contents-literally filename nil 10 14)
- (emms-info-native--checked-id3v2-size (buffer-string))))
+ (emms-info-native--checked-id3v2-size 'frame (buffer-string))))
(defun emms-info-native--checked-id3v2-size (elt bytes)
"Calculate id3v2 element ELT size from BYTES.
@@ -607,7 +613,7 @@ Return the size."
(if (= emms-info-native--id3v2-version 4)
(setq size (emms-info-native--decode-id3v2-size bytes t))
(setq size (emms-info-native--decode-id3v2-size bytes nil)))))
- (when (or (= size 0) (> size emms-info-native--max-peek-size))
+ (when (> size emms-info-native--max-peek-size)
(error "id3v2 tag or frame size %s is invalid" size))
size))
@@ -633,30 +639,34 @@ unsynchronization and decoded as such.
Return metadata in a list of (FIELD . VALUE) cons cells."
(let ((offset begin)
+ (limit (- end (emms-info-native--id3v2-frame-header-size)))
comments)
- (condition-case nil
- (while (< offset end)
- (let* ((header (emms-info-native--decode-id3v2-frame-header filename
- offset))
- (info-id (emms-info-native--id3v2-frame-info-id header))
- (decoded-size (bindat-get-field (cdr header) 'size)))
- (setq offset (car header)) ;advance to frame data begin
- (if (or unsync info-id)
- ;; Note that if unsync is t, we have to always read a
- ;; frame to gets its true size so that we can adjust
- ;; offset correctly.
- (let ((data (emms-info-native--read-id3v2-frame-data filename
- offset
-
decoded-size
- unsync)))
- (setq offset (car data))
- (when info-id
- (let ((value (emms-info-native--decode-id3v2-string (cdr
data))))
- (push (cons info-id value) comments))))
- ;; Skip the frame.
- (cl-incf offset decoded-size))))
- (error nil))
- comments))
+ (catch 'eof
+ (while (< offset limit)
+ (let* ((header (emms-info-native--decode-id3v2-frame-header filename
+ offset))
+ (info-id (emms-info-native--id3v2-frame-info-id header))
+ (decoded-size (bindat-get-field (cdr header) 'size)))
+ (when (= decoded-size 0) (throw 'eof t))
+ (setq offset (car header)) ;advance to frame data begin
+ (if (or unsync info-id)
+ ;; Note that if unsync is t, we have to always read a
+ ;; frame to gets its true size so that we can adjust
+ ;; offset correctly.
+ (let ((data (emms-info-native--read-id3v2-frame-data filename
+ offset
+ decoded-size
+ unsync)))
+ (setq offset (car data))
+ (when info-id
+ (let ((value (emms-info-native--decode-id3v2-string (cdr
data))))
+ (push (cons info-id value) comments))))
+ ;; Skip the frame.
+ (cl-incf offset decoded-size)))))
+ comments))
+
+(defun emms-info-native--id3v2-frame-header-size ()
+ (if (= emms-info-native--id3v2-version 2) 6 10))
(defun emms-info-native--decode-id3v2-frame-header (filename begin)
"Read and decode id3v2 frame header from FILENAME.
@@ -666,7 +676,7 @@ Return a cons cell (OFFSET . FRAME), where OFFSET is the
byte
offset after the frame header, and FRAME is the decoded frame."
(with-temp-buffer
(set-buffer-multibyte nil)
- (let ((end (+ begin (if (= emms-info-native--id3v2-version 2) 6 10))))
+ (let ((end (+ begin (emms-info-native--id3v2-frame-header-size))))
(insert-file-contents-literally filename nil begin end)
(cons end (bindat-unpack emms-info-native--id3v2-frame-header-bindat-spec
(buffer-string))))))
@@ -690,7 +700,7 @@ data."
(let ((peek-end (+ begin (* 2 num-bytes)))
(end num-bytes))
(insert-file-contents-literally filename nil begin peek-end)
- (beginning-of-buffer)
+ (goto-char (point-min))
(while (and (re-search-forward (string 255 0) nil t)
(< (point) end))
(replace-match (string 255))
- [elpa] externals/emms e89bc15 26/80: Merge branch 'info-native', (continued)
- [elpa] externals/emms e89bc15 26/80: Merge branch 'info-native', Stefan Monnier, 2021/03/17
- [elpa] externals/emms fa8f64e 33/80: Fix whitespace trimming, Stefan Monnier, 2021/03/17
- [elpa] externals/emms 5aea8e7 35/80: Fix id3v2 frame id to info-field mapping, Stefan Monnier, 2021/03/17
- [elpa] externals/emms f9f2bab 30/80: Trim trailing whitespace from id3v2 strings, Stefan Monnier, 2021/03/17
- [elpa] externals/emms 60c9304 32/80: Trim trailing whitespace from all info-fields, Stefan Monnier, 2021/03/17
- [elpa] externals/emms 6e5d477 21/80: Simplify FLAC code, Stefan Monnier, 2021/03/17
- [elpa] externals/emms 757043b 41/80: Merge branch 'info-native', Stefan Monnier, 2021/03/17
- [elpa] externals/emms 7479d7d 19/80: Use lexical binding, Stefan Monnier, 2021/03/17
- [elpa] externals/emms a372976 20/80: Fix Opus channel mapping decoding, Stefan Monnier, 2021/03/17
- [elpa] externals/emms 4a4a358 23/80: Remove emms-info-native return value, Stefan Monnier, 2021/03/17
- [elpa] externals/emms 0fe6100 28/80: Improve id3v2 error handling,
Stefan Monnier <=
- [elpa] externals/emms cd437ca 40/80: Fix byte compilation, Stefan Monnier, 2021/03/17
- [elpa] externals/emms a57cc7e 43/80: * emms-bookmarks.el: lexical scoping declaration, Stefan Monnier, 2021/03/17
- [elpa] externals/emms fcdb111 25/80: Add mappings for more id3v2 text frames, Stefan Monnier, 2021/03/17
- [elpa] externals/emms c8f198d 31/80: Put some id3v2.4 frame data to info-date instead of info-year, Stefan Monnier, 2021/03/17
- [elpa] externals/emms b7684ba 39/80: Match id3v1 genres in id3v2.4 frame, Stefan Monnier, 2021/03/17
- [elpa] externals/emms d12014d 50/80: * emms-i18n.el: lexical declaration, Stefan Monnier, 2021/03/17
- [elpa] externals/emms abf6b01 49/80: * emms-history.el: lexical declaration, Stefan Monnier, 2021/03/17
- [elpa] externals/emms 0fcea44 52/80: * emms-info.el: add lexical and remove unused lexical variable, Stefan Monnier, 2021/03/17
- [elpa] externals/emms ba16ff6 13/80: * emms-tag-editor.el: lexical compatibility work, Stefan Monnier, 2021/03/17
- [elpa] externals/emms bf22384 16/80: Clean up Vorbis code, Stefan Monnier, 2021/03/17