Skip to content

Commit 390c6cb

Browse files
peffgitster
authored andcommitted
http: use strbufs instead of fixed buffers
We keep the names of incoming packs and objects in fixed PATH_MAX-size buffers, and snprintf() into them. This is unlikely to end up with truncated filenames, but it is possible (especially on systems where PATH_MAX is shorter than actual paths can be). Let's switch to using strbufs, which makes the question go away entirely. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 468165c commit 390c6cb

File tree

2 files changed

+38
-32
lines changed

2 files changed

+38
-32
lines changed

http.c

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,7 @@ void release_http_pack_request(struct http_pack_request *preq)
20872087
preq->packfile = NULL;
20882088
}
20892089
preq->slot = NULL;
2090+
strbuf_release(&preq->tmpfile);
20902091
free(preq->url);
20912092
free(preq);
20922093
}
@@ -2109,27 +2110,27 @@ int finish_http_pack_request(struct http_pack_request *preq)
21092110
lst = &((*lst)->next);
21102111
*lst = (*lst)->next;
21112112

2112-
if (!strip_suffix(preq->tmpfile, ".pack.temp", &len))
2113+
if (!strip_suffix(preq->tmpfile.buf, ".pack.temp", &len))
21132114
die("BUG: pack tmpfile does not end in .pack.temp?");
2114-
tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile);
2115+
tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile.buf);
21152116

21162117
argv_array_push(&ip.args, "index-pack");
21172118
argv_array_pushl(&ip.args, "-o", tmp_idx, NULL);
2118-
argv_array_push(&ip.args, preq->tmpfile);
2119+
argv_array_push(&ip.args, preq->tmpfile.buf);
21192120
ip.git_cmd = 1;
21202121
ip.no_stdin = 1;
21212122
ip.no_stdout = 1;
21222123

21232124
if (run_command(&ip)) {
2124-
unlink(preq->tmpfile);
2125+
unlink(preq->tmpfile.buf);
21252126
unlink(tmp_idx);
21262127
free(tmp_idx);
21272128
return -1;
21282129
}
21292130

21302131
unlink(sha1_pack_index_name(p->sha1));
21312132

2132-
if (finalize_object_file(preq->tmpfile, sha1_pack_name(p->sha1))
2133+
if (finalize_object_file(preq->tmpfile.buf, sha1_pack_name(p->sha1))
21332134
|| finalize_object_file(tmp_idx, sha1_pack_index_name(p->sha1))) {
21342135
free(tmp_idx);
21352136
return -1;
@@ -2148,19 +2149,19 @@ struct http_pack_request *new_http_pack_request(
21482149
struct http_pack_request *preq;
21492150

21502151
preq = xcalloc(1, sizeof(*preq));
2152+
strbuf_init(&preq->tmpfile, 0);
21512153
preq->target = target;
21522154

21532155
end_url_with_slash(&buf, base_url);
21542156
strbuf_addf(&buf, "objects/pack/pack-%s.pack",
21552157
sha1_to_hex(target->sha1));
21562158
preq->url = strbuf_detach(&buf, NULL);
21572159

2158-
snprintf(preq->tmpfile, sizeof(preq->tmpfile), "%s.temp",
2159-
sha1_pack_name(target->sha1));
2160-
preq->packfile = fopen(preq->tmpfile, "a");
2160+
strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(target->sha1));
2161+
preq->packfile = fopen(preq->tmpfile.buf, "a");
21612162
if (!preq->packfile) {
21622163
error("Unable to open local file %s for pack",
2163-
preq->tmpfile);
2164+
preq->tmpfile.buf);
21642165
goto abort;
21652166
}
21662167

@@ -2187,6 +2188,7 @@ struct http_pack_request *new_http_pack_request(
21872188
return preq;
21882189

21892190
abort:
2191+
strbuf_release(&preq->tmpfile);
21902192
free(preq->url);
21912193
free(preq);
21922194
return NULL;
@@ -2237,48 +2239,49 @@ struct http_object_request *new_http_object_request(const char *base_url,
22372239
{
22382240
char *hex = sha1_to_hex(sha1);
22392241
struct strbuf filename = STRBUF_INIT;
2240-
char prevfile[PATH_MAX];
2242+
struct strbuf prevfile = STRBUF_INIT;
22412243
int prevlocal;
22422244
char prev_buf[PREV_BUF_SIZE];
22432245
ssize_t prev_read = 0;
22442246
off_t prev_posn = 0;
22452247
struct http_object_request *freq;
22462248

22472249
freq = xcalloc(1, sizeof(*freq));
2250+
strbuf_init(&freq->tmpfile, 0);
22482251
hashcpy(freq->sha1, sha1);
22492252
freq->localfile = -1;
22502253

22512254
sha1_file_name(&filename, sha1);
2252-
snprintf(freq->tmpfile, sizeof(freq->tmpfile),
2253-
"%s.temp", filename.buf);
2255+
strbuf_addf(&freq->tmpfile, "%s.temp", filename.buf);
22542256

2255-
snprintf(prevfile, sizeof(prevfile), "%s.prev", filename.buf);
2256-
unlink_or_warn(prevfile);
2257-
rename(freq->tmpfile, prevfile);
2258-
unlink_or_warn(freq->tmpfile);
2257+
strbuf_addf(&prevfile, "%s.prev", filename.buf);
2258+
unlink_or_warn(prevfile.buf);
2259+
rename(freq->tmpfile.buf, prevfile.buf);
2260+
unlink_or_warn(freq->tmpfile.buf);
22592261
strbuf_release(&filename);
22602262

22612263
if (freq->localfile != -1)
22622264
error("fd leakage in start: %d", freq->localfile);
2263-
freq->localfile = open(freq->tmpfile,
2265+
freq->localfile = open(freq->tmpfile.buf,
22642266
O_WRONLY | O_CREAT | O_EXCL, 0666);
22652267
/*
22662268
* This could have failed due to the "lazy directory creation";
22672269
* try to mkdir the last path component.
22682270
*/
22692271
if (freq->localfile < 0 && errno == ENOENT) {
2270-
char *dir = strrchr(freq->tmpfile, '/');
2272+
char *dir = strrchr(freq->tmpfile.buf, '/');
22712273
if (dir) {
22722274
*dir = 0;
2273-
mkdir(freq->tmpfile, 0777);
2275+
mkdir(freq->tmpfile.buf, 0777);
22742276
*dir = '/';
22752277
}
2276-
freq->localfile = open(freq->tmpfile,
2278+
freq->localfile = open(freq->tmpfile.buf,
22772279
O_WRONLY | O_CREAT | O_EXCL, 0666);
22782280
}
22792281

22802282
if (freq->localfile < 0) {
2281-
error_errno("Couldn't create temporary file %s", freq->tmpfile);
2283+
error_errno("Couldn't create temporary file %s",
2284+
freq->tmpfile.buf);
22822285
goto abort;
22832286
}
22842287

@@ -2292,7 +2295,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
22922295
* If a previous temp file is present, process what was already
22932296
* fetched.
22942297
*/
2295-
prevlocal = open(prevfile, O_RDONLY);
2298+
prevlocal = open(prevfile.buf, O_RDONLY);
22962299
if (prevlocal != -1) {
22972300
do {
22982301
prev_read = xread(prevlocal, prev_buf, PREV_BUF_SIZE);
@@ -2309,7 +2312,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
23092312
} while (prev_read > 0);
23102313
close(prevlocal);
23112314
}
2312-
unlink_or_warn(prevfile);
2315+
unlink_or_warn(prevfile.buf);
2316+
strbuf_release(&prevfile);
23132317

23142318
/*
23152319
* Reset inflate/SHA1 if there was an error reading the previous temp
@@ -2324,7 +2328,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
23242328
lseek(freq->localfile, 0, SEEK_SET);
23252329
if (ftruncate(freq->localfile, 0) < 0) {
23262330
error_errno("Couldn't truncate temporary file %s",
2327-
freq->tmpfile);
2331+
freq->tmpfile.buf);
23282332
goto abort;
23292333
}
23302334
}
@@ -2354,6 +2358,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
23542358
return freq;
23552359

23562360
abort:
2361+
strbuf_release(&prevfile);
23572362
free(freq->url);
23582363
free(freq);
23592364
return NULL;
@@ -2381,33 +2386,33 @@ int finish_http_object_request(struct http_object_request *freq)
23812386
if (freq->http_code == 416) {
23822387
warning("requested range invalid; we may already have all the data.");
23832388
} else if (freq->curl_result != CURLE_OK) {
2384-
if (stat(freq->tmpfile, &st) == 0)
2389+
if (stat(freq->tmpfile.buf, &st) == 0)
23852390
if (st.st_size == 0)
2386-
unlink_or_warn(freq->tmpfile);
2391+
unlink_or_warn(freq->tmpfile.buf);
23872392
return -1;
23882393
}
23892394

23902395
git_inflate_end(&freq->stream);
23912396
git_SHA1_Final(freq->real_sha1, &freq->c);
23922397
if (freq->zret != Z_STREAM_END) {
2393-
unlink_or_warn(freq->tmpfile);
2398+
unlink_or_warn(freq->tmpfile.buf);
23942399
return -1;
23952400
}
23962401
if (hashcmp(freq->sha1, freq->real_sha1)) {
2397-
unlink_or_warn(freq->tmpfile);
2402+
unlink_or_warn(freq->tmpfile.buf);
23982403
return -1;
23992404
}
24002405

24012406
sha1_file_name(&filename, freq->sha1);
2402-
freq->rename = finalize_object_file(freq->tmpfile, filename.buf);
2407+
freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf);
24032408
strbuf_release(&filename);
24042409

24052410
return freq->rename;
24062411
}
24072412

24082413
void abort_http_object_request(struct http_object_request *freq)
24092414
{
2410-
unlink_or_warn(freq->tmpfile);
2415+
unlink_or_warn(freq->tmpfile.buf);
24112416

24122417
release_http_object_request(freq);
24132418
}
@@ -2427,4 +2432,5 @@ void release_http_object_request(struct http_object_request *freq)
24272432
release_active_slot(freq->slot);
24282433
freq->slot = NULL;
24292434
}
2435+
strbuf_release(&freq->tmpfile);
24302436
}

http.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ struct http_pack_request {
200200
struct packed_git *target;
201201
struct packed_git **lst;
202202
FILE *packfile;
203-
char tmpfile[PATH_MAX];
203+
struct strbuf tmpfile;
204204
struct active_request_slot *slot;
205205
};
206206

@@ -212,7 +212,7 @@ extern void release_http_pack_request(struct http_pack_request *preq);
212212
/* Helpers for fetching object */
213213
struct http_object_request {
214214
char *url;
215-
char tmpfile[PATH_MAX];
215+
struct strbuf tmpfile;
216216
int localfile;
217217
CURLcode curl_result;
218218
char errorstr[CURL_ERROR_SIZE];

0 commit comments

Comments
 (0)