From 72255d580e23405375562160bf05fb55d3248f39 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Fri, 2 Jan 2009 10:48:11 +0100
Subject: mapper: allocate the result of map_uri_fs(), map_directory_fs()

Don't use fixed stack buffers.
---
 src/mapper.c        | 29 ++++++++++-------------------
 src/mapper.h        |  8 ++++----
 src/playlist_save.c | 12 ++++++++----
 src/update.c        | 28 ++++++++++++++++++----------
 4 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/src/mapper.c b/src/mapper.c
index 3777b7c62..6b0a7a449 100644
--- a/src/mapper.c
+++ b/src/mapper.c
@@ -89,53 +89,44 @@ void mapper_finish(void)
 	g_free(playlist_dir);
 }
 
-static char *
-rmp2amp_r(char *dst, const char *rel_path)
-{
-	pfx_dir(dst, rel_path, strlen(rel_path),
-		(const char *)music_dir, music_dir_length);
-	return dst;
-}
-
-const char *
-map_uri_fs(const char *uri, char *buffer)
+char *
+map_uri_fs(const char *uri)
 {
 	assert(uri != NULL);
 	assert(*uri != '/');
-	assert(buffer != NULL);
 
-	return rmp2amp_r(buffer, utf8_to_fs_charset(buffer, uri));
+	return g_build_filename(music_dir, uri, NULL);
 }
 
-const char *
-map_directory_fs(const struct directory *directory, char *buffer)
+char *
+map_directory_fs(const struct directory *directory)
 {
 	const char *dirname = directory_get_path(directory);
 	if (isRootDirectory(dirname))
-	    return music_dir;
+		return g_strdup(music_dir);
 
-	return map_uri_fs(dirname, buffer);
+	return map_uri_fs(dirname);
 }
 
 const char *
 map_directory_child_fs(const struct directory *directory, const char *name,
 		       char *buffer)
 {
-	char buffer2[MPD_PATH_MAX];
-	const char *parent_fs;
+	char *parent_fs;
 
 	/* check for invalid or unauthorized base names */
 	if (*name == 0 || strchr(name, '/') != NULL ||
 	    strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
 		return NULL;
 
-	parent_fs = map_directory_fs(directory, buffer2);
+	parent_fs = map_directory_fs(directory);
 	if (parent_fs == NULL)
 		return NULL;
 
 	name = utf8_to_fs_charset(buffer, name);
 	pfx_dir(buffer, name, strlen(name),
 		parent_fs, strlen(parent_fs));
+	g_free(parent_fs);
 	return buffer;
 }
 
diff --git a/src/mapper.h b/src/mapper.h
index 2f4ab353d..ee8d34dab 100644
--- a/src/mapper.h
+++ b/src/mapper.h
@@ -37,8 +37,8 @@ void mapper_finish(void);
  * is basically done by converting the URI to the file system charset
  * and prepending the music directory.
  */
-const char *
-map_uri_fs(const char *uri, char *buffer);
+char *
+map_uri_fs(const char *uri);
 
 /**
  * Determines the file system path of a directory object.
@@ -47,8 +47,8 @@ map_uri_fs(const char *uri, char *buffer);
  * @param a buffer which is MPD_PATH_MAX bytes long
  * @return the path in file system encoding, or NULL if mapping failed
  */
-const char *
-map_directory_fs(const struct directory *directory, char *buffer);
+char *
+map_directory_fs(const struct directory *directory);
 
 /**
  * Determines the file system path of a directory's child (may be a
diff --git a/src/playlist_save.c b/src/playlist_save.c
index b07137d9e..b6bc99369 100644
--- a/src/playlist_save.c
+++ b/src/playlist_save.c
@@ -24,6 +24,8 @@
 #include "ls.h"
 #include "database.h"
 
+#include <glib.h>
+
 void
 playlist_print_song(FILE *file, const struct song *song)
 {
@@ -44,14 +46,16 @@ void
 playlist_print_uri(FILE *file, const char *uri)
 {
 	char tmp[MPD_PATH_MAX];
-	const char *s;
+	char *s;
 
 	if (playlist_saveAbsolutePaths && !isRemoteUrl(uri) &&
 	    uri[0] != '/')
-		s = map_uri_fs(uri, tmp);
+		s = map_uri_fs(uri);
 	else
-		s = utf8_to_fs_charset(tmp, uri);
+		s = g_strdup(utf8_to_fs_charset(tmp, uri));
 
-	if (s != NULL)
+	if (s != NULL) {
 		fprintf(file, "%s\n", s);
+		g_free(s);
+	}
 }
diff --git a/src/update.c b/src/update.c
index 01fb76ddc..08360edd2 100644
--- a/src/update.c
+++ b/src/update.c
@@ -191,11 +191,16 @@ removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory)
 	struct delete_data data;
 
 	for (i = dv->nr; --i >= 0; ) {
-		const char *path_fs;
+		char *path_fs;
+		bool is_dir;
 
-		path_fs = map_directory_fs(dv->base[i], path_max_tmp);
-		if (path_fs == NULL ||
-		    !g_file_test(path_fs, G_FILE_TEST_IS_DIR))
+		path_fs = map_directory_fs(dv->base[i]);
+		if (path_fs == NULL)
+			continue;
+
+		is_dir = g_file_test(path_fs, G_FILE_TEST_IS_DIR);
+		g_free(path_fs);
+		if (!is_dir)
 			continue;
 		g_debug("removing directory: %s", dv->base[i]->path);
 		dirvec_delete(dv, dv->base[i]);
@@ -210,13 +215,15 @@ removeDeletedFromDirectory(char *path_max_tmp, struct directory *directory)
 static int
 stat_directory(const struct directory *directory, struct stat *st)
 {
-	char buffer[MPD_PATH_MAX];
-	const char *path_fs;
+	char *path_fs;
+	int ret;
 
-	path_fs = map_directory_fs(directory, buffer);
+	path_fs = map_directory_fs(directory);
 	if (path_fs == NULL)
 		return -1;
-	return stat(path_fs, st);
+	ret = stat(path_fs, st);
+	g_free(path_fs);
+	return ret;
 }
 
 static int
@@ -471,17 +478,18 @@ updateDirectory(struct directory *directory, const struct stat *st)
 	DIR *dir;
 	struct dirent *ent;
 	char path_max_tmp[MPD_PATH_MAX];
-	const char *path_fs;
+	char *path_fs;
 
 	assert(S_ISDIR(st->st_mode));
 
 	directory_set_stat(directory, st);
 
-	path_fs = map_directory_fs(directory, path_max_tmp);
+	path_fs = map_directory_fs(directory);
 	if (path_fs == NULL)
 		return false;
 
 	dir = opendir(path_fs);
+	g_free(path_fs);
 	if (!dir)
 		return false;
 
-- 
cgit v1.2.3