check path truncation - stagit-gopher - A git gopher frontend. (mirror) | |
git clone git://bitreich.org/stagit-gopher/ git://enlrupgkhuxnvlhsf6lc3fziv5h2h… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit ad22404903d25e126d97635b01cecb7be33bfd69 | |
parent f4f53c577eb86d4e65494270a9cf259b27ea22b9 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Wed, 24 Feb 2016 14:47:20 +0100 | |
check path truncation | |
be strict about it | |
Diffstat: | |
M TODO | 2 -- | |
M stagit-index.c | 24 ++++++++++++++++++------ | |
M stagit.c | 55 +++++++++++++++++++++--------… | |
3 files changed, 56 insertions(+), 25 deletions(-) | |
--- | |
diff --git a/TODO b/TODO | |
@@ -1,5 +1,3 @@ | |
-check path truncation? snprintf(), strlcpy. | |
- | |
performance: | |
- optimize git_diff_get_stats. | |
- speed up generating files. | |
diff --git a/stagit-index.c b/stagit-index.c | |
@@ -178,7 +178,7 @@ main(int argc, char *argv[]) | |
const git_error *e = NULL; | |
FILE *fp; | |
char path[PATH_MAX], *p; | |
- int i, ret = 0; | |
+ int i, r, ret = 0; | |
if (argc < 2) { | |
fprintf(stderr, "%s [repodir...]\n", argv[0]); | |
@@ -199,18 +199,24 @@ main(int argc, char *argv[]) | |
continue; | |
} | |
- /* use directory name as name */ | |
+ /* use directory name as name, truncation of name is no proble… | |
p = xbasename(repodir); | |
snprintf(name, sizeof(name), "%s", p); | |
free(p); | |
/* read description or .git/description */ | |
description[0] = '\0'; | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "… | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '/' ? "" … | |
if (!(fp = fopen(path, "r"))) { | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" … | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '… | |
fp = fopen(path, "r"); | |
} | |
if (fp) { | |
@@ -221,11 +227,17 @@ main(int argc, char *argv[]) | |
/* read owner or .git/owner */ | |
owner[0] = '\0'; | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "… | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '/' ? "" … | |
if (!(fp = fopen(path, "r"))) { | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" … | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '… | |
fp = fopen(path, "r"); | |
} | |
if (fp) { | |
diff --git a/stagit.c b/stagit.c | |
@@ -188,7 +188,8 @@ mkdirp(const char *path) | |
{ | |
char tmp[PATH_MAX], *p; | |
- strlcpy(tmp, path, sizeof(tmp)); | |
+ if (strlcpy(tmp, path, sizeof(tmp)) >= sizeof(tmp)) | |
+ errx(1, "path truncated: '%s'", path); | |
for (p = tmp + (tmp[0] == '/'); *p; p++) { | |
if (*p != '/') | |
continue; | |
@@ -426,6 +427,7 @@ writelog(FILE *fp, const git_oid *oid) | |
size_t len; | |
char path[PATH_MAX]; | |
FILE *fpfile; | |
+ int r; | |
git_revwalk_new(&w, repo); | |
git_revwalk_push(w, oid); | |
@@ -469,7 +471,10 @@ writelog(FILE *fp, const git_oid *oid) | |
relpath = "../"; | |
- snprintf(path, sizeof(path), "commit/%s.html", ci->oid); | |
+ r = snprintf(path, sizeof(path), "commit/%s.html", ci->oid); | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: 'commit/%s.html'", ci->oid); | |
+ | |
/* check if file exists if so skip it */ | |
if (access(path, F_OK)) { | |
fpfile = efopen(path, "w"); | |
@@ -591,8 +596,8 @@ writeblob(git_object *obj, const char *fpath, const char *f… | |
p = fpath; | |
while (*p) { | |
- if (*p == '/') | |
- strlcat(tmp, "../", sizeof(tmp)); | |
+ if (*p == '/' && strlcat(tmp, "../", sizeof(tmp)) >= sizeof(tm… | |
+ errx(1, "path truncated: '../%s'", tmp); | |
p++; | |
} | |
relpath = tmp; | |
@@ -670,7 +675,7 @@ writefilestree(FILE *fp, git_tree *tree, const char *branch… | |
git_object *obj = NULL; | |
git_off_t filesize; | |
size_t count, i; | |
- int lc, ret; | |
+ int lc, r, ret; | |
count = git_tree_entrycount(tree); | |
for (i = 0; i < count; i++) { | |
@@ -678,8 +683,11 @@ writefilestree(FILE *fp, git_tree *tree, const char *branc… | |
git_tree_entry_to_object(&obj, repo, entry)) | |
return -1; | |
entryname = git_tree_entry_name(entry); | |
- snprintf(entrypath, sizeof(entrypath), "%s%s%s", | |
+ r = snprintf(entrypath, sizeof(entrypath), "%s%s%s", | |
path, path[0] ? "/" : "", entryname); | |
+ if (r == -1 || (size_t)r >= sizeof(entrypath)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ path, path[0] ? "/" : "", entryname); | |
switch (git_object_type(obj)) { | |
case GIT_OBJ_BLOB: | |
break; | |
@@ -695,12 +703,13 @@ writefilestree(FILE *fp, git_tree *tree, const char *bran… | |
git_object_free(obj); | |
continue; | |
} | |
- if (path[0]) | |
- snprintf(filepath, sizeof(filepath), "file/%s/%s.html", | |
- path, entryname); | |
- else | |
- snprintf(filepath, sizeof(filepath), "file/%s.html", | |
- entryname); | |
+ | |
+ r = snprintf(filepath, sizeof(filepath), "file/%s%s%s.html", | |
+ path, path[0] ? "/" : "", entryname); | |
+ if (r == -1 || (size_t)r >= sizeof(filepath)) | |
+ errx(1, "path truncated: 'file/%s%s%s.html'", | |
+ path, path[0] ? "/" : "", entryname); | |
+ | |
filesize = git_blob_rawsize((git_blob *)obj); | |
lc = writeblob(obj, filepath, entryname, filesize); | |
@@ -868,7 +877,7 @@ main(int argc, char *argv[]) | |
const git_error *e = NULL; | |
FILE *fp, *fpread; | |
char path[PATH_MAX], *p; | |
- int status; | |
+ int r, status; | |
if (argc != 2) { | |
fprintf(stderr, "%s <repodir>\n", argv[0]); | |
@@ -902,11 +911,17 @@ main(int argc, char *argv[]) | |
*p = '\0'; | |
/* read description or .git/description */ | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "descript… | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "… | |
if (!(fpread = fopen(path, "r"))) { | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "… | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '/' ? "" … | |
fpread = fopen(path, "r"); | |
} | |
if (fpread) { | |
@@ -916,11 +931,17 @@ main(int argc, char *argv[]) | |
} | |
/* read url or .git/url */ | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "url"); | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "… | |
if (!(fpread = fopen(path, "r"))) { | |
- snprintf(path, sizeof(path), "%s%s%s", | |
+ r = snprintf(path, sizeof(path), "%s%s%s", | |
repodir, repodir[strlen(repodir)] == '/' ? "" : "/", "… | |
+ if (r == -1 || (size_t)r >= sizeof(path)) | |
+ errx(1, "path truncated: '%s%s%s'", | |
+ repodir, repodir[strlen(repodir)] == '/' ? "" … | |
fpread = fopen(path, "r"); | |
} | |
if (fpread) { |