Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 49dc2cc

Browse files
René Scharfegitster
authored andcommitted
dir: convert to strbuf
The functions read_directory_recursive() and treat_leading_path() both use buffers sized to fit PATH_MAX characters. The latter can be made to overrun its buffer, e.g. like this: $ a=0123456789abcdef $ a=$a$a$a$a$a$a$a$a $ a=$a$a$a$a$a$a$a$a $ a=$a$a$a$a$a$a$a$a $ git add $a/a Instead of trying to add a check and potentionally forgetting to address similar cases, convert the involved functions and their helpers to use struct strbuf. The patch is suprisingly large because the helpers treat_path() and treat_one_path() modify the buffer as well and thus need to be converted, too. Signed-off-by: Rene Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f174a25 commit 49dc2cc

File tree

1 file changed

+36
-39
lines changed

1 file changed

+36
-39
lines changed

dir.c

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -866,14 +866,14 @@ enum path_treatment {
866866
};
867867

868868
static enum path_treatment treat_one_path(struct dir_struct *dir,
869-
char *path, int *len,
869+
struct strbuf *path,
870870
const struct path_simplify *simplify,
871871
int dtype, struct dirent *de)
872872
{
873-
int exclude = excluded(dir, path, &dtype);
873+
int exclude = excluded(dir, path->buf, &dtype);
874874
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
875-
&& exclude_matches_pathspec(path, *len, simplify))
876-
dir_add_ignored(dir, path, *len);
875+
&& exclude_matches_pathspec(path->buf, path->len, simplify))
876+
dir_add_ignored(dir, path->buf, path->len);
877877

878878
/*
879879
* Excluded? If we don't explicitly want to show
@@ -883,7 +883,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
883883
return path_ignored;
884884

885885
if (dtype == DT_UNKNOWN)
886-
dtype = get_dtype(de, path, *len);
886+
dtype = get_dtype(de, path->buf, path->len);
887887

888888
/*
889889
* Do we want to see just the ignored files?
@@ -900,9 +900,8 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
900900
default:
901901
return path_ignored;
902902
case DT_DIR:
903-
memcpy(path + *len, "/", 2);
904-
(*len)++;
905-
switch (treat_directory(dir, path, *len, simplify)) {
903+
strbuf_addch(path, '/');
904+
switch (treat_directory(dir, path->buf, path->len, simplify)) {
906905
case show_directory:
907906
if (exclude != !!(dir->flags
908907
& DIR_SHOW_IGNORED))
@@ -923,26 +922,21 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
923922

924923
static enum path_treatment treat_path(struct dir_struct *dir,
925924
struct dirent *de,
926-
char *path, int path_max,
925+
struct strbuf *path,
927926
int baselen,
928-
const struct path_simplify *simplify,
929-
int *len)
927+
const struct path_simplify *simplify)
930928
{
931929
int dtype;
932930

933931
if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
934932
return path_ignored;
935-
*len = strlen(de->d_name);
936-
/* Ignore overly long pathnames! */
937-
if (*len + baselen + 8 > path_max)
938-
return path_ignored;
939-
memcpy(path + baselen, de->d_name, *len + 1);
940-
*len += baselen;
941-
if (simplify_away(path, *len, simplify))
933+
strbuf_setlen(path, baselen);
934+
strbuf_addstr(path, de->d_name);
935+
if (simplify_away(path->buf, path->len, simplify))
942936
return path_ignored;
943937

944938
dtype = DTYPE(de);
945-
return treat_one_path(dir, path, len, simplify, dtype, de);
939+
return treat_one_path(dir, path, simplify, dtype, de);
946940
}
947941

948942
/*
@@ -964,16 +958,15 @@ static int read_directory_recursive(struct dir_struct *dir,
964958

965959
if (fdir) {
966960
struct dirent *de;
967-
char path[PATH_MAX + 1];
968-
memcpy(path, base, baselen);
961+
struct strbuf path = STRBUF_INIT;
962+
963+
strbuf_add(&path, base, baselen);
969964

970965
while ((de = readdir(fdir)) != NULL) {
971-
int len;
972-
switch (treat_path(dir, de, path, sizeof(path),
973-
baselen, simplify, &len)) {
966+
switch (treat_path(dir, de, &path, baselen, simplify)) {
974967
case path_recurse:
975968
contents += read_directory_recursive
976-
(dir, path, len, 0, simplify);
969+
(dir, path.buf, path.len, 0, simplify);
977970
continue;
978971
case path_ignored:
979972
continue;
@@ -984,10 +977,11 @@ static int read_directory_recursive(struct dir_struct *dir,
984977
if (check_only)
985978
goto exit_early;
986979
else
987-
dir_add_name(dir, path, len);
980+
dir_add_name(dir, path.buf, path.len);
988981
}
989982
exit_early:
990983
closedir(fdir);
984+
strbuf_release(&path);
991985
}
992986

993987
return contents;
@@ -1051,8 +1045,8 @@ static int treat_leading_path(struct dir_struct *dir,
10511045
const char *path, int len,
10521046
const struct path_simplify *simplify)
10531047
{
1054-
char pathbuf[PATH_MAX];
1055-
int baselen, blen;
1048+
struct strbuf sb = STRBUF_INIT;
1049+
int baselen, rc = 0;
10561050
const char *cp;
10571051

10581052
while (len && path[len - 1] == '/')
@@ -1067,19 +1061,22 @@ static int treat_leading_path(struct dir_struct *dir,
10671061
baselen = len;
10681062
else
10691063
baselen = cp - path;
1070-
memcpy(pathbuf, path, baselen);
1071-
pathbuf[baselen] = '\0';
1072-
if (!is_directory(pathbuf))
1073-
return 0;
1074-
if (simplify_away(pathbuf, baselen, simplify))
1075-
return 0;
1076-
blen = baselen;
1077-
if (treat_one_path(dir, pathbuf, &blen, simplify,
1064+
strbuf_setlen(&sb, 0);
1065+
strbuf_add(&sb, path, baselen);
1066+
if (!is_directory(sb.buf))
1067+
break;
1068+
if (simplify_away(sb.buf, sb.len, simplify))
1069+
break;
1070+
if (treat_one_path(dir, &sb, simplify,
10781071
DT_DIR, NULL) == path_ignored)
1079-
return 0; /* do not recurse into it */
1080-
if (len <= baselen)
1081-
return 1; /* finished checking */
1072+
break; /* do not recurse into it */
1073+
if (len <= baselen) {
1074+
rc = 1;
1075+
break; /* finished checking */
1076+
}
10821077
}
1078+
strbuf_release(&sb);
1079+
return rc;
10831080
}
10841081

10851082
int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec)

0 commit comments

Comments
 (0)