[vlc-commits] [Git][videolan/vlc][master] 3 commits: ftp: properly parse MLST facts

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Fri May 27 15:51:02 UTC 2022



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
c8713775 by Marvin Scholz at 2022-05-27T15:30:26+00:00
ftp: properly parse MLST facts

Fix #26046

- - - - -
400c92dd by Marvin Scholz at 2022-05-27T15:30:26+00:00
ftp: handle MLST size fact

- - - - -
87ef078c by Marvin Scholz at 2022-05-27T15:30:26+00:00
ftp: remove leftover debug output

- - - - -


1 changed file:

- modules/access/ftp.c


Changes:

=====================================
modules/access/ftp.c
=====================================
@@ -46,6 +46,7 @@
 #include <vlc_charset.h>
 #include <vlc_interrupt.h>
 #include <vlc_keystore.h>
+#include <vlc_strings.h>
 
 #ifndef IPPORT_FTP
 # define IPPORT_FTP 21u
@@ -909,6 +910,43 @@ static ssize_t Read( stream_t *p_access, void *p_buffer, size_t i_len )
     return i_read;
 }
 
+/**
+ * Parse MLST facts list
+ *
+ * Parses a MLST facts list (without the trailing space/filename)
+ * pointed to by linep and fills the key/value variables.
+ * If a not properly formatted fact is encountered, the
+ * whole fact value will be in key and val will be NULL.
+ *
+ * \note This function modifies the linep pointer, so
+ *       the original value for it must be saved to free
+ *       it once done.
+ * \retval false if at the end of the list
+ * \retval true  if there are more list items to process
+ */
+static bool mlst_facts_iter(char **linep, const char **key, const char **val)
+{
+    // MLST format parsed here is 'key=val;key=val...;'
+    // Lack of trailing ; at the end is accepted too, even though
+    // not permitted by the standard.
+    char *fact = strsep(linep, ";");
+    *key = NULL;
+    *val = NULL;
+
+    if (fact == NULL || fact[0] == '\0')
+        return false;
+
+    // Separate key and value
+    char *sep = strchr(fact, '=');
+    if (sep) {
+        *sep++ = '\0';
+    }
+    *key = fact;
+    *val = sep;
+
+    return true;
+}
+
 /*****************************************************************************
  * DirRead:
  *****************************************************************************/
@@ -927,6 +965,7 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_current_node)
     {
         char *psz_file;
         int type = ITEM_TYPE_UNKNOWN;
+        long long size = 0;
 
         char *psz_line = vlc_tls_GetLine( p_sys->data );
         if( psz_line == NULL )
@@ -934,22 +973,33 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_current_node)
 
         if( p_sys->features.b_mlst )
         {
-            /* MLST Format is key=val;key=val...; FILENAME */
-            if( strstr( psz_line, "type=dir" ) )
-                type = ITEM_TYPE_DIRECTORY;
-            if( strstr( psz_line, "type=file" ) )
-                type = ITEM_TYPE_FILE;
-
-            /* Get the filename or fail */
-            psz_file = strchr( psz_line, ' ' );
-            if( psz_file )
-                psz_file++;
-            else
-            {
-                msg_Warn( p_access, "Empty filename in MLST list" );
+            const char *key, *val;
+            char *facts = psz_line;
+
+            // Separate MLST and filename
+            psz_file = strchr(psz_line, ' ');
+            if (likely(psz_file)) {
+                *psz_file++ = '\0';
+            } else {
+                msg_Warn( p_access, "No filename in MLST list found" );
                 free( psz_line );
                 continue;
             }
+
+            while (mlst_facts_iter( &facts, &key, &val )) {
+                if (val == NULL) {
+                    msg_Warn( p_access, "Skipping invalid MLST fact '%s'", key);
+                    continue;
+                }
+                if (!vlc_ascii_strcasecmp( key, "type" )) {
+                    if (!vlc_ascii_strcasecmp( val, "dir" ))
+                        type = ITEM_TYPE_DIRECTORY;
+                    else if (!vlc_ascii_strcasecmp( val, "file" ))
+                        type = ITEM_TYPE_FILE;
+                } else if (!vlc_ascii_strcasecmp( key, "size" )) {
+                    size = atoll(val);
+                }
+            }
         }
         else
             psz_file = psz_line;
@@ -994,10 +1044,13 @@ static int DirRead (stream_t *p_access, input_item_node_t *p_current_node)
 
         if (likely(vlc_memstream_close(&ms) == 0))
         {
-            msg_Err(p_access, "%s -> %s", p_sys->url.psz_path, ms.ptr);
-
+            input_item_t *p_item;
             i_ret = vlc_readdir_helper_additem( &rdh, ms.ptr, NULL, psz_file,
-                                                type, ITEM_NET, NULL );
+                                                type, ITEM_NET, &p_item );
+
+            if (i_ret == VLC_SUCCESS && p_item && size > 0) {
+                input_item_AddStat(p_item, "size", size);
+            }
             free(ms.ptr);
         }
         free( psz_line );



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b001ee4658dee5d9926e522a14f25e566385da1b...87ef078ce8b256754107367b1d6ead86931ab9d6

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b001ee4658dee5d9926e522a14f25e566385da1b...87ef078ce8b256754107367b1d6ead86931ab9d6
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