From be79b44dc873f7bff3bcdbb0353bb4036e140794 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Sat, 15 Jun 2019 13:59:22 +0200
Subject: [PATCH] archive/Lookup: pass const pointer

---
 src/archive/ArchiveLookup.cxx            | 13 +++++++------
 src/archive/ArchiveLookup.hxx            |  2 +-
 src/input/plugins/ArchiveInputPlugin.cxx | 12 ++----------
 test/test_archive.cxx                    | 24 ++++++------------------
 4 files changed, 16 insertions(+), 35 deletions(-)

diff --git a/src/archive/ArchiveLookup.cxx b/src/archive/ArchiveLookup.cxx
index f11247fa8..5ec0abcd2 100644
--- a/src/archive/ArchiveLookup.cxx
+++ b/src/archive/ArchiveLookup.cxx
@@ -35,16 +35,17 @@ FindSlash(PathTraitsFS::pointer_type p, size_t i) noexcept
 }
 
 ArchiveLookupResult
-archive_lookup(PathTraitsFS::pointer_type pathname)
+archive_lookup(PathTraitsFS::const_pointer_type pathname)
 {
-	size_t idx = strlen(pathname);
+	PathTraitsFS::string buffer(pathname);
+	size_t idx = buffer.size();
 
 	PathTraitsFS::pointer_type slash = nullptr;
 
 	while (true) {
 		try {
 			//try to stat if its real directory
-			const FileInfo file_info(Path::FromFS(pathname));
+			const FileInfo file_info(Path::FromFS(buffer.c_str()));
 
 			//is something found ins original path (is not an archive)
 			if (slash == nullptr)
@@ -53,7 +54,7 @@ archive_lookup(PathTraitsFS::pointer_type pathname)
 			//its a file ?
 			if (file_info.IsRegular()) {
 				//so the upper should be file
-				return {AllocatedPath::FromFS(pathname), AllocatedPath::FromFS(slash + 1)};
+				return {AllocatedPath::FromFS(buffer.c_str()), AllocatedPath::FromFS(slash + 1)};
 			} else {
 				return {};
 			}
@@ -66,12 +67,12 @@ archive_lookup(PathTraitsFS::pointer_type pathname)
 		if (slash != nullptr)
 			*slash = '/';
 
-		slash = FindSlash(pathname, idx - 1);
+		slash = FindSlash(&buffer.front(), idx - 1);
 		if (slash == nullptr)
 			return {};
 
 		*slash = 0;
-		idx = slash - pathname;
+		idx = slash - buffer.c_str();
 	}
 }
 
diff --git a/src/archive/ArchiveLookup.hxx b/src/archive/ArchiveLookup.hxx
index b49845c0c..567ca1bb4 100644
--- a/src/archive/ArchiveLookup.hxx
+++ b/src/archive/ArchiveLookup.hxx
@@ -50,7 +50,7 @@ struct ArchiveLookupResult {
  * Throws on error.
  */
 ArchiveLookupResult
-archive_lookup(PathTraitsFS::pointer_type pathname);
+archive_lookup(PathTraitsFS::const_pointer_type pathname);
 
 #endif
 
diff --git a/src/input/plugins/ArchiveInputPlugin.cxx b/src/input/plugins/ArchiveInputPlugin.cxx
index 2ed3b96ed..d4bf86544 100644
--- a/src/input/plugins/ArchiveInputPlugin.cxx
+++ b/src/input/plugins/ArchiveInputPlugin.cxx
@@ -25,30 +25,22 @@
 #include "../InputStream.hxx"
 #include "fs/Path.hxx"
 #include "Log.hxx"
-#include "util/ScopeExit.hxx"
-
-#include <string.h>
 
 InputStreamPtr
 OpenArchiveInputStream(Path path, Mutex &mutex)
 {
 	const ArchivePlugin *arplug;
 
-	char *pname = strdup(path.c_str());
-	AtScopeExit(pname) {
-		free(pname);
-	};
-
 	// archive_lookup will modify pname when true is returned
 	ArchiveLookupResult l;
 	try {
-		l = archive_lookup(pname);
+		l = archive_lookup(path.c_str());
 		if (l.archive.IsNull()) {
 			return nullptr;
 		}
 	} catch (...) {
 		LogFormat(LogLevel::DEBUG, std::current_exception(),
-			  "not an archive, lookup %s failed", pname);
+			  "not an archive, lookup %s failed", path.c_str());
 		return nullptr;
 	}
 
diff --git a/test/test_archive.cxx b/test/test_archive.cxx
index 6ae6a3450..ff3a93314 100644
--- a/test/test_archive.cxx
+++ b/test/test_archive.cxx
@@ -8,35 +8,23 @@
 
 TEST(ArchiveTest, Lookup)
 {
-	char *path = strdup("");
-	EXPECT_THROW(archive_lookup(path), std::system_error);
-	free(path);
+	EXPECT_THROW(archive_lookup(""), std::system_error);
 
-	path = strdup(".");
-	EXPECT_FALSE(archive_lookup(path));
-	free(path);
+	EXPECT_FALSE(archive_lookup("."));
 
-	path = strdup("config.h");
-	EXPECT_FALSE(archive_lookup(path));
-	free(path);
+	EXPECT_FALSE(archive_lookup("config.h"));
 
-	path = strdup("src/foo/bar");
-	EXPECT_THROW(archive_lookup(path), std::system_error);
-	free(path);
+	EXPECT_THROW(archive_lookup("src/foo/bar"), std::system_error);
 
 	fclose(fopen("dummy", "w"));
 
-	path = strdup("dummy/foo/bar");
-	auto result = archive_lookup(path);
+	auto result = archive_lookup("dummy/foo/bar");
 	EXPECT_TRUE(result);
 	EXPECT_STREQ(result.archive.c_str(), "dummy");
 	EXPECT_STREQ(result.inside.c_str(), "foo/bar");
-	free(path);
 
-	path = strdup("config.h/foo/bar");
-	result = archive_lookup(path);
+	result = archive_lookup("config.h/foo/bar");
 	EXPECT_TRUE(result);
 	EXPECT_STREQ(result.archive.c_str(), "config.h");
 	EXPECT_STREQ(result.inside.c_str(), "foo/bar");
-	free(path);
 }