[vlc-commits] [Git][videolan/vlc][master] 4 commits: skiptags: separate the code to read the tag and skip data

Steve Lhomme (@robUx4) gitlab at videolan.org
Fri Apr 8 10:38:39 UTC 2022



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
7759e8e4 by Steve Lhomme at 2022-04-08T08:59:25+00:00
skiptags: separate the code to read the tag and skip data

- - - - -
8cfa465d by Steve Lhomme at 2022-04-08T08:59:25+00:00
skiptags: don't skip more than SSIZE_MAX at once

vlc_stream_Read() cannot return properly more than that.

- - - - -
4c06a11c by Steve Lhomme at 2022-04-08T08:59:25+00:00
skiptags: move the APE size constraint where it matters

The extra 32 octets are only needed if a certain flag is set.

The size constraint is on the max amount that GetDWLE can return which doesn't
have any limit in the specs:
https://mutagen-specs.readthedocs.io/en/latest/apev2/apev2.html

A different check on the size we actually allow to keep (MAX_TAG_SIZE) in
memory is done elsewhere and doesn't belong in the header size reporter.

- - - - -
225e0c1e by Steve Lhomme at 2022-04-08T08:59:25+00:00
skiptags: only check the extra footer size for APEv2

APEv1 should have flags set to 0 (no footer), but let's not assume writers set
this properly.

https://mutagen-specs.readthedocs.io/en/latest/apev2/apev2.html

- - - - -


1 changed file:

- modules/stream_filter/skiptags.c


Changes:

=====================================
modules/stream_filter/skiptags.c
=====================================
@@ -97,15 +97,20 @@ static uint_fast32_t SkipAPETag(stream_t *s)
         return 0;
 
     uint_fast32_t size = GetDWLE(peek + 12);
-    if (size > SSIZE_MAX - 32u)
-        return 0; /* impossibly long tag */
 
-    uint_fast32_t flags = GetDWLE(peek + 16);
-    if ((flags & (1u << 29)) == 0)
-        return 0;
+    if (version >= 2000)
+    {
+        uint_fast32_t flags = GetDWLE(peek + 16);
+        if ((flags & (1u << 29)) == 0)
+            return 0;
 
-    if (flags & (1u << 30))
-        size += 32;
+        if (flags & (1u << 30))
+        {
+            if (size > UINT32_MAX - 32u)
+                return 0; /* impossibly long tag */
+            size += 32;
+        }
+    }
 
     msg_Dbg(s, "AP2 v%"PRIuFAST32" tag found, "
             "skipping %"PRIuFAST32" bytes", version / 1000, size);
@@ -117,34 +122,53 @@ static bool SkipTag(stream_t *s, uint_fast32_t (*skipper)(stream_t *),
 {
     uint_fast64_t offset = vlc_stream_Tell(s);
     uint_fast32_t size = skipper(s);
-    if(size> 0)
+    if (size == 0)
+        return false;
+    if (*pi_tags_count < MAX_TAGS && size <= MAX_TAG_SIZE)
     {
-        /* Skip the entire tag */
-        ssize_t read;
-        if(*pi_tags_count < MAX_TAGS && size <= MAX_TAG_SIZE)
-        {
-            *pp_block = vlc_stream_Block(s, size);
-            read = *pp_block ? (ssize_t)(*pp_block)->i_buffer : -1;
+        *pp_block = vlc_stream_Block(s, size);
+        if (unlikely(!*pp_block))
+        {   /* I/O error, try to restore offset. If it fails, screwed. */
+            if (vlc_stream_Seek(s, offset))
+                msg_Err(s, "seek failure");
+            return false;
         }
-        else
+        if((*pp_block)->i_buffer < size)
         {
-            read = vlc_stream_Read(s, NULL, size);
+            // unexpected EOF, tag not fully read
+            block_ChainRelease(*pp_block);
+            *pp_block = NULL;
+            return false;
         }
+        (*pi_tags_count)++;
+        return true;
+    }
+
+    // Tag too big, skip the entire tag
+    while(size)
+    {
+        /* Skip the entire tag */
+#if SSIZE_MAX < UINT_FAST32_MAX
+        ssize_t skip = __MIN(size, SSIZE_MAX);
+#else
+        ssize_t skip = size;
+#endif
+        ssize_t read = vlc_stream_Read(s, NULL, skip);
 
-        if(read < (ssize_t)size)
+        if (unlikely(read < 0))
+        {   /* I/O error, try to restore offset. If it fails, screwed. */
+            if (vlc_stream_Seek(s, offset))
+                msg_Err(s, "seek failure");
+            return false;
+        }
+        if(read < skip)
         {
-            block_ChainRelease(*pp_block);
-            *pp_block = NULL;
-            if (unlikely(read < 0))
-            {   /* I/O error, try to restore offset. If it fails, screwed. */
-                if (vlc_stream_Seek(s, offset))
-                    msg_Err(s, "seek failure");
-                return false;
-            }
+            // unexpected EOF
+            return false;
         }
-        else (*pi_tags_count)++;
+        size -= read;
     }
-    return size != 0;
+    return true;
 }
 
 static ssize_t Read(stream_t *stream, void *buf, size_t buflen)



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/217857f033ce104a2115d00e32798f1837172f6f...225e0c1ee68da3aae0db80beb962af732ae4b1f1

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/217857f033ce104a2115d00e32798f1837172f6f...225e0c1ee68da3aae0db80beb962af732ae4b1f1
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list