This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-vfs.git


The following commit(s) were added to refs/heads/master by this push:
     new c5c168e01 [VFS-861] Http5FileProvider Basic authentication fails: 
UserAuthenticationData.setData(Type, char[]) should clone its array input
c5c168e01 is described below

commit c5c168e0138e8cdaeb423e7497bb19833c1925cb
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Mar 6 07:06:46 2026 -0500

    [VFS-861] Http5FileProvider Basic authentication fails:
    UserAuthenticationData.setData(Type, char[]) should clone its array
    input
    
    Refactor for reuse.
---
 .../vfs2/provider/webdav/WebdavFileProvider.java   | 11 +---
 .../vfs2/provider/ftp/FTPClientWrapper.java        | 15 ++---
 .../vfs2/provider/ftps/FtpsClientWrapper.java      |  7 +--
 .../vfs2/provider/http/HttpClientFactory.java      |  7 +--
 .../vfs2/provider/http/HttpFileProvider.java       |  8 +--
 .../vfs2/provider/http4/Http4FileProvider.java     | 13 ++---
 .../vfs2/provider/http5/Http5FileProvider.java     | 13 ++---
 .../vfs2/provider/sftp/SftpFileProvider.java       |  8 +--
 .../commons/vfs2/util/UserAuthenticatorUtils.java  | 67 ++++++++++++++++++++--
 9 files changed, 87 insertions(+), 62 deletions(-)

diff --git 
a/commons-vfs2-jackrabbit1/src/main/java/org/apache/commons/vfs2/provider/webdav/WebdavFileProvider.java
 
b/commons-vfs2-jackrabbit1/src/main/java/org/apache/commons/vfs2/provider/webdav/WebdavFileProvider.java
index 4e9b013a1..359fe6f52 100644
--- 
a/commons-vfs2-jackrabbit1/src/main/java/org/apache/commons/vfs2/provider/webdav/WebdavFileProvider.java
+++ 
b/commons-vfs2-jackrabbit1/src/main/java/org/apache/commons/vfs2/provider/webdav/WebdavFileProvider.java
@@ -21,8 +21,6 @@ import java.util.Collection;
 import java.util.Collections;
 
 import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.lang3.CharSequenceUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.vfs2.Capability;
 import org.apache.commons.vfs2.FileName;
 import org.apache.commons.vfs2.FileObject;
@@ -83,23 +81,18 @@ public class WebdavFileProvider extends HttpFileProvider {
         // Create the file system
         final GenericFileName rootName = (GenericFileName) name;
         final FileSystemOptions fsOpts = fileSystemOptions == null ? new 
FileSystemOptions() : fileSystemOptions;
-
         UserAuthenticationData authData = null;
         HttpClient httpClient;
         try {
             authData = UserAuthenticatorUtils.authenticate(fsOpts, 
AUTHENTICATOR_TYPES);
-
             httpClient = 
HttpClientFactory.createConnection(WebdavFileSystemConfigBuilder.getInstance(), 
"http",
                     rootName.getHostName(), rootName.getPort(),
-                    
StringUtils.valueOf(UserAuthenticatorUtils.getData(authData,
-                            UserAuthenticationData.USERNAME, 
CharSequenceUtils.toCharArray(rootName.getUserName()))),
-                    
StringUtils.valueOf(UserAuthenticatorUtils.getData(authData,
-                            UserAuthenticationData.PASSWORD, 
CharSequenceUtils.toCharArray(rootName.getPassword()))),
+                    UserAuthenticatorUtils.getUserName(rootName, authData),
+                    UserAuthenticatorUtils.getPassword(rootName, authData),
                     fsOpts);
         } finally {
             UserAuthenticatorUtils.cleanup(authData);
         }
-
         return new WebdavFileSystem(rootName, httpClient, fsOpts);
     }
 
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FTPClientWrapper.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FTPClientWrapper.java
index 604db2fe0..05dd3bc26 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FTPClientWrapper.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FTPClientWrapper.java
@@ -21,7 +21,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.time.Instant;
 
-import org.apache.commons.lang3.CharSequenceUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.net.ftp.FTPClient;
@@ -118,19 +117,17 @@ public class FTPClientWrapper implements FtpClient {
     /**
      * Creates an FTPClient.
      *
-     * @param rootFileName the root file name.
+     * @param rootName the root file name.
      * @param authData authentication data.
      * @return an FTPClient.
      * @throws FileSystemException if an error occurs while establishing a 
connection.
      */
-    protected FTPClient createClient(final GenericFileName rootFileName, final 
UserAuthenticationData authData)
+    protected FTPClient createClient(final GenericFileName rootName, final 
UserAuthenticationData authData)
         throws FileSystemException {
-        return FtpClientFactory.createConnection(rootFileName.getHostName(), 
rootFileName.getPort(),
-            UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.USERNAME,
-                CharSequenceUtils.toCharArray(rootFileName.getUserName())),
-            UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.PASSWORD,
-                CharSequenceUtils.toCharArray(rootFileName.getPassword())),
-            rootFileName.getPath(), getFileSystemOptions());
+        return FtpClientFactory.createConnection(rootName.getHostName(), 
rootName.getPort(),
+            UserAuthenticatorUtils.getUserNameChars(rootName, authData),
+            UserAuthenticatorUtils.getPasswordChars(rootName, authData),
+            rootName.getPath(), getFileSystemOptions());
     }
 
     @Override
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftps/FtpsClientWrapper.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftps/FtpsClientWrapper.java
index 12ae83522..c56747f80 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftps/FtpsClientWrapper.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftps/FtpsClientWrapper.java
@@ -16,7 +16,6 @@
  */
 package org.apache.commons.vfs2.provider.ftps;
 
-import org.apache.commons.lang3.CharSequenceUtils;
 import org.apache.commons.net.ftp.FTPClient;
 import org.apache.commons.net.ftp.FTPSClient;
 import org.apache.commons.vfs2.FileSystemException;
@@ -46,10 +45,8 @@ final class FtpsClientWrapper extends FTPClientWrapper {
     protected FTPClient createClient(final GenericFileName rootName, final 
UserAuthenticationData authData)
             throws FileSystemException {
         return FtpsClientFactory.createConnection(rootName.getHostName(), 
rootName.getPort(),
-                UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.USERNAME,
-                        CharSequenceUtils.toCharArray(rootName.getUserName())),
-                UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.PASSWORD,
-                        CharSequenceUtils.toCharArray(rootName.getPassword())),
+                UserAuthenticatorUtils.getUserNameChars(rootName, authData),
+                UserAuthenticatorUtils.getPasswordChars(rootName, authData),
                 rootName.getPath(), getFileSystemOptions());
     }
 }
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpClientFactory.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpClientFactory.java
index 02823ac3c..bdf563ffa 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpClientFactory.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpClientFactory.java
@@ -84,11 +84,8 @@ public final class HttpClientFactory {
 
                     if (authData != null) {
                         final UsernamePasswordCredentials proxyCreds = new 
UsernamePasswordCredentials(
-                            StringUtils.valueOf(
-                                UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.USERNAME, null)),
-                            StringUtils.valueOf(
-                                UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.PASSWORD, null)));
-
+                            UserAuthenticatorUtils.getUserName(null, authData),
+                            UserAuthenticatorUtils.getPassword(null, 
authData));
                         final AuthScope scope = new AuthScope(proxyHost, 
AuthScope.ANY_PORT);
                         client.getState().setProxyCredentials(scope, 
proxyCreds);
                     }
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpFileProvider.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpFileProvider.java
index 5af5ed504..acdf8406d 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpFileProvider.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http/HttpFileProvider.java
@@ -21,8 +21,6 @@ import java.util.Collection;
 import java.util.Collections;
 
 import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.lang3.CharSequenceUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.vfs2.Capability;
 import org.apache.commons.vfs2.FileName;
 import org.apache.commons.vfs2.FileSystem;
@@ -76,10 +74,8 @@ public class HttpFileProvider extends 
AbstractOriginatingFileProvider {
             final String internalScheme = lastChar == 's' || lastChar == 'S' ? 
"https" : "http";
             httpClient = HttpClientFactory.createConnection(internalScheme, 
rootName.getHostName(),
                     rootName.getPort(),
-                    
StringUtils.valueOf(UserAuthenticatorUtils.getData(authData,
-                            UserAuthenticationData.USERNAME, 
CharSequenceUtils.toCharArray(rootName.getUserName()))),
-                    
StringUtils.valueOf(UserAuthenticatorUtils.getData(authData,
-                            UserAuthenticationData.PASSWORD, 
CharSequenceUtils.toCharArray(rootName.getPassword()))),
+                    UserAuthenticatorUtils.getUserName(rootName, authData),
+                    UserAuthenticatorUtils.getPassword(rootName, authData),
                     fileSystemOptions);
         } finally {
             UserAuthenticatorUtils.cleanup(authData);
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java
index 6a64f0c2c..9b60ffffa 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java
@@ -33,7 +33,6 @@ import java.util.stream.Stream;
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
 
-import org.apache.commons.lang3.CharSequenceUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.time.DurationUtils;
 import org.apache.commons.vfs2.Capability;
@@ -239,13 +238,9 @@ public class Http4FileProvider extends 
AbstractOriginatingFileProvider {
         final HttpClientContext clientContext = HttpClientContext.create();
         final CredentialsProvider credsProvider = new 
BasicCredentialsProvider();
         clientContext.setCredentialsProvider(credsProvider);
-        final String rootUserName = rootName.getUserName();
-        final String userName = 
StringUtils.valueOf(UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.USERNAME,
-                rootUserName != null ? 
CharSequenceUtils.toCharArray(rootUserName) : null));
+        final String userName = UserAuthenticatorUtils.getUserName(rootName, 
authData);
         if (!StringUtils.isEmpty(userName)) {
-            final String rootPassword = rootName.getPassword();
-            final String password = 
StringUtils.valueOf(UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.PASSWORD,
-                    rootPassword != null ? 
CharSequenceUtils.toCharArray(rootPassword) : null));
+            final String password = 
UserAuthenticatorUtils.getPassword(rootName, authData);
             credsProvider.setCredentials(new AuthScope(rootName.getHostName(), 
rootName.getPort()), new UsernamePasswordCredentials(userName, password));
         }
         final HttpHost proxyHost = getProxyHttpHost(builder, 
fileSystemOptions);
@@ -256,8 +251,8 @@ public class Http4FileProvider extends 
AbstractOriginatingFileProvider {
                         new UserAuthenticationData.Type[] 
{UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD});
                 if (proxyAuthData != null) {
                     final UsernamePasswordCredentials proxyCreds = new 
UsernamePasswordCredentials(
-                            
StringUtils.valueOf(UserAuthenticatorUtils.getData(proxyAuthData, 
UserAuthenticationData.USERNAME, null)),
-                            
StringUtils.valueOf(UserAuthenticatorUtils.getData(proxyAuthData, 
UserAuthenticationData.PASSWORD, null)));
+                            UserAuthenticatorUtils.getUserName(null, authData),
+                            UserAuthenticatorUtils.getPassword(null, 
authData));
                     credsProvider.setCredentials(new 
AuthScope(proxyHost.getHostName(), proxyHost.getPort()), proxyCreds);
                 }
                 if (builder.isPreemptiveAuth(fileSystemOptions)) {
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http5/Http5FileProvider.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http5/Http5FileProvider.java
index 4ef767545..8465bf02c 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http5/Http5FileProvider.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http5/Http5FileProvider.java
@@ -34,7 +34,6 @@ import java.util.stream.Stream;
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
 
-import org.apache.commons.lang3.CharSequenceUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.vfs2.Capability;
 import org.apache.commons.vfs2.FileName;
@@ -230,13 +229,9 @@ public class Http5FileProvider extends 
AbstractOriginatingFileProvider {
         final HttpClientContext clientContext = HttpClientContext.create();
         final BasicCredentialsProvider credsProvider = new 
BasicCredentialsProvider();
         clientContext.setCredentialsProvider(credsProvider);
-        final String rootUser = rootName.getUserName();
-        final String userName = 
StringUtils.valueOf(UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.USERNAME,
-                rootUser != null ? CharSequenceUtils.toCharArray(rootUser) : 
null));
+        final String userName = UserAuthenticatorUtils.getUserName(rootName, 
authData);
         if (!StringUtils.isEmpty(userName)) {
-            final String rootPassword = rootName.getPassword();
-            final char[] password = UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.PASSWORD,
-                    rootPassword != null ? 
CharSequenceUtils.toCharArray(rootPassword) : null);
+            final char[] password = 
UserAuthenticatorUtils.getPasswordChars(rootName, authData);
             credsProvider.setCredentials(new AuthScope(rootName.getHostName(), 
rootName.getPort()),
                     new UsernamePasswordCredentials(userName, 
password.clone()));
         }
@@ -248,8 +243,8 @@ public class Http5FileProvider extends 
AbstractOriginatingFileProvider {
                         new UserAuthenticationData.Type[] 
{UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD});
                 if (proxyAuthData != null) {
                     final UsernamePasswordCredentials proxyCreds = new 
UsernamePasswordCredentials(
-                            
StringUtils.valueOf(UserAuthenticatorUtils.getData(proxyAuthData, 
UserAuthenticationData.USERNAME, null)),
-                            UserAuthenticatorUtils.getData(proxyAuthData, 
UserAuthenticationData.PASSWORD, null));
+                            UserAuthenticatorUtils.getUserName(null, authData),
+                            UserAuthenticatorUtils.getPassword(null, 
authData).toCharArray());
                     // set proxy host port
                     credsProvider.setCredentials(new 
AuthScope(proxyHost.getHostName(), proxyHost.getPort()), proxyCreds);
                 }
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileProvider.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileProvider.java
index 8e06b3967..5378967f4 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileProvider.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileProvider.java
@@ -20,7 +20,6 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
-import org.apache.commons.lang3.CharSequenceUtils;
 import org.apache.commons.vfs2.Capability;
 import org.apache.commons.vfs2.FileName;
 import org.apache.commons.vfs2.FileSystem;
@@ -61,12 +60,9 @@ public class SftpFileProvider extends 
AbstractOriginatingFileProvider {
         UserAuthenticationData authData = null;
         try {
             authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, 
AUTHENTICATOR_TYPES);
-
             return SftpClientFactory.createConnection(rootName.getHostName(), 
rootName.getPort(),
-                    UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.USERNAME,
-                            
CharSequenceUtils.toCharArray(rootName.getUserName())),
-                    UserAuthenticatorUtils.getData(authData, 
UserAuthenticationData.PASSWORD,
-                            
CharSequenceUtils.toCharArray(rootName.getPassword())),
+                    UserAuthenticatorUtils.getUserNameChars(rootName, 
authData),
+                    UserAuthenticatorUtils.getPasswordChars(rootName, 
authData),
                     fileSystemOptions);
         } catch (final Exception e) {
             throw new FileSystemException("vfs.provider.sftp/connect.error", 
rootName, e);
diff --git 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/UserAuthenticatorUtils.java
 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/UserAuthenticatorUtils.java
index cf4c62a89..5fa6add99 100644
--- 
a/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/UserAuthenticatorUtils.java
+++ 
b/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/UserAuthenticatorUtils.java
@@ -22,6 +22,7 @@ import org.apache.commons.vfs2.FileSystemOptions;
 import org.apache.commons.vfs2.UserAuthenticationData;
 import org.apache.commons.vfs2.UserAuthenticator;
 import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
+import org.apache.commons.vfs2.provider.GenericFileName;
 
 /**
  * Helps with authentication.
@@ -62,21 +63,79 @@ public final class UserAuthenticatorUtils {
         }
     }
 
+    private static String get(final String value, final UserAuthenticationData 
authData, final UserAuthenticationData.Type type) {
+        return StringUtils.valueOf(getData(authData, type, value != null ? 
CharSequenceUtils.toCharArray(value) : null));
+    }
+
     /**
      * Gets a copy of the data of a given type from the UserAuthenticationData 
or null if there is no data or data of this type available.
      *
      * @param data            The UserAuthenticationData.
      * @param type            The type of the element to retrieve.
-     * @param overrideValue The override value.
+     * @param override The override value.
      * @return The data of the given type as a character array or null if the 
data is not available.
+     * @see #getPassword(GenericFileName, UserAuthenticationData)
+     * @see #getPasswordChars(GenericFileName, UserAuthenticationData)
+     * @see #getUserName(GenericFileName, UserAuthenticationData)
+     * @see #getUserNameChars(GenericFileName, UserAuthenticationData)
      */
-    public static char[] getData(final UserAuthenticationData data, final 
UserAuthenticationData.Type type, final char[] overrideValue) {
-        if (overrideValue != null) {
-            return overrideValue;
+    public static char[] getData(final UserAuthenticationData data, final 
UserAuthenticationData.Type type, final char[] override) {
+        if (override != null) {
+            return override;
         }
         return data != null ? data.getData(type) : null;
     }
 
+    /**
+     * Gets the password from the UserAuthenticationData or from the root name 
if there is no password in the UserAuthenticationData.
+     *
+     * @param rootName The root name.
+     * @param authData The UserAuthenticationData.
+     * @return The password from the UserAuthenticationData or from the root 
name if there is no password in the UserAuthenticationData.
+     * @since 2.11.0
+     */
+    public static String getPassword(final GenericFileName rootName, final 
UserAuthenticationData authData) {
+        return get(rootName != null ? rootName.getPassword() : null, authData, 
UserAuthenticationData.PASSWORD);
+    }
+
+    /**
+     * Gets the password from the UserAuthenticationData or from the root name 
if there is no password in the UserAuthenticationData.
+     *
+     * @param rootName The root name.
+     * @param authData The UserAuthenticationData.
+     * @return The password from the UserAuthenticationData or from the root 
name if there is no password in the UserAuthenticationData.
+     * @since 2.11.0
+     */
+    public static char[] getPasswordChars(final GenericFileName rootName, 
final UserAuthenticationData authData) {
+        final String password = getPassword(rootName, authData);
+        return password != null ? password.toCharArray() : null;
+    }
+
+    /**
+     * Gets the user name from the UserAuthenticationData or from the root 
name if there is no user name in the UserAuthenticationData.
+     *
+     * @param rootName The root name.
+     * @param authData The UserAuthenticationData.
+     * @return The user name as a String or null if there is no user name in 
the UserAuthenticationData and the root name does not contain a user name.
+     * @since 2.11.0
+     */
+    public static String getUserName(final GenericFileName rootName, final 
UserAuthenticationData authData) {
+        return get(rootName != null ? rootName.getUserName() : null, authData, 
UserAuthenticationData.USERNAME);
+    }
+
+    /**
+     * Gets the user name from the UserAuthenticationData or from the root 
name if there is no user name in the UserAuthenticationData.
+     *
+     * @param rootName The root name.
+     * @param authData The UserAuthenticationData.
+     * @return The user name as a String or null if there is no user name in 
the UserAuthenticationData and the root name does not contain a user name.
+     * @since 2.11.0
+     */
+    public static char[] getUserNameChars(final GenericFileName rootName, 
final UserAuthenticationData authData) {
+        final String userName = getUserName(rootName, authData);
+        return userName != null ? userName.toCharArray() : null;
+    }
+
     /**
      * Converts a string to a char array (null-safe).
      *

Reply via email to