[vlc-commits] [Git][videolan/vlc][master] 3 commits: skins2: parser: limit recursivity

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Thu Jul 16 08:33:43 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
e4fda8d6 by François Cartegnie at 2026-07-16T10:22:57+02:00
skins2: parser: limit recursivity

- - - - -
d8ba062b by François Cartegnie at 2026-07-16T10:22:57+02:00
skins2: parser: restrict subpath

- - - - -
2561bf79 by François Cartegnie at 2026-07-16T10:22:57+02:00
skins2: clean up failed extractions

- - - - -


3 changed files:

- modules/gui/skins2/parser/skin_parser.cpp
- modules/gui/skins2/parser/skin_parser.hpp
- modules/gui/skins2/src/theme_loader.cpp


Changes:

=====================================
modules/gui/skins2/parser/skin_parser.cpp
=====================================
@@ -26,9 +26,9 @@
 #include <math.h>
 
 SkinParser::SkinParser( intf_thread_t *pIntf, const std::string &rFileName,
-                        const std::string &rPath, BuilderData *pData ):
+                        const std::string &rPath, BuilderData *pData, unsigned instance ):
     XMLParser( pIntf, rFileName ), m_path( rPath ), m_pData( pData ),
-    m_ownData( pData == NULL ), m_xOffset( 0 ), m_yOffset( 0 )
+    m_ownData( pData == NULL ), m_xOffset( 0 ), m_yOffset( 0 ), m_instanceCount( instance )
 {
     // Make sure the data is allocated
     if( m_pData == NULL )
@@ -63,6 +63,30 @@ inline bool SkinParser::MissingAttr( AttrList_t &attr, const std::string &name,
     return false;
 }
 
+static bool isSubPath( const std::string &base, const std::string &path, const std::string &dirsep )
+{
+    char *baseReal = realpath( base.c_str(), NULL );
+    char *pathReal = realpath( path.c_str(), NULL );
+
+    if( !baseReal || !pathReal )
+    {
+        free( baseReal );
+        free( pathReal );
+        return false;
+    }
+
+    std::string basePath = baseReal;
+    std::string subPath = pathReal;
+    free( baseReal );
+    free( pathReal );
+
+    if( basePath.size() < dirsep.size() ||
+        basePath.compare( basePath.size() - dirsep.size(), dirsep.size(), dirsep ) )
+        basePath += dirsep;
+
+    return subPath.compare( 0, basePath.size(), basePath ) == 0;
+}
+
 void SkinParser::handleBeginElement( const std::string &rName, AttrList_t &attr )
 {
 #define RequireAttr( attr, name, a ) \
@@ -70,12 +94,24 @@ void SkinParser::handleBeginElement( const std::string &rName, AttrList_t &attr
 
     if( rName == "Include" )
     {
+        if( m_instanceCount >= 4 )
+        {
+            m_errors = true;
+            return;
+        }
         RequireAttr( attr, rName, "file" );
 
         OSFactory *pFactory = OSFactory::instance( getIntf() );
         std::string fullPath = m_path + pFactory->getDirSeparator() + attr["file"];
+        if( !isSubPath( m_path, fullPath, pFactory->getDirSeparator() ) )
+        {
+            msg_Err( getIntf(), "bad theme: Include escapes theme directory: %s",
+                     attr["file"] );
+            m_errors = true;
+            return;
+        }
         msg_Dbg( getIntf(), "opening included XML file: %s", fullPath.c_str() );
-        SkinParser subParser( getIntf(), fullPath.c_str(), m_path, m_pData );
+        SkinParser subParser( getIntf(), fullPath.c_str(), m_path, m_pData, m_instanceCount + 1 );
         subParser.parse();
     }
 


=====================================
modules/gui/skins2/parser/skin_parser.hpp
=====================================
@@ -43,7 +43,7 @@ public:
     };
 
     SkinParser( intf_thread_t *pIntf, const std::string &rFileName,
-                const std::string &rPath, BuilderData *pData = NULL );
+                const std::string &rPath, BuilderData *pData = NULL, unsigned = 0 );
     virtual ~SkinParser();
 
     const BuilderData &getData() const { return *m_pData; }
@@ -75,6 +75,8 @@ private:
     int m_curLayer;
     /// Set of used id
     std::set<std::string> m_idSet;
+    /// recursive depth control
+    unsigned m_instanceCount;
 
     /// Callbacks
     virtual void handleBeginElement( const std::string &rName,


=====================================
modules/gui/skins2/src/theme_loader.cpp
=====================================
@@ -114,6 +114,7 @@ bool ThemeLoader::extract( const std::string &fileName )
     if( unarchive( fileName, tempPath ) == false )
     {
         msg_Err( getIntf(), "extraction from %s failed", fileName.c_str() );
+        deleteTempFiles( tempPath );
         return false;
     }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b76155e974cd0a634e355129b9157683da8605bb...2561bf793a15cddc7c517bcc66fcd52e3e3faf4e

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b76155e974cd0a634e355129b9157683da8605bb...2561bf793a15cddc7c517bcc66fcd52e3e3faf4e
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list