Skip to content

m4a files - UnhandledPromiseRejectionWarning: EndOfStreamError: End-Of-Stream #2552

@dj-nuo

Description

@dj-nuo

Is there an existing issue for this?

  • I have searched the existing issues

music-metadata version

11.10.3

Current Behavior

I have .m4a file that caused music-metadata to crash with this error:

UnhandledPromiseRejectionWarning: EndOfStreamError: End-Of-Stream
    at FileTokenizer.readBuffer (file:///Users/aleksej/Downloads/minimal-mm/node_modules/strtok3/lib/FileTokenizer.js:33:19)
    at async FileTokenizer.readToken (file:///Users/aleksej/Downloads/minimal-mm/node_modules/strtok3/lib/AbstractTokenizer.js:32:21)
    at async file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/MP4Parser.js:372:40
    at async Atom.readAtom (file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/Atom.js:18:9)
    at async Atom.readAtoms (file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/Atom.js:36:30)
    at async Atom.readAtom (file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/Atom.js:18:9)
    at async Atom.readAtoms (file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/Atom.js:36:30)
    at async Atom.readAtom (file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/Atom.js:18:9)
    at async Atom.readAtoms (file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/Atom.js:36:30)
    at async Atom.readAtom (file:///Users/aleksej/Downloads/minimal-mm/node_modules/music-metadata/lib/mp4/Atom.js:18:9)

Here is the file: https://drive.google.com/file/d/1WCQHj4UTEP81tkkplLcGHbRmemA780Zi/view?usp=sharing

And here is the patch to fix the issue: music-metadata+11.10.3.patch

diff --git a/node_modules/music-metadata/lib/mp4/Atom.js b/node_modules/music-metadata/lib/mp4/Atom.js
index c940cf1..62c154a 100644
--- a/node_modules/music-metadata/lib/mp4/Atom.js
+++ b/node_modules/music-metadata/lib/mp4/Atom.js
@@ -33,9 +33,17 @@ export class Atom {
     }
     async readAtoms(tokenizer, dataHandler, size) {
         while (size > 0) {
-            const atomBean = await Atom.readAtom(tokenizer, dataHandler, this, size);
-            this.children.push(atomBean);
-            size -= atomBean.header.length === 0n ? size : Number(atomBean.header.length);
+            try {
+                const atomBean = await Atom.readAtom(tokenizer, dataHandler, this, size);
+                this.children.push(atomBean);
+                size -= atomBean.header.length === 0n ? size : Number(atomBean.header.length);
+            } catch (error) {
+                if (error.message && error.message.includes('End-Of-Stream')) {
+                    debug(`EndOfStreamError while parsing atoms in ${this.atomPath}, stopping atom parsing`);
+                    break;
+                }
+                throw error;
+            }
         }
     }
     async readData(tokenizer, dataHandler, remaining) {
diff --git a/node_modules/music-metadata/lib/mp4/MP4Parser.js b/node_modules/music-metadata/lib/mp4/MP4Parser.js
index 8296d9d..0fce56f 100644
--- a/node_modules/music-metadata/lib/mp4/MP4Parser.js
+++ b/node_modules/music-metadata/lib/mp4/MP4Parser.js
@@ -369,8 +369,17 @@ export class MP4Parser extends BasicParser {
                     break;
                 }
                 default: {
-                    const uint8Array = await this.tokenizer.readToken(new Token.Uint8ArrayType(payLoadLength));
-                    this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${textDecode(uint8Array, 'ascii')}`);
+                    try {
+                        const uint8Array = await this.tokenizer.readToken(new Token.Uint8ArrayType(payLoadLength));
+                        this.addWarning(`Unsupported meta-item: ${tagKey}[${child.header.name}] => value=${uint8ArrayToHex(uint8Array)} ascii=${textDecode(uint8Array, 'ascii')}`);
+                    } catch (error) {
+                        if (error.message && error.message.includes('End-Of-Stream')) {
+                            this.addWarning(`Skipping malformed meta-item: ${tagKey}[${child.header.name}], payload length ${payLoadLength} exceeds available data`);
+                            return; // Stop parsing this metadata item
+                        } else {
+                            throw error;
+                        }
+                    }
                 }
             }
         }, metaAtom.getPayloadLength(0));

(branched issue from #2546 )

Expected Behavior

No response

Attached audio sample?

  • I have provided sufficient information to reproduce the issue

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions