mailsplit: make PATH_MAX buffers dynamic
There are several PATH_MAX-sized buffers in mailsplit, along with some questionable uses of sprintf. These are not really of security interest, as local mailsplit pathnames are not typically under control of an attacker, and you could generally only overflow a few numbers at the end of a path that approaches PATH_MAX (a longer path would choke mailsplit long before). But it does not hurt to be careful, and as a bonus we lift some limits for systems with too-small PATH_MAX varibles. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Sep 24, 2015 at 17:05 UTC
1d895f194ff612057989f477dc106aa1c7ac2016
1 file changed
+23
-11
builtin/mailsplit.c
+23
-11
@@ -98,30 +98,37 @@ static int populate_maildir_list(struct string_list *list, const char *path)
98
{
99
DIR *dir;
100
struct dirent *dent;
101
- char name[PATH_MAX];
101
+ char *name = NULL;
102
char *subs[] = { "cur", "new", NULL };
103
char **sub;
104
+ int ret = -1;
105
106
for (sub = subs; *sub; ++sub) {
106
- snprintf(name, sizeof(name), "%s/%s", path, *sub);
107
+ free(name);
108
+ name = xstrfmt("%s/%s", path, *sub);
109
if ((dir = opendir(name)) == NULL) {
110
if (errno == ENOENT)
111
continue;
112
error("cannot opendir %s (%s)", name, strerror(errno));
111
- return -1;
113
+ goto out;
114
}
115
116
while ((dent = readdir(dir)) != NULL) {
117
if (dent->d_name[0] == '.')
118
continue;
117
- snprintf(name, sizeof(name), "%s/%s", *sub, dent->d_name);
119
+ free(name);
120
+ name = xstrfmt("%s/%s", *sub, dent->d_name);
121
string_list_insert(list, name);
122
}
123
124
closedir(dir);
125
}
126
124
- return 0;
127
+ ret = 0;
128
+
129
+out:
130
+ free(name);
131
+ return ret;
132
}
133
134
static int maildir_filename_cmp(const char *a, const char *b)
@@ -148,8 +155,7 @@ static int maildir_filename_cmp(const char *a, const char *b)
155
static int split_maildir(const char *maildir, const char *dir,
156
int nr_prec, int skip)
157
{
151
- char file[PATH_MAX];
152
- char name[PATH_MAX];
158
+ char *file = NULL;
159
FILE *f = NULL;
160
int ret = -1;
161
int i;
@@ -161,7 +167,11 @@ static int split_maildir(const char *maildir, const char *dir,
167
goto out;
168
169
for (i = 0; i < list.nr; i++) {
164
- snprintf(file, sizeof(file), "%s/%s", maildir, list.items[i].string);
170
+ char *name;
171
+
172
+ free(file);
173
+ file = xstrfmt("%s/%s", maildir, list.items[i].string);
174
+
175
f = fopen(file, "r");
176
if (!f) {
177
error("cannot open mail %s (%s)", file, strerror(errno));
@@ -173,8 +183,9 @@ static int split_maildir(const char *maildir, const char *dir,
183
goto out;
184
}
185
176
- sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
186
+ name = xstrfmt("%s/%0*d", dir, nr_prec, ++skip);
187
split_one(f, name, 1);
188
+ free(name);
189
190
fclose(f);
191
f = NULL;
@@ -184,6 +195,7 @@ static int split_maildir(const char *maildir, const char *dir,
195
out:
196
if (f)
197
fclose(f);
198
+ free(file);
199
string_list_clear(&list, 1);
200
return ret;
201
}
@@ -191,7 +203,6 @@ out:
203
static int split_mbox(const char *file, const char *dir, int allow_bare,
204
int nr_prec, int skip)
205
{
194
- char name[PATH_MAX];
206
int ret = -1;
207
int peek;
208
@@ -218,8 +229,9 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,
229
}
230
231
while (!file_done) {
221
- sprintf(name, "%s/%0*d", dir, nr_prec, ++skip);
232
+ char *name = xstrfmt("%s/%0*d", dir, nr_prec, ++skip);
233
file_done = split_one(f, name, allow_bare);
234
+ free(name);
235
}
236
237
if (f != stdin)