Download raw body.
got_path_strip_trailing_slashes: change to preserve the first "/"
otherwise a path made of only "/" becomes an empty string, which is not
desiderable since we're managing paths. Adjust the callers to cope with
the behaviour change.
ok?
diff 554d01aac8a3901d8a7f0ac67b88392d1fd2a71d c3f50630385142d9b8e1f024294037c21ea4ac5c
commit - 554d01aac8a3901d8a7f0ac67b88392d1fd2a71d
commit + c3f50630385142d9b8e1f024294037c21ea4ac5c
blob - f367e5a43d5c219b2524ae00cf0508b70c89693a
blob + 86375a5ba981252f7373c914687eb34e0fe9822e
--- gotd/parse.y
+++ gotd/parse.y
@@ -1370,11 +1370,17 @@ conf_protect_ref_namespace(char **new, struct got_path
*new = NULL;
got_path_strip_trailing_slashes(namespace);
if (!refname_is_valid(namespace))
return -1;
- if (asprintf(&s, "%s/", namespace) == -1) {
+ if (got_path_is_root_dir(namespace)) {
+ s = strdup(namespace);
+ if (s == NULL) {
+ yyerror("strdup: %s", strerror(errno));
+ return -1;
+ }
+ } else if (asprintf(&s, "%s/", namespace) == -1) {
yyerror("asprintf: %s", strerror(errno));
return -1;
}
error = got_pathlist_insert(&pe, refs, s, NULL);
@@ -1522,11 +1528,17 @@ conf_notify_ref_namespace(struct gotd_repo *repo, char
got_path_strip_trailing_slashes(namespace);
if (!refname_is_valid(namespace))
return -1;
- if (asprintf(&s, "%s/", namespace) == -1) {
+ if (got_path_is_root_dir(namespace)) {
+ s = strdup(namespace);
+ if (s == NULL) {
+ yyerror("strdup: %s", strerror(errno));
+ return -1;
+ }
+ } else if (asprintf(&s, "%s/", namespace) == -1) {
yyerror("asprintf: %s", strerror(errno));
return -1;
}
error = got_pathlist_insert(&pe, &repo->notification_ref_namespaces,
blob - a93897378b3c9c123c2da0f01702fb86d2481274
blob + eaed62bb5e478983164ee2a6b5cf893e4e258435
--- gotsys/parse.y
+++ gotsys/parse.y
@@ -1063,13 +1063,11 @@ webopts1 : DISABLE AUTHENTICATION {
"an empty string");
free($4);
YYERROR;
}
- if (!got_path_is_root_dir($4))
- got_path_strip_trailing_slashes($4);
-
+ got_path_strip_trailing_slashes($4);
if (!got_path_is_absolute($4)) {
int ret;
ret = snprintf(srv->repos_url_path,
sizeof(srv->repos_url_path),
@@ -1828,11 +1826,17 @@ conf_protect_ref_namespace(char **new, struct got_path
*new = NULL;
got_path_strip_trailing_slashes(namespace);
if (!refname_is_valid(namespace))
return -1;
- if (asprintf(&s, "%s/", namespace) == -1) {
+ if (got_path_is_root_dir(namespace)) {
+ s = strdup(namespace);
+ if (s == NULL) {
+ yyerror("strdup: %s", strerror(errno));
+ return -1;
+ }
+ } else if (asprintf(&s, "%s/", namespace) == -1) {
yyerror("asprintf: %s", strerror(errno));
return -1;
}
error = got_pathlist_insert(&pe, refs, s, NULL);
@@ -1979,12 +1983,17 @@ conf_notify_ref_namespace(struct gotsys_repo *repo, ch
char *s;
got_path_strip_trailing_slashes(namespace);
if (!refname_is_valid(namespace))
return -1;
-
- if (asprintf(&s, "%s/", namespace) == -1) {
+ if (got_path_is_root_dir(namespace)) {
+ s = strdup(namespace);
+ if (s == NULL) {
+ yyerror("strdup: %s", strerror(errno));
+ return -1;
+ }
+ } else if (asprintf(&s, "%s/", namespace) == -1) {
yyerror("asprintf: %s", strerror(errno));
return -1;
}
error = got_pathlist_insert(&pe, &repo->notification_ref_namespaces,
blob - 361d77c7427fc4a3d7cf21474edb09a17c84f5ed
blob + dc9d8ca2826bc77b85db2cff43d7a50c8dfdbc3f
--- gotwebd/gotweb.c
+++ gotwebd/gotweb.c
@@ -539,10 +539,11 @@ gotweb_serve_website(struct request *c, struct website
for (i = 0; i < nentries; i++) {
struct gotweb_url url = {
.index_page = -1,
.action = -1,
};
+ const char *index = "/index.html";
te = got_object_tree_get_entry(tree, i);
if (te == NULL) {
char *id_str;
@@ -562,11 +563,14 @@ gotweb_serve_website(struct request *c, struct website
strcasecmp(name, "index.html") != 0)
continue;
/* XXX gotweb_reply uses request struct field */
got_path_strip_trailing_slashes(p->document_uri);
- if (strlcat(p->document_uri, "/index.html",
+ if (got_path_is_root_dir(p->document_uri))
+ index++; /* skip initial "/" */
+
+ if (strlcat(p->document_uri, index,
sizeof(p->document_uri)) >=
sizeof(p->document_uri)) {
error = got_error(GOT_ERR_NO_SPACE);
goto done;
}
@@ -696,13 +700,11 @@ gotweb_route_request(int *is_repository_request, struc
error = got_error_from_errno("strdup");
goto done;
}
}
- if (!got_path_is_root_dir(*request_path))
- got_path_strip_trailing_slashes(*request_path);
-
+ got_path_strip_trailing_slashes(*request_path);
*site = gotweb_get_website(srv, *request_path);
/*
* If the target of the request is ambiguous, the longer path wins.
*/
blob - ab1b6288020128df255679667f47261e6eed76a0
blob + b618203af4224f676c92168f6e40fd0e17977773
--- gotwebd/pages.tmpl
+++ gotwebd/pages.tmpl
@@ -186,11 +186,12 @@ nextsep(char *s, char **t)
while (url_path[0] == '/')
url_path++;
if (url_path[0] != '\0') {
if (url_root[0] != '\0') {
got_path_strip_trailing_slashes(prefix);
- strlcat(prefix, "/", sizeof(prefix));
+ if (!got_path_is_root_dir(prefix))
+ strlcat(prefix, "/", sizeof(prefix));
}
strlcat(prefix, url_path, sizeof(prefix));
}
got_path_strip_trailing_slashes(prefix);
@@ -1490,11 +1491,12 @@ date: {{ datebuf }} {{ " UTC" }} {{ "\n" }}
while (url_path[0] == '/')
url_path++;
if (url_path[0] != '\0') {
if (url_root[0] != '\0') {
got_path_strip_trailing_slashes(prefix);
- strlcat(prefix, "/", sizeof(prefix));
+ if (!got_path_is_root_dir(prefix))
+ strlcat(prefix, "/", sizeof(prefix));
}
strlcat(prefix, url_path, sizeof(prefix));
}
got_path_strip_trailing_slashes(prefix);
blob - e356cea29b105402010bc95aa09710adfd5c96ef
blob + 6e931ee077053256fdea2e1ba51a4d329d71f30c
--- gotwebd/parse.y
+++ gotwebd/parse.y
@@ -427,13 +427,11 @@ main : PREFORK NUMBER {
" string");
free($2);
YYERROR;
}
- if (!got_path_is_root_dir($2))
- got_path_strip_trailing_slashes($2);
-
+ got_path_strip_trailing_slashes($2);
n = strlcpy(gotwebd->gotweb_url_root, $2,
sizeof(gotwebd->gotweb_url_root));
if (n >= sizeof(gotwebd->gotweb_url_root)) {
yyerror("gotweb_url_root too long, exceeds "
"%zd bytes: %s",
@@ -458,13 +456,11 @@ main : PREFORK NUMBER {
" string");
free($2);
YYERROR;
}
- if (!got_path_is_root_dir($2))
- got_path_strip_trailing_slashes($2);
-
+ got_path_strip_trailing_slashes($2);
n = strlcpy(gotwebd->repos_url_path, $2,
sizeof(gotwebd->repos_url_path));
if (n >= sizeof(gotwebd->repos_url_path)) {
yyerror("repos_url_path too long, exceeds "
"%zd bytes: %s",
@@ -809,13 +805,11 @@ serveropts1 : REPOS_PATH STRING {
" string");
free($2);
YYERROR;
}
- if (!got_path_is_root_dir($2))
- got_path_strip_trailing_slashes($2);
-
+ got_path_strip_trailing_slashes($2);
n = strlcpy(new_srv->gotweb_url_root, $2,
sizeof(new_srv->gotweb_url_root));
if (n >= sizeof(new_srv->gotweb_url_root)) {
yyerror("gotweb_url_root too long, exceeds "
"%zd bytes: %s",
@@ -839,13 +833,11 @@ serveropts1 : REPOS_PATH STRING {
" string");
free($2);
YYERROR;
}
- if (!got_path_is_root_dir($2))
- got_path_strip_trailing_slashes($2);
-
+ got_path_strip_trailing_slashes($2);
n = strlcpy(new_srv->repos_url_path, $2,
sizeof(new_srv->repos_url_path));
if (n >= sizeof(new_srv->repos_url_path)) {
yyerror("repos_url_path too long, exceeds "
"%zd bytes: %s",
@@ -2010,15 +2002,11 @@ parse_config(const char *filename, struct gotwebd *env
sizeof(srv->full_repos_url_path) - 1);
return -1;
}
}
- if (!got_path_is_root_dir(srv->full_repos_url_path)) {
- got_path_strip_trailing_slashes(
- srv->full_repos_url_path);
- }
-
+ got_path_strip_trailing_slashes(srv->full_repos_url_path);
RB_FOREACH(pe, got_pathlist_head, &srv->websites) {
const char *url_path = pe->path;
struct website *site = pe->data;
if (site->auth_config == 0)
blob - c52de692cb3df4f92464143bd3f8bdd3a32ebc90
blob + ccd4ca57ebc3da3041d26be979d2339e3fb5cf9d
--- lib/dial.c
+++ lib/dial.c
@@ -188,12 +188,13 @@ got_dial_parse_uri(char **proto, char **host, char **p
*server_path = strdup(p);
if (*server_path == NULL) {
err = got_error_from_errno("strdup");
goto done;
}
+
got_path_strip_trailing_slashes(*server_path);
- if ((*server_path)[0] == '\0') {
+ if (got_path_is_root_dir(*server_path)) {
err = got_error(GOT_ERR_PARSE_URI);
goto done;
}
err = got_path_basename(repo_name, *server_path);
blob - b43f45fcda4659959a1775f2a328234862001f60
blob + 1be262eb423fe458698d66819eb694c1d1eef476
--- lib/path.c
+++ lib/path.c
@@ -429,11 +429,13 @@ void
got_path_strip_trailing_slashes(char *path)
{
size_t x;
x = strlen(path);
- while (x-- > 0 && path[x] == '/')
+
+ /* if the input is "/" don't trim it */
+ while (x-- > 1 && path[x] == '/')
path[x] = '\0';
}
/* based on findprog() from usr.bin/which/which.c */
const struct got_error *
blob - fca04b3b62b7ecd7035e827c334fa35ad977b7a3
blob + 1a6c5d63489f0fc3240c2601bd4a04ce00ad43ad
--- lib/worktree.c
+++ lib/worktree.c
@@ -183,13 +183,13 @@ got_worktree_init(const char *path, struct got_referen
} else {
absprefix = strdup(prefix);
if (absprefix == NULL)
return got_error_from_errno("strdup");
}
- if (!got_path_is_root_dir(absprefix))
- got_path_strip_trailing_slashes(absprefix);
+ got_path_strip_trailing_slashes(absprefix);
+
/* Create top-level directory (may already exist). */
if (mkdir(path, GOT_DEFAULT_DIR_MODE) == -1 && errno != EEXIST) {
err = got_error_from_errno2("mkdir", path);
goto done;
}
blob - 9c87f1cb18b976ef796bcbe79abffd540c2e80a8
blob + 5406ccec12650b57a31461290e66973c8fda4b86
--- lib/worktree_open.c
+++ lib/worktree_open.c
@@ -193,13 +193,13 @@ open_worktree(struct got_worktree **worktree, const ch
err = read_meta_file(&(*worktree)->path_prefix, path_meta,
GOT_WORKTREE_PATH_PREFIX);
if (err)
goto done;
- if (!got_path_is_root_dir((*worktree)->path_prefix))
- got_path_strip_trailing_slashes((*worktree)->path_prefix);
+ got_path_strip_trailing_slashes((*worktree)->path_prefix);
+
err = read_meta_file(&base_commit_id_str, path_meta,
GOT_WORKTREE_BASE_COMMIT);
if (err)
goto done;
blob - c4da368ef9fe5fb3b4c6ff3a0879637e0a4a2611
blob + c3febf63fe7daf00c838081bf3ab693ce816f381
--- regress/path/path_test.c
+++ regress/path/path_test.c
@@ -21,10 +21,11 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include <err.h>
+#include <limits.h>
#include "got_error.h"
#include "got_path.h"
#ifndef nitems
@@ -97,10 +98,43 @@ path_cmp(void)
}
return 1;
}
+static int
+path_strip_trailing_slashes(void)
+{
+ const struct path_cmp_test {
+ const char *input;
+ const char *expected;
+ } test_data[] = {
+ { "", "" },
+ { "/", "/" },
+ { "///", "/" },
+ { "/a", "/a" },
+ { "/a/", "/a" },
+ { "/a//", "/a" },
+ };
+ size_t i;
+
+ for (i = 0; i < nitems(test_data); i++) {
+ char p[PATH_MAX];
+ const char *input = test_data[i].input;
+ const char *expected = test_data[i].expected;
+
+ strlcpy(p, input, sizeof(p));
+ got_path_strip_trailing_slashes(p);
+ if (strcmp(p, expected) != 0) {
+ test_printf("%d: '%s' -> '%s'; expected '%s'\n",
+ i, input, p, expected);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
const char *path_list_input[] = {
"", "/", "a", "/b", "/bar", "bar/sub", "/bar/sub", "/bar/",
"/bar.c", "/bar/sub/sub2", "/bar.sub.sub2", "/foo",
"/foo/sub", "/foo/", "/foo/", "x/a",
};
@@ -246,10 +280,11 @@ main(int argc, char *argv[])
}
argc -= optind;
argv += optind;
RUN_TEST(path_cmp(), "path_cmp");
+ RUN_TEST(path_strip_trailing_slashes(), "path_strip_trailing_slashes");
RUN_TEST(path_list(), "path_list");
RUN_TEST(path_list_reverse_input(), "path_list_reverse_input");
return failure ? 1 : 0;
}
got_path_strip_trailing_slashes: change to preserve the first "/"