aboutsummaryrefslogtreecommitdiffstats
path: root/src/directory_save.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-11-01 15:37:16 +0100
committerMax Kellermann <max@duempel.org>2009-11-01 15:37:16 +0100
commit9bcfd3a47da540abeb2da06471cf2fa11c14db49 (patch)
tree37cfca02bd797fe16329717d036c05dee07a147a /src/directory_save.c
parent451f932d80f5b695adb59e293391d17c9b996fb8 (diff)
downloadmpd-9bcfd3a47da540abeb2da06471cf2fa11c14db49.tar.gz
mpd-9bcfd3a47da540abeb2da06471cf2fa11c14db49.tar.xz
mpd-9bcfd3a47da540abeb2da06471cf2fa11c14db49.zip
text_file: allocate line buffers dynamically
Use a single GString buffer object in all functions loading the database. Enlarge it automatically for long lines. This eliminates the maximum line length for tag values. There is still an upper limit of 512 kB to prevent denial of service, but that's reasonable I guess.
Diffstat (limited to 'src/directory_save.c')
-rw-r--r--src/directory_save.c45
1 files changed, 23 insertions, 22 deletions
diff --git a/src/directory_save.c b/src/directory_save.c
index f353c7c2e..ed4f0190f 100644
--- a/src/directory_save.c
+++ b/src/directory_save.c
@@ -20,7 +20,7 @@
#include "directory_save.h"
#include "directory.h"
#include "song.h"
-#include "path.h"
+#include "text_file.h"
#include "song_save.h"
#include <assert.h>
@@ -80,10 +80,10 @@ directory_save(FILE *fp, struct directory *directory)
static struct directory *
directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
- GError **error_r)
+ GString *buffer, GError **error_r)
{
- char buffer[MPD_PATH_MAX * 2];
struct directory *directory;
+ const char *line;
bool success;
if (directory_get_child(parent, name) != NULL) {
@@ -101,19 +101,21 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
g_free(path);
}
- if (!fgets(buffer, sizeof(buffer), fp)) {
+ line = read_text_line(fp, buffer);
+ if (line == NULL) {
g_set_error(error_r, directory_quark(), 0,
"Unexpected end of file");
directory_free(directory);
return NULL;
}
- if (g_str_has_prefix(buffer, DIRECTORY_MTIME)) {
+ if (g_str_has_prefix(line, DIRECTORY_MTIME)) {
directory->mtime =
- g_ascii_strtoull(buffer + sizeof(DIRECTORY_MTIME) - 1,
+ g_ascii_strtoull(line + sizeof(DIRECTORY_MTIME) - 1,
NULL, 10);
- if (!fgets(buffer, sizeof(buffer), fp)) {
+ line = read_text_line(fp, buffer);
+ if (line == NULL) {
g_set_error(error_r, directory_quark(), 0,
"Unexpected end of file");
directory_free(directory);
@@ -121,14 +123,14 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
}
}
- if (!g_str_has_prefix(buffer, DIRECTORY_BEGIN)) {
+ if (!g_str_has_prefix(line, DIRECTORY_BEGIN)) {
g_set_error(error_r, directory_quark(), 0,
- "Malformed line: %s", buffer);
+ "Malformed line: %s", line);
directory_free(directory);
return NULL;
}
- success = directory_load(fp, directory, error_r);
+ success = directory_load(fp, directory, buffer, error_r);
if (!success) {
directory_free(directory);
return NULL;
@@ -138,32 +140,31 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
}
bool
-directory_load(FILE *fp, struct directory *directory, GError **error)
+directory_load(FILE *fp, struct directory *directory,
+ GString *buffer, GError **error)
{
- char buffer[MPD_PATH_MAX * 2];
+ const char *line;
bool success;
- while (fgets(buffer, sizeof(buffer), fp)
- && !g_str_has_prefix(buffer, DIRECTORY_END)) {
- g_strchomp(buffer);
-
- if (g_str_has_prefix(buffer, DIRECTORY_DIR)) {
+ while ((line = read_text_line(fp, buffer)) != NULL &&
+ !g_str_has_prefix(line, DIRECTORY_END)) {
+ if (g_str_has_prefix(line, DIRECTORY_DIR)) {
struct directory *subdir =
directory_load_subdir(fp, directory,
- buffer + sizeof(DIRECTORY_DIR) - 1,
- error);
+ line + sizeof(DIRECTORY_DIR) - 1,
+ buffer, error);
if (subdir == NULL)
return false;
dirvec_add(&directory->children, subdir);
- } else if (g_str_has_prefix(buffer, SONG_BEGIN)) {
+ } else if (g_str_has_prefix(line, SONG_BEGIN)) {
success = songvec_load(fp, &directory->songs,
- directory, error);
+ directory, buffer, error);
if (!success)
return false;
} else {
g_set_error(error, directory_quark(), 0,
- "Malformed line: %s", buffer);
+ "Malformed line: %s", line);
return false;
}
}