Browse Source

[core] buffer_append_path_len()

concatenate paths, placing single '/' between strings

reverts broken commit:b9402283

(thx avij)
personal/stbuehler/fix-fdevent
Glenn Strauss 3 years ago
parent
commit
77c01f9817
  1. 15
      src/buffer.c
  2. 1
      src/buffer.h
  3. 3
      src/chunk.c
  4. 6
      src/mod_dirlisting.c
  5. 12
      src/mod_userdir.c
  6. 42
      src/mod_webdav.c
  7. 6
      src/response.c
  8. 34
      src/t/test_buffer.c

15
src/buffer.c

@ -198,6 +198,21 @@ void buffer_append_string_len(buffer *b, const char *s, size_t s_len) {
b->used += s_len;
}
void buffer_append_path_len(buffer *b, const char *a, size_t alen) {
size_t blen = buffer_string_length(b);
int aslash = (alen && a[0] == '/');
buffer_string_prepare_append(b, alen+2); /*(+ '/' and + '\0' if 0 == blen)*/
if (blen && b->ptr[blen-1] == '/') {
if (aslash) --b->used;
}
else {
if (!b->used) ++b->used;
if (!aslash) b->ptr[++b->used - 2] = '/';
}
memcpy(b->ptr+b->used-1, a, alen);
b->ptr[(b->used += alen)-1] = '\0';
}
void buffer_append_uint_hex_lc(buffer *b, uintmax_t value) {
char *buf;
unsigned int shift = 0;

1
src/buffer.h

@ -170,6 +170,7 @@ static inline int light_isalnum(int c) {
static inline size_t buffer_string_length(const buffer *b); /* buffer string length without terminating 0 */
static inline size_t buffer_string_space(const buffer *b); /* maximum length of string that can be stored without reallocating */
static inline void buffer_append_slash(buffer *b); /* append '/' no non-empty strings not ending in '/' */
void buffer_append_path_len(buffer *b, const char *a, size_t alen); /* join strings with '/', if '/' not present */
#define BUFFER_APPEND_STRING_CONST(x, y) \
buffer_append_string_len(x, y, sizeof(y) - 1)

3
src/chunk.c

@ -509,8 +509,7 @@ static chunk *chunkqueue_get_append_tempfile(server *srv, chunkqueue *cq) {
data_string *ds = (data_string *)cq->tempdirs->data[cq->tempdir_idx];
buffer_copy_buffer(template, ds->value);
buffer_append_slash(template);
buffer_append_string_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX"));
buffer_append_path_len(template, CONST_STR_LEN("lighttpd-upload-XXXXXX"));
#ifdef __COVERITY__
/* POSIX-2008 requires mkstemp create file with 0600 perms */

6
src/mod_dirlisting.c

@ -807,8 +807,7 @@ static void http_list_directory_header(server *srv, connection *con, plugin_data
buffer *hb = p->conf.show_header;
if (hb->ptr[0] != '/') {
buffer_copy_buffer(p->tmp_buf, con->physical.path);
buffer_append_slash(p->tmp_buf);
buffer_append_string_buffer(p->tmp_buf, p->conf.show_header);
buffer_append_path_len(p->tmp_buf, CONST_BUF_LEN(p->conf.show_header));
hb = p->tmp_buf;
}
@ -858,8 +857,7 @@ static void http_list_directory_footer(server *srv, connection *con, plugin_data
buffer *rb = p->conf.show_readme;
if (rb->ptr[0] != '/') {
buffer_copy_buffer(p->tmp_buf, con->physical.path);
buffer_append_slash(p->tmp_buf);
buffer_append_string_buffer(p->tmp_buf, p->conf.show_readme);
buffer_append_path_len(p->tmp_buf, CONST_BUF_LEN(p->conf.show_readme));
rb = p->tmp_buf;
}

12
src/mod_userdir.c

@ -262,6 +262,7 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
}
/* we build the physical path */
buffer_clear(p->temp_path);
if (buffer_string_is_empty(p->conf.basepath)) {
#ifdef HAVE_PWD_H
@ -287,16 +288,13 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
}
buffer_copy_buffer(p->temp_path, p->conf.basepath);
buffer_append_slash(p->temp_path);
if (p->conf.letterhomes) {
if (p->username->ptr[0] == '.') return HANDLER_GO_ON;
buffer_append_string_len(p->temp_path, p->username->ptr, 1);
buffer_append_slash(p->temp_path);
buffer_append_path_len(p->temp_path, p->username->ptr, 1);
}
buffer_append_string_buffer(p->temp_path, p->username);
buffer_append_path_len(p->temp_path, CONST_BUF_LEN(p->username));
}
buffer_append_slash(p->temp_path);
buffer_append_string_buffer(p->temp_path, p->conf.path);
buffer_append_path_len(p->temp_path, CONST_BUF_LEN(p->conf.path));
if (buffer_string_is_empty(p->conf.basepath)) {
struct stat st;
@ -330,8 +328,6 @@ URIHANDLER_FUNC(mod_userdir_docroot_handler) {
}
buffer_copy_buffer(con->physical.path, p->temp_path);
buffer_clear(p->temp_path);
return HANDLER_GO_ON;
}

42
src/mod_webdav.c

@ -590,6 +590,7 @@ static int webdav_delete_dir(server *srv, connection *con, handler_ctx *hctx, ph
while(NULL != (de = readdir(dir))) {
struct stat st;
size_t nlen;
if ((de->d_name[0] == '.' && de->d_name[1] == '\0') ||
(de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
@ -597,13 +598,12 @@ static int webdav_delete_dir(server *srv, connection *con, handler_ctx *hctx, ph
/* ignore the parent dir */
}
nlen = strlen(de->d_name);
buffer_copy_buffer(d.path, dst->path);
buffer_append_slash(d.path);
buffer_append_string(d.path, de->d_name);
buffer_append_path_len(d.path, de->d_name, nlen);
buffer_copy_buffer(d.rel_path, dst->rel_path);
buffer_append_slash(d.rel_path);
buffer_append_string(d.rel_path, de->d_name);
buffer_append_path_len(d.rel_path, de->d_name, nlen);
/* stat and unlink afterwards */
if (-1 == stat(d.path->ptr, &st)) {
@ -770,27 +770,25 @@ static int webdav_copy_dir(server *srv, connection *con, handler_ctx *hctx, phys
while (NULL != (de = readdir(srcdir))) {
struct stat st;
size_t nlen;
if ((de->d_name[0] == '.' && de->d_name[1] == '\0')
|| (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')) {
continue;
}
nlen = strlen(de->d_name);
buffer_copy_buffer(s.path, src->path);
buffer_append_slash(s.path);
buffer_append_string(s.path, de->d_name);
buffer_append_path_len(s.path, de->d_name, nlen);
buffer_copy_buffer(d.path, dst->path);
buffer_append_slash(d.path);
buffer_append_string(d.path, de->d_name);
buffer_append_path_len(d.path, de->d_name, nlen);
buffer_copy_buffer(s.rel_path, src->rel_path);
buffer_append_slash(s.rel_path);
buffer_append_string(s.rel_path, de->d_name);
buffer_append_path_len(s.rel_path, de->d_name, nlen);
buffer_copy_buffer(d.rel_path, dst->rel_path);
buffer_append_slash(d.rel_path);
buffer_append_string(d.rel_path, de->d_name);
buffer_append_path_len(d.rel_path, de->d_name, nlen);
if (-1 == stat(s.path->ptr, &st)) {
/* why ? */
@ -1500,19 +1498,18 @@ static handler_t mod_webdav_propfind(server *srv, connection *con, plugin_data *
d.rel_path = buffer_init();
while(NULL != (de = readdir(dir))) {
size_t nlen;
if (de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) {
continue;
/* ignore the parent and target dir */
}
nlen = strlen(de->d_name);
buffer_copy_buffer(d.path, dst->path);
buffer_append_slash(d.path);
buffer_append_path_len(d.path, de->d_name, nlen);
buffer_copy_buffer(d.rel_path, dst->rel_path);
buffer_append_slash(d.rel_path);
buffer_append_string(d.path, de->d_name);
buffer_append_string(d.rel_path, de->d_name);
buffer_append_path_len(d.rel_path, de->d_name, nlen);
buffer_clear(prop_200);
buffer_clear(prop_404);
@ -2064,16 +2061,7 @@ static handler_t mod_webdav_copymove(server *srv, connection *con, plugin_data *
buffer_copy_buffer(p->physical.path, p->physical.doc_root);
buffer_append_slash(p->physical.path);
buffer_copy_buffer(p->physical.basedir, p->physical.path);
/* don't add a second / */
if (p->physical.rel_path->ptr[0] == '/') {
#ifdef __COVERITY__
if (buffer_string_length(p->physical.rel_path) < 1) return HANDLER_ERROR;
#endif
buffer_append_string_len(p->physical.path, p->physical.rel_path->ptr + 1, buffer_string_length(p->physical.rel_path) - 1);
} else {
buffer_append_string_buffer(p->physical.path, p->physical.rel_path);
}
buffer_append_path_len(p->physical.path, CONST_BUF_LEN(p->physical.rel_path));
}
}

6
src/response.c

@ -615,11 +615,7 @@ handler_t http_response_prepare(server *srv, connection *con) {
buffer_copy_buffer(con->physical.basedir, con->physical.doc_root);
buffer_copy_buffer(con->physical.path, con->physical.doc_root);
if (buffer_string_is_empty(con->physical.rel_path)
|| con->physical.rel_path->ptr[0] != '/') {
buffer_append_slash(con->physical.path);
}
buffer_append_string_buffer(con->physical.path, con->physical.rel_path);
buffer_append_path_len(con->physical.path, CONST_BUF_LEN(con->physical.rel_path));
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s", "-- after doc_root");

34
src/t/test_buffer.c

@ -114,10 +114,44 @@ static void test_buffer_string_space(void) {
buffer_free(b);
}
static void test_buffer_append_path_len(void) {
buffer *b = buffer_init();
buffer_append_path_len(b, CONST_STR_LEN("a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("/a")));
buffer_clear(b);
buffer_append_path_len(b, CONST_STR_LEN("a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("/a")));
buffer_clear(b);
buffer_append_path_len(b, CONST_STR_LEN("/a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("/a")));
buffer_copy_string_len(b, CONST_STR_LEN("/"));
buffer_append_path_len(b, CONST_STR_LEN("a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("/a")));
buffer_copy_string_len(b, CONST_STR_LEN("/"));
buffer_append_path_len(b, CONST_STR_LEN("/a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("/a")));
buffer_copy_string_len(b, CONST_STR_LEN("a"));
buffer_append_path_len(b, CONST_STR_LEN("a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("a/a")));
buffer_copy_string_len(b, CONST_STR_LEN("a/"));
buffer_append_path_len(b, CONST_STR_LEN("a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("a/a")));
buffer_copy_string_len(b, CONST_STR_LEN("a/"));
buffer_append_path_len(b, CONST_STR_LEN("/a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("a/a")));
buffer_copy_string_len(b, CONST_STR_LEN("/a/"));
buffer_append_path_len(b, CONST_STR_LEN("/a"));
assert(buffer_is_equal_string(b, CONST_STR_LEN("/a/a")));
buffer_free(b);
}
int main() {
test_buffer_path_simplify();
test_buffer_to_lower_upper();
test_buffer_string_space();
test_buffer_append_path_len();
return 0;
}

Loading…
Cancel
Save