Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott J. Goldman <scottjgo@gmail.com>2012-05-10 10:45:55 +0400
committerScott J. Goldman <scottjgo@gmail.com>2012-05-12 20:51:32 +0400
commit6fb1c0b489c49b761eeddd655dd01e61d402722d (patch)
tree439eda0a4863656b4301280e2671d25c84994a04 /src/path.c
parentb1ec25facc4fe0cf7633e05f340e689c9f728ed0 (diff)
Fix readdir_r() usage for Solaris
On Solaris, struct dirent is defined differently than Linux. The field containing the path name is of size 0, rather than NAME_MAX. So, we need to use a properly sized buffer on Solaris to avoid a stack overflow. Also fix some DIR* leaks on cleanup.
Diffstat (limited to 'src/path.c')
-rw-r--r--src/path.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/path.c b/src/path.c
index 9f31676b1..84edf6d89 100644
--- a/src/path.c
+++ b/src/path.c
@@ -494,7 +494,7 @@ int git_path_direach(
{
ssize_t wd_len;
DIR *dir;
- struct dirent de_buf, *de;
+ struct dirent *de, *de_buf;
if (git_path_to_dir(path) < 0)
return -1;
@@ -506,14 +506,23 @@ int git_path_direach(
return -1;
}
- while (p_readdir_r(dir, &de_buf, &de) == 0 && de != NULL) {
+#ifdef __sun
+ de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1);
+#else
+ de_buf = git__malloc(sizeof(struct dirent));
+#endif
+
+ while (p_readdir_r(dir, de_buf, &de) == 0 && de != NULL) {
int result;
if (is_dot_or_dotdot(de->d_name))
continue;
- if (git_buf_puts(path, de->d_name) < 0)
+ if (git_buf_puts(path, de->d_name) < 0) {
+ closedir(dir);
+ git__free(de_buf);
return -1;
+ }
result = fn(arg, path);
@@ -521,11 +530,13 @@ int git_path_direach(
if (result < 0) {
closedir(dir);
+ git__free(de_buf);
return -1;
}
}
closedir(dir);
+ git__free(de_buf);
return 0;
}
@@ -537,7 +548,7 @@ int git_path_dirload(
{
int error, need_slash;
DIR *dir;
- struct dirent de_buf, *de;
+ struct dirent *de, *de_buf;
size_t path_len;
assert(path != NULL && contents != NULL);
@@ -549,11 +560,17 @@ int git_path_dirload(
return -1;
}
+#ifdef __sun
+ de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1);
+#else
+ de_buf = git__malloc(sizeof(struct dirent));
+#endif
+
path += prefix_len;
path_len -= prefix_len;
need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0;
- while ((error = p_readdir_r(dir, &de_buf, &de)) == 0 && de != NULL) {
+ while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) {
char *entry_path;
size_t entry_len;
@@ -573,11 +590,15 @@ int git_path_dirload(
memcpy(&entry_path[path_len + need_slash], de->d_name, entry_len);
entry_path[path_len + need_slash + entry_len] = '\0';
- if (git_vector_insert(contents, entry_path) < 0)
+ if (git_vector_insert(contents, entry_path) < 0) {
+ closedir(dir);
+ git__free(de_buf);
return -1;
+ }
}
closedir(dir);
+ git__free(de_buf);
if (error != 0)
giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path);