Use buffer API to read and modify "used" member

- a lot of code tried to handle manually adding terminating zeroes and
  keeping track of the correct "used" count.
  Replaced all "external" usages with simple wrapper functions:
  * buffer_string_is_empty (used <= 1), buffer_is_empty (used == 0);
    prefer buffer_string_is_empty
  * buffer_string_set_length
  * buffer_string_length
  * CONST_BUF_LEN() macro
- removed "static" buffer hacks (buffers pointing to constant/stack
  memory instead of malloc()ed data)
- buffer_append_strftime(): refactor buffer+strftime uses
- li_tohex(): no need for a buffer for binary-to-hex conversion:
  the output data length is easy to predict
- remove "-Winline" from extra warnings: the "inline" keyword just
  supresses the warning about unused but defined (static) functions;
  don't care whether it actually gets inlined or not.

From: Stefan Bühler <stbuehler@web.de>

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2979 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.36
Stefan Bühler 2015-02-08 19:10:44 +00:00
parent adfa06de99
commit ad3e93ea96
58 changed files with 670 additions and 780 deletions

View File

@ -666,7 +666,7 @@ AC_ARG_ENABLE(extra-warnings,
esac],[extrawarnings=false])
if test x$extrawarnings = xtrue; then
TRY_CFLAGS([-g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security])
TRY_CFLAGS([-g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security])
fi
dnl build version-id

View File

@ -35,7 +35,7 @@ IF(CMAKE_COMPILER_IS_GNUCC)
OPTION(BUILD_EXTRA_WARNINGS "extra warnings")
IF(BUILD_EXTRA_WARNINGS)
SET(WARN_FLAGS "-g -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security")
SET(WARN_FLAGS "-g -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security")
# -Werror -Wbad-function-cast -Wmissing-prototypes
ELSE(BUILD_EXTRA_WARNINGS)
SET(WARN_FLAGS "")

View File

@ -98,7 +98,7 @@ static int array_get_index(array *a, const char *key, size_t keylen, int *rndx)
} else if (pos >= (int)a->used) {
pos -= i;
} else {
cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used);
cmp = buffer_caseless_compare(key, keylen, CONST_BUF_LEN(a->data[a->sorted[pos]]->key));
if (cmp == 0) {
/* found */
@ -121,7 +121,7 @@ static int array_get_index(array *a, const char *key, size_t keylen, int *rndx)
data_unset *array_get_element(array *a, const char *key) {
int ndx;
if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) {
if (-1 != (ndx = array_get_index(a, key, strlen(key), NULL))) {
/* found, leave here */
return a->data[ndx];
@ -171,7 +171,7 @@ data_unset *array_replace(array *a, data_unset *du) {
int ndx;
force_assert(NULL != du);
if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) {
if (-1 == (ndx = array_get_index(a, CONST_BUF_LEN(du->key), NULL))) {
array_insert_unique(a, du);
return NULL;
} else {
@ -187,13 +187,13 @@ int array_insert_unique(array *a, data_unset *str) {
size_t j;
/* generate unique index if neccesary */
if (str->key->used == 0 || str->is_index_key) {
if (buffer_is_empty(str->key) || str->is_index_key) {
buffer_copy_int(str->key, a->unique_ndx++);
str->is_index_key = 1;
}
/* try to find the string */
if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) {
if (-1 != (ndx = array_get_index(a, CONST_BUF_LEN(str->key), &pos))) {
/* found, leave here */
if (a->data[ndx]->type == str->type) {
str->insert_dup(a->data[ndx], str);
@ -235,7 +235,7 @@ int array_insert_unique(array *a, data_unset *str) {
if (pos != ndx &&
((pos < 0) ||
buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) {
buffer_caseless_compare(CONST_BUF_LEN(str->key), CONST_BUF_LEN(a->data[a->sorted[pos]]->key)) > 0)) {
pos++;
}

View File

@ -9,7 +9,6 @@
static const char hex_chars[] = "0123456789abcdef";
/**
* init the buffer
*
@ -83,37 +82,44 @@ static size_t buffer_align_size(size_t size) {
return size + align;
}
static char* buffer_prepare_copy(buffer *b, size_t size) {
/* make sure buffer is at least "size" big. discard old data */
static void buffer_alloc(buffer *b, size_t size) {
force_assert(NULL != b);
if (0 == size) size = 1;
/* also allocate space for terminating 0 */
/* check for overflow: unsigned overflow is defined to wrap around */
force_assert(1 + size > size);
++size;
if (size <= b->size) return;
if (0 == b->size || size > b->size) {
if (NULL != b->ptr) free(b->ptr);
b->ptr = NULL;
if (NULL != b->ptr) free(b->ptr);
b->size = buffer_align_size(size);
force_assert(b->size > 0);
b->ptr = malloc(b->size);
force_assert(NULL != b->ptr);
}
/* reset */
b->used = 0;
b->ptr[0] = '\0';
b->size = buffer_align_size(size);
b->ptr = malloc(b->size);
return b->ptr;
force_assert(NULL != b->ptr);
}
/* make sure buffer is at least "size" big. keep old data */
static void buffer_realloc(buffer *b, size_t size) {
force_assert(NULL != b);
if (0 == size) size = 1;
if (size <= b->size) return;
b->size = buffer_align_size(size);
b->ptr = realloc(b->ptr, b->size);
force_assert(NULL != b->ptr);
}
char* buffer_string_prepare_copy(buffer *b, size_t size) {
force_assert(NULL != b);
force_assert(size + 1 > size);
buffer_alloc(b, size + 1);
buffer_prepare_copy(b, size);
b->used = 1;
b->ptr[0] = '\0';
return b->ptr;
}
@ -124,28 +130,29 @@ char* buffer_string_prepare_append(buffer *b, size_t size) {
if (buffer_string_is_empty(b)) {
return buffer_string_prepare_copy(b, size);
} else {
/* not empty, b->used already includes a terminating 0 */
size_t req_size = b->used + size;
/* not empty, b->used already includes a terminating 0 */
force_assert(req_size >= b->used);
/* check for overflow: unsigned overflow is defined to wrap around */
force_assert(req_size >= b->used);
/* only append to 0-terminated string */
force_assert('\0' == b->ptr[b->used - 1]);
if (req_size > b->size) {
char *ptr;
b->size = buffer_align_size(req_size);
ptr = realloc(b->ptr, b->size);
force_assert(NULL != ptr);
b->ptr = ptr;
}
buffer_realloc(b, req_size);
return b->ptr + b->used - 1;
}
}
void buffer_string_set_length(buffer *b, size_t len) {
force_assert(NULL != b);
force_assert(len + 1 > len);
buffer_realloc(b, len + 1);
b->used = len + 1;
b->ptr[len] = '\0';
}
void buffer_commit(buffer *b, size_t size)
{
@ -182,7 +189,8 @@ void buffer_copy_string_len(buffer *b, const char *s, size_t s_len) {
void buffer_copy_buffer(buffer *b, const buffer *src) {
if (NULL == src || 0 == src->used) {
buffer_prepare_copy(b, 0);
buffer_string_prepare_copy(b, 0);
b->used = 0; /* keep special empty state for now */
} else {
buffer_copy_string_len(b, src->ptr, buffer_string_length(src));
}
@ -301,6 +309,37 @@ void buffer_copy_int(buffer *b, intmax_t val) {
buffer_append_int(b, val);
}
void buffer_append_strftime(buffer *b, const char *format, const struct tm *tm) {
size_t r;
char* buf;
force_assert(NULL != b);
force_assert(NULL != tm);
if (NULL == format || '\0' == format[0]) {
/* empty format */
buffer_string_prepare_append(b, 0);
return;
}
buf = buffer_string_prepare_append(b, 255);
r = strftime(buf, buffer_string_space(b), format, tm);
/* 0 (in some apis buffer_string_space(b)) signals the string may have
* been too small; but the format could also just have lead to an empty
* string
*/
if (0 == r || r >= buffer_string_space(b)) {
/* give it a second try with a larger string */
buf = buffer_string_prepare_append(b, 4095);
r = strftime(buf, buffer_string_space(b), format, tm);
}
if (r >= buffer_string_space(b)) r = 0;
buffer_commit(b, r);
}
void li_itostrn(char *buf, size_t buf_len, intmax_t val) {
char p_buf[LI_ITOSTRING_LENGTH];
char* const p_buf_end = p_buf + sizeof(p_buf);
@ -446,20 +485,22 @@ int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) {
return 0 == memcmp(b1->ptr + b1->used - 1 - len, b2->ptr + b2->used - 1 - len, len);
}
void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
void li_tohex(char *buf, const char *s, size_t s_len) {
size_t i;
/* overflow protection */
force_assert(in_len * 2 + 1 > in_len);
buffer_prepare_copy(b, in_len * 2);
b->used = 0;
for (i = 0; i < in_len; i++) {
b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F];
b->ptr[b->used++] = hex_chars[in[i] & 0x0F];
for (i = 0; i < s_len; i++) {
buf[2*i] = hex_chars[(s[i] >> 4) & 0x0F];
buf[2*i+1] = hex_chars[s[i] & 0x0F];
}
b->ptr[b->used++] = '\0';
buf[2*s_len] = '\0';
}
void buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) {
/* overflow protection */
force_assert(in_len * 2 > in_len);
buffer_string_set_length(b, 2 * in_len);
li_tohex(b->ptr, in, in_len);
}
/* everything except: ! ( ) * - . 0-9 A-Z _ a-z */
@ -882,8 +923,7 @@ void buffer_path_simplify(buffer *dest, buffer *src)
walk++;
}
*out = '\0';
dest->used = (out - start) + 1;
buffer_string_set_length(dest, out - start);
}
int light_isdigit(int c) {

View File

@ -10,6 +10,7 @@
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <time.h>
#if defined HAVE_STDINT_H
# include <stdint.h>
@ -71,6 +72,13 @@ char* buffer_string_prepare_append(buffer *b, size_t size);
*/
void buffer_commit(buffer *b, size_t size);
/* sets string length:
* - always stores a terminating zero to terminate the "new" string
* - does not modify the string data apart from terminating zero
* - reallocates the buffer iff needed
*/
void buffer_string_set_length(buffer *b, size_t len);
void buffer_copy_string(buffer *b, const char *s);
void buffer_copy_string_len(buffer *b, const char *s, size_t s_len);
void buffer_copy_buffer(buffer *b, const buffer *src);
@ -85,6 +93,8 @@ void buffer_append_long_hex(buffer *b, unsigned long len);
void buffer_append_int(buffer *b, intmax_t val);
void buffer_copy_int(buffer *b, intmax_t val);
void buffer_append_strftime(buffer *b, const char *format, const struct tm *tm);
/* '-', log_10 (2^bits) = bits * log 2 / log 10 < bits * 0.31, terminating 0 */
#define LI_ITOSTRING_LENGTH (2 + (8 * sizeof(intmax_t) * 31 + 99) / 100)
@ -93,6 +103,9 @@ void li_itostr(char *buf, intmax_t val); /* buf must have at least LI_ITOSTRING_
void li_utostrn(char *buf, size_t buf_len, uintmax_t val);
void li_utostr(char *buf, uintmax_t val); /* buf must have at least LI_ITOSTRING_LENGTH bytes */
/* buf must be (at least) 2*s_len + 1 big. uses lower-case hex letters. */
void li_tohex(char *buf, const char *s, size_t s_len);
char * buffer_search_string_len(buffer *b, const char *needle, size_t len);
/* NULL buffer or empty buffer (used == 0);

View File

@ -264,10 +264,11 @@ void chunkqueue_get_memory(chunkqueue *cq, char **mem, size_t *len, size_t min_s
}
/* if buffer is really small just make it bigger */
else if (have < min_size && b->size <= REALLOC_MAX_SIZE) {
size_t new_size = b->used + min_size, append;
size_t cur_len = buffer_string_length(b);
size_t new_size = cur_len + min_size, append;
if (new_size < alloc_size) new_size = alloc_size;
append = new_size - b->used;
append = new_size - cur_len;
if (append >= min_size) {
buffer_string_prepare_append(b, append);
have = buffer_string_space(b);
@ -301,12 +302,8 @@ void chunkqueue_use_memory(chunkqueue *cq, size_t len) {
force_assert(NULL != cq->last && MEM_CHUNK == cq->last->type);
b = cq->last->mem;
force_assert(b->used > 0);
force_assert(len <= buffer_string_space(b));
if (len > 0) {
b->used += len;
b->ptr[b->used - 1] = '\0';
buffer_commit(b, len);
} else if (buffer_string_is_empty(b)) {
/* unused buffer: can't remove chunk easily from
* end of list, so just reset the buffer

View File

@ -491,7 +491,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat
#ifndef elementsof
#define elementsof(x) (sizeof(x) / sizeof(x[0]))
#endif
n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0,
n = pcre_exec(dc->regex, dc->regex_study, CONST_BUF_LEN(l), 0, 0,
cache->matches, elementsof(cache->matches));
cache->patterncount = n;

View File

@ -1130,7 +1130,7 @@ int config_read(server *srv, const char *fn) {
dcwd = data_string_init();
buffer_string_prepare_copy(dcwd->value, 1023);
if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {
dcwd->value->used = strlen(dcwd->value->ptr) + 1;
buffer_commit(dcwd->value, strlen(dcwd->value->ptr));
buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD"));
array_insert_unique(srv->config, (data_unset *)dcwd);
} else {
@ -1320,7 +1320,7 @@ int config_set_defaults(server *srv) {
srv->srvconf.port = s->ssl_enabled ? 443 : 80;
}
if (srv->srvconf.event_handler->used == 0) {
if (buffer_string_is_empty(srv->srvconf.event_handler)) {
/* choose a good default
*
* the event_handler list is sorted by 'goodness'

View File

@ -400,7 +400,7 @@ static int connection_handle_write_prepare(server *srv, connection *con) {
* 403 is from the response handler when noone else catched it
*
* */
if ((!con->http_status || con->http_status == 200) && con->uri.path->used &&
if ((!con->http_status || con->http_status == 200) && !buffer_string_is_empty(con->uri.path) &&
con->uri.path->ptr[0] != '*') {
response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST"));
@ -873,42 +873,7 @@ static int connection_handle_read_state(server *srv, connection *con) {
}
}
/* the last chunk might be empty */
for (c = cq->first; c;) {
if (cq->first == c && c->mem->used == 0) {
/* the first node is empty */
/* ... and it is empty, move it to unused */
cq->first = c->next;
if (cq->first == NULL) cq->last = NULL;
c->next = cq->unused;
cq->unused = c;
cq->unused_chunks++;
c = cq->first;
} else if (c->next && c->next->mem->used == 0) {
chunk *fc;
/* next node is the last one */
/* ... and it is empty, move it to unused */
fc = c->next;
c->next = fc->next;
fc->next = cq->unused;
cq->unused = fc;
cq->unused_chunks++;
/* the last node was empty */
if (c->next == NULL) {
cq->last = c;
}
c = c->next;
} else {
c = c->next;
}
}
chunkqueue_remove_finished_chunks(cq);
/* we might have got several packets at once
*/
@ -927,15 +892,12 @@ static int connection_handle_read_state(server *srv, connection *con) {
last_offset = 0;
for (c = cq->first; c; c = c->next) {
buffer b;
size_t i;
size_t len = buffer_string_length(c->mem) - c->offset;
const char *b = c->mem->ptr + c->offset;
b.ptr = c->mem->ptr + c->offset;
b.used = c->mem->used - c->offset;
if (b.used > 0) b.used--; /* buffer "used" includes terminating zero */
for (i = 0; i < b.used; i++) {
char ch = b.ptr[i];
for (i = 0; i < len; ++i) {
char ch = b[i];
if ('\r' == ch) {
/* chec if \n\r\n follows */
@ -945,13 +907,11 @@ static int connection_handle_read_state(server *srv, connection *con) {
int header_end_match_pos = 1;
for ( ; cc; cc = cc->next, j = 0 ) {
buffer bb;
bb.ptr = cc->mem->ptr + cc->offset;
bb.used = cc->mem->used - cc->offset;
if (bb.used > 0) bb.used--; /* buffer "used" includes terminating zero */
size_t bblen = buffer_string_length(cc->mem) - cc->offset;
const char *bb = c->mem->ptr + cc->offset;
for ( ; j < bb.used; j++) {
ch = bb.ptr[j];
for ( ; j < bblen; j++) {
ch = bb[j];
if (ch == header_end[header_end_match_pos]) {
header_end_match_pos++;
@ -976,25 +936,16 @@ found_header_end:
buffer_reset(con->request.request);
for (c = cq->first; c; c = c->next) {
buffer b;
b.ptr = c->mem->ptr + c->offset;
b.used = c->mem->used - c->offset;
size_t len = buffer_string_length(c->mem) - c->offset;
if (c == last_chunk) {
b.used = last_offset + 1;
len = last_offset;
}
buffer_append_string_buffer(con->request.request, &b);
buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, len);
c->offset += len;
if (c == last_chunk) {
c->offset += last_offset;
break;
} else {
/* the whole packet was copied */
c->offset = c->mem->used - 1;
}
if (c == last_chunk) break;
}
connection_set_state(srv, con, CON_STATE_REQUEST_END);

View File

@ -36,7 +36,7 @@ static int data_string_insert_dup(data_unset *dst, data_unset *src) {
data_string *ds_dst = (data_string *)dst;
data_string *ds_src = (data_string *)src;
if (ds_dst->value->used) {
if (!buffer_is_empty(ds_dst->value)) {
buffer_append_string_len(ds_dst->value, CONST_STR_LEN(", "));
buffer_append_string_buffer(ds_dst->value, ds_src->value);
} else {
@ -52,7 +52,7 @@ static int data_response_insert_dup(data_unset *dst, data_unset *src) {
data_string *ds_dst = (data_string *)dst;
data_string *ds_src = (data_string *)src;
if (ds_dst->value->used) {
if (!buffer_is_empty(ds_dst->value)) {
buffer_append_string_len(ds_dst->value, CONST_STR_LEN("\r\n"));
buffer_append_string_buffer(ds_dst->value, ds_dst->key);
buffer_append_string_len(ds_dst->value, CONST_STR_LEN(": "));
@ -69,18 +69,19 @@ static int data_response_insert_dup(data_unset *dst, data_unset *src) {
static void data_string_print(const data_unset *d, int depth) {
data_string *ds = (data_string *)d;
unsigned int i;
size_t i, len;
UNUSED(depth);
/* empty and uninitialized strings */
if (ds->value->used < 1) {
if (buffer_string_is_empty(ds->value)) {
fputs("\"\"", stdout);
return;
}
/* print out the string as is, except prepend " with backslash */
putc('"', stdout);
for (i = 0; i < ds->value->used - 1; i++) {
len = buffer_string_length(ds->value);
for (i = 0; i < len; i++) {
unsigned char c = ds->value->ptr[i];
if (c == '"') {
fputs("\\\"", stdout);

View File

@ -37,10 +37,11 @@ int etag_create(buffer *etag, struct stat *st,etag_flags_t flags) {
}
int etag_mutate(buffer *mut, buffer *etag) {
size_t i;
size_t i, len;
uint32_t h;
for (h=0, i=0; i < etag->used-1; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
len = buffer_string_length(etag);
for (h=0, i=0; i < len; ++i) h = (h<<5)^(h>>27)^(etag->ptr[i]);
buffer_reset(mut);
buffer_copy_string_len(mut, CONST_STR_LEN("\""));

View File

@ -125,7 +125,7 @@ int http_response_redirect_to_directory(server *srv, connection *con) {
buffer_copy_buffer(o, con->uri.scheme);
buffer_append_string_len(o, CONST_STR_LEN("://"));
if (con->uri.authority->used) {
if (!buffer_is_empty(con->uri.authority)) {
buffer_append_string_buffer(o, con->uri.authority);
} else {
/* get the name of the currently connected socket */
@ -237,10 +237,7 @@ buffer * strftime_cache_get(server *srv, time_t last_mod) {
srv->mtime_cache[i].mtime = last_mod;
buffer_string_prepare_copy(srv->mtime_cache[i].str, 1023);
tm = gmtime(&(srv->mtime_cache[i].mtime));
srv->mtime_cache[i].str->used = strftime(srv->mtime_cache[i].str->ptr,
srv->mtime_cache[i].str->size - 1,
"%a, %d %b %Y %H:%M:%S GMT", tm);
srv->mtime_cache[i].str->used++;
buffer_append_strftime(srv->mtime_cache[i].str, "%a, %d %b %Y %H:%M:%S GMT", tm);
return srv->mtime_cache[i].str;
}

View File

@ -39,13 +39,7 @@ typedef unsigned char HASH[HASHLEN];
typedef char HASHHEX[HASHHEXLEN+1];
static void CvtHex(const HASH Bin, char Hex[33]) {
unsigned short i;
for (i = 0; i < 16; i++) {
Hex[i*2] = int2hex((Bin[i] >> 4) & 0xf);
Hex[i*2+1] = int2hex(Bin[i] & 0xf);
}
Hex[32] = '\0';
li_tohex(Hex, (const char*) Bin, 16);
}
/**
@ -97,9 +91,7 @@ static unsigned char * base64_decode(buffer *out, const char *in) {
size_t in_len = strlen(in);
buffer_string_prepare_copy(out, in_len);
result = (unsigned char *)out->ptr;
result = (unsigned char *) buffer_string_prepare_copy(out, in_len);
/* run through the whole string, converting as we go */
for (i = 0; i < in_len; i++) {
@ -157,8 +149,7 @@ static unsigned char * base64_decode(buffer *out, const char *in) {
break;
}
result[j] = '\0';
out->used = j;
buffer_commit(out, j);
return result;
}
@ -166,7 +157,7 @@ static unsigned char * base64_decode(buffer *out, const char *in) {
static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *username, buffer *realm, buffer *password) {
int ret = -1;
if (!username->used|| !realm->used) return -1;
if (buffer_is_empty(username) || buffer_is_empty(realm)) return -1;
if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
stream f;
@ -226,8 +217,8 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
pwd_len = f.size - (f_pwd - f.start);
}
if (username->used - 1 == u_len &&
(realm->used - 1 == r_len) &&
if (buffer_string_length(username) == u_len &&
(buffer_string_length(realm) == r_len) &&
(0 == strncmp(username->ptr, f_user, u_len)) &&
(0 == strncmp(realm->ptr, f_realm, r_len))) {
/* found */
@ -296,7 +287,7 @@ static int http_auth_get_password(server *srv, mod_auth_plugin_data *p, buffer *
pwd_len = f.size - (f_pwd - f.start);
}
if (username->used - 1 == u_len &&
if (buffer_string_length(username) == u_len &&
(0 == strncmp(username->ptr, f_user, u_len))) {
/* found */
@ -652,10 +643,10 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
char a1[256];
li_MD5_Init(&Md5Ctx);
li_MD5_Update(&Md5Ctx, (unsigned char *)username->ptr, username->used - 1);
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, (unsigned char *)realm->ptr, realm->used - 1);
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(username));
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(realm));
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)pw, strlen(pw));
li_MD5_Final(HA1, &Md5Ctx);
@ -682,7 +673,7 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
char *crypted;
/* a simple DES password is 2 + 11 characters. everything else should be longer. */
if (password->used < 13 + 1) {
if (buffer_string_length(password) < 13) {
return -1;
}
@ -707,7 +698,7 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
char *dn;
int ret;
char *attrs[] = { LDAP_NO_ATTRS, NULL };
size_t i;
size_t i, len;
/* for now we stay synchronous */
@ -726,7 +717,8 @@ static int http_auth_basic_password_compare(server *srv, mod_auth_plugin_data *p
* a unpleasant way
*/
for (i = 0; i < username->used - 1; i++) {
len = buffer_string_length(username);
for (i = 0; i < len; i++) {
char c = username->ptr[i];
if (!isalpha(c) &&
@ -863,9 +855,8 @@ int http_auth_basic_check(server *srv, connection *con, mod_auth_plugin_data *p,
return 0;
}
*pw++ = '\0';
username->used = pw - username->ptr;
buffer_string_set_length(username, pw - username->ptr);
pw++;
password = buffer_init();
/* copy password to r1 */
@ -1084,10 +1075,10 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
/* generate password from plain-text */
li_MD5_Init(&Md5Ctx);
li_MD5_Update(&Md5Ctx, (unsigned char *)username, strlen(username));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)realm, strlen(realm));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, (unsigned char *)password->ptr, password->used - 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(password));
li_MD5_Final(HA1, &Md5Ctx);
} else if (p->conf.auth_backend == AUTH_BACKEND_HTDIGEST) {
/* HA1 */
@ -1109,9 +1100,9 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
/* Errata ID 1649: http://www.rfc-editor.org/errata_search.php?rfc=2617 */
CvtHex(HA1, a1);
li_MD5_Update(&Md5Ctx, (unsigned char *)a1, 32);
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
li_MD5_Final(HA1, &Md5Ctx);
}
@ -1121,12 +1112,12 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
/* calculate H(A2) */
li_MD5_Init(&Md5Ctx);
li_MD5_Update(&Md5Ctx, (unsigned char *)m, strlen(m));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)uri, strlen(uri));
/* qop=auth-int not supported, already checked above */
/*
if (qop && strcasecmp(qop, "auth-int") == 0) {
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *) [body checksum], HASHHEXLEN);
}
*/
@ -1136,16 +1127,16 @@ int http_auth_digest_check(server *srv, connection *con, mod_auth_plugin_data *p
/* calculate response */
li_MD5_Init(&Md5Ctx);
li_MD5_Update(&Md5Ctx, (unsigned char *)a1, HASHHEXLEN);
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)nonce, strlen(nonce));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
if (qop && *qop) {
li_MD5_Update(&Md5Ctx, (unsigned char *)nc, strlen(nc));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)cnonce, strlen(cnonce));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
li_MD5_Update(&Md5Ctx, (unsigned char *)qop, strlen(qop));
li_MD5_Update(&Md5Ctx, (unsigned char *)":", 1);
li_MD5_Update(&Md5Ctx, CONST_STR_LEN(":"));
};
li_MD5_Update(&Md5Ctx, (unsigned char *)HA2Hex, HASHHEXLEN);
li_MD5_Final(RespHash, &Md5Ctx);
@ -1198,8 +1189,8 @@ int http_auth_digest_generate_nonce(server *srv, mod_auth_plugin_data *p, buffer
/* generate shared-secret */
li_MD5_Init(&Md5Ctx);
li_MD5_Update(&Md5Ctx, (unsigned char *)fn->ptr, fn->used - 1);
li_MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
li_MD5_Update(&Md5Ctx, CONST_BUF_LEN(fn));
li_MD5_Update(&Md5Ctx, CONST_STR_LEN("+"));
/* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
li_itostr(hh, srv->cur_ts);

View File

@ -42,8 +42,7 @@ static void http_chunk_append_len(server *srv, connection *con, size_t len) {
b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
len >>= 4;
}
b->used = i;
b->ptr[b->used++] = '\0';
buffer_commit(b, i);
buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
}
@ -82,7 +81,7 @@ void http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
cq = con->write_queue;
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
http_chunk_append_len(srv, con, mem->used - 1);
http_chunk_append_len(srv, con, buffer_string_length(mem));
}
chunkqueue_append_buffer(cq, mem);

View File

@ -333,8 +333,7 @@ static int log_buffer_prepare(buffer *b, server *srv, const char *filename, unsi
/* cache the generated timestamp */
if (srv->cur_ts != srv->last_generated_debug_ts) {
buffer_string_prepare_copy(srv->ts_debug_str, 255);
strftime(srv->ts_debug_str->ptr, srv->ts_debug_str->size - 1, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
srv->ts_debug_str->used = strlen(srv->ts_debug_str->ptr) + 1;
buffer_append_strftime(srv->ts_debug_str, "%Y-%m-%d %H:%M:%S", localtime(&(srv->cur_ts)));
srv->last_generated_debug_ts = srv->cur_ts;
}
@ -362,8 +361,7 @@ static void log_write(server *srv, buffer *b) {
case ERRORLOG_FILE:
case ERRORLOG_FD:
buffer_append_string_len(b, CONST_STR_LEN("\n"));
force_assert(b->used > 0);
write(srv->errorlog_fd, b->ptr, b->used - 1);
write(srv->errorlog_fd, CONST_BUF_LEN(b));
break;
case ERRORLOG_SYSLOG:
syslog(LOG_ERR, "%s", b->ptr);
@ -387,11 +385,11 @@ int log_error_write(server *srv, const char *filename, unsigned int line, const
int log_error_write_multiline_buffer(server *srv, const char *filename, unsigned int line, buffer *multiline, const char *fmt, ...) {
va_list ap;
size_t prefix_used;
size_t prefix_len;
buffer *b = srv->errorlog_buf;
char *pos, *end, *current_line;
if (multiline->used < 2) return 0;
if (buffer_string_is_empty(multiline)) return 0;
if (-1 == log_buffer_prepare(b, srv, filename, line)) return 0;
@ -399,20 +397,19 @@ int log_error_write_multiline_buffer(server *srv, const char *filename, unsigned
log_buffer_append_printf(b, fmt, ap);
va_end(ap);
prefix_used = b->used;
prefix_len = buffer_string_length(b);
current_line = pos = multiline->ptr;
end = multiline->ptr + multiline->used;
end = multiline->ptr + buffer_string_length(multiline);
for ( ; pos < end ; ++pos) {
for ( ; pos <= end ; ++pos) {
switch (*pos) {
case '\n':
case '\r':
case '\0': /* handles end of string */
if (current_line < pos) {
/* truncate to prefix */
b->used = prefix_used;
b->ptr[b->used - 1] = '\0';
buffer_string_set_length(b, prefix_len);
buffer_append_string_len(b, current_line, pos - current_line);
log_write(srv, b);

View File

@ -125,11 +125,11 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
int s_len;
size_t k;
if (con->uri.path->used == 0) return HANDLER_GO_ON;
if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
mod_access_patch_connection(srv, con, p);
s_len = con->uri.path->used - 1;
s_len = buffer_string_length(con->uri.path);
if (con->conf.log_request_handling) {
log_error_write(srv, __FILE__, __LINE__, "s",
@ -138,12 +138,12 @@ URIHANDLER_FUNC(mod_access_uri_handler) {
for (k = 0; k < p->conf.access_deny->used; k++) {
data_string *ds = (data_string *)p->conf.access_deny->data[k];
int ct_len = ds->value->used - 1;
int ct_len = buffer_string_length(ds->value);
int denied = 0;
if (ct_len > s_len) continue;
if (ds->value->used == 0) continue;
if (buffer_is_empty(ds->value)) continue;
/* if we have a case-insensitive FS we have to lower-case the URI here too */

View File

@ -223,9 +223,9 @@ static void accesslog_append_escaped(buffer *dest, buffer *str) {
static int accesslog_parse_format(server *srv, format_fields *fields, buffer *format) {
size_t i, j, k = 0, start = 0;
if (format->used == 0) return -1;
if (buffer_is_empty(format)) return -1;
for (i = 0; i < format->used - 1; i++) {
for (i = 0; i < buffer_string_length(format); i++) {
switch(format->ptr[i]) {
case '%':
if (i > 0 && start != i) {
@ -297,11 +297,11 @@ static int accesslog_parse_format(server *srv, format_fields *fields, buffer *fo
case '{':
/* go forward to } */
for (k = i+2; k < format->used - 1; k++) {
for (k = i+2; k < buffer_string_length(format); k++) {
if (format->ptr[k] == '}') break;
}
if (k == format->used - 1) {
if (k == buffer_string_length(format)) {
log_error_write(srv, __FILE__, __LINE__, "s", "%{ has to be terminated by a }");
return -1;
}
@ -416,9 +416,9 @@ FREE_FUNC(mod_accesslog_free) {
if (!s) continue;
if (s->access_logbuffer->used) {
if (!buffer_string_is_empty(s->access_logbuffer)) {
if (s->log_access_fd != -1) {
write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
write(s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
}
}
@ -502,7 +502,7 @@ SETDEFAULTS_FUNC(log_access_open) {
/* parse */
if (s->format->used) {
if (!buffer_is_empty(s->format)) {
size_t j, count;
s->parsed_format = calloc(1, sizeof(*(s->parsed_format)));
@ -572,7 +572,7 @@ SETDEFAULTS_FUNC(log_access_open) {
continue;
}
if (s->access_logfile->used < 2) continue;
if (buffer_string_is_empty(s->access_logfile)) continue;
if (-1 == (s->log_access_fd = open_logfile_or_pipe(srv, s->access_logfile->ptr)))
return HANDLER_ERROR;
@ -591,17 +591,17 @@ SIGHUP_FUNC(log_access_cycle) {
for (i = 0; i < srv->config_context->used; i++) {
plugin_config *s = p->config_storage[i];
if (s->access_logbuffer->used) {
if (!buffer_string_is_empty(s->access_logbuffer)) {
if (s->log_access_fd != -1) {
write(s->log_access_fd, s->access_logbuffer->ptr, s->access_logbuffer->used - 1);
write(s->log_access_fd, CONST_BUF_LEN(s->access_logbuffer));
}
buffer_reset(s->access_logbuffer);
}
if (s->use_syslog == 0 &&
s->access_logfile->used > 1 &&
s->access_logfile->ptr[0] != '|') {
if (s->use_syslog == 0
&& !buffer_string_is_empty(s->access_logfile)
&& s->access_logfile->ptr[0] != '|') {
if (-1 != s->log_access_fd) close(s->log_access_fd);
@ -691,8 +691,8 @@ REQUESTDONE_FUNC(log_access_write) {
b = p->conf.access_logbuffer;
}
if (b->used == 0) {
buffer_copy_string_len(b, CONST_STR_LEN(""));
if (buffer_is_empty(b)) {
buffer_string_set_length(b, 0);
}
for (j = 0; j < p->conf.parsed_format->used; j++) {
@ -715,11 +715,10 @@ REQUESTDONE_FUNC(log_access_write) {
#if defined(HAVE_STRUCT_TM_GMTOFF)
# ifdef HAVE_LOCALTIME_R
localtime_r(&(srv->cur_ts), &tm);
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm);
buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, &tm);
# else /* HAVE_LOCALTIME_R */
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, localtime_r(&(srv->cur_ts)));
buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, localtime(&(srv->cur_ts)));
# endif /* HAVE_LOCALTIME_R */
p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
if (p->conf.append_tz_offset) {
buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1);
@ -739,11 +738,10 @@ REQUESTDONE_FUNC(log_access_write) {
#else /* HAVE_STRUCT_TM_GMTOFF */
# ifdef HAVE_GMTIME_R
gmtime_r(&(srv->cur_ts), &tm);
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm);
buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, &tm);
# else /* HAVE_GMTIME_R */
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, gmtime(&(srv->cur_ts)));
buffer_append_strftime(p->conf.ts_accesslog_str, p->conf.ts_accesslog_fmt_str->ptr, gmtime(&(srv->cur_ts)));
# endif /* HAVE_GMTIME_R */
p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1;
#endif /* HAVE_STRUCT_TM_GMTOFF */
*(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts;
@ -765,14 +763,14 @@ REQUESTDONE_FUNC(log_access_write) {
buffer_append_string_len(b, CONST_STR_LEN("-"));
break;
case FORMAT_REMOTE_USER:
if (NULL != (ds = (data_string *)array_get_element(con->environment, "REMOTE_USER")) && ds->value->used > 1) {
if (NULL != (ds = (data_string *)array_get_element(con->environment, "REMOTE_USER")) && !buffer_string_is_empty(ds->value)) {
accesslog_append_escaped(b, ds->value);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
}
break;
case FORMAT_REQUEST_LINE:
if (con->request.request_line->used) {
if (!buffer_string_is_empty(con->request.request_line)) {
accesslog_append_escaped(b, con->request.request_line);
}
break;
@ -810,7 +808,7 @@ REQUESTDONE_FUNC(log_access_write) {
}
break;
case FORMAT_FILENAME:
if (con->physical.path->used > 1) {
if (!buffer_string_is_empty(con->physical.path)) {
buffer_append_string_buffer(b, con->physical.path);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
@ -834,14 +832,14 @@ REQUESTDONE_FUNC(log_access_write) {
buffer_append_int(b, srv->cur_ts - con->request_start);
break;
case FORMAT_SERVER_NAME:
if (con->server_name->used > 1) {
if (!buffer_string_is_empty(con->server_name)) {
buffer_append_string_buffer(b, con->server_name);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
}
break;
case FORMAT_HTTP_HOST:
if (con->uri.authority->used > 1) {
if (!buffer_string_is_empty(con->uri.authority)) {
accesslog_append_escaped(b, con->uri.authority);
} else {
buffer_append_string_len(b, CONST_STR_LEN("-"));
@ -849,7 +847,7 @@ REQUESTDONE_FUNC(log_access_write) {
break;
case FORMAT_REQUEST_PROTOCOL:
buffer_append_string_len(b,
con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0", 8);
con->request.http_version == HTTP_VERSION_1_1 ? "HTTP/1.1" : "HTTP/1.0", 8);
break;
case FORMAT_REQUEST_METHOD:
buffer_append_string(b, get_http_method_name(con->request.http_method));
@ -904,19 +902,19 @@ REQUESTDONE_FUNC(log_access_write) {
buffer_append_string_len(b, CONST_STR_LEN("\n"));
if (p->conf.use_syslog || /* syslog doesn't cache */
(p->conf.access_logfile->used && p->conf.access_logfile->ptr[0] == '|') || /* pipes don't cache */
(!buffer_string_is_empty(p->conf.access_logfile) && p->conf.access_logfile->ptr[0] == '|') || /* pipes don't cache */
newts ||
b->used > BUFFER_MAX_REUSE_SIZE) {
buffer_string_length(b) >= BUFFER_MAX_REUSE_SIZE) {
if (p->conf.use_syslog) {
#ifdef HAVE_SYSLOG_H
if (b->used > 2) {
if (!buffer_string_is_empty(b)) {
/* syslog appends a \n on its own */
syslog(p->conf.syslog_level, "%*s", (int) b->used - 2, b->ptr);
buffer_string_set_length(b, buffer_string_length(b) - 1);
syslog(p->conf.syslog_level, "%s", b->ptr);
}
#endif
} else if (p->conf.log_access_fd != -1) {
force_assert(b->used > 0);
write(p->conf.log_access_fd, b->ptr, b->used - 1);
write(p->conf.log_access_fd, CONST_BUF_LEN(b));
}
buffer_reset(b);
}

View File

@ -95,10 +95,10 @@ SETDEFAULTS_FUNC(mod_alias_set_defaults) {
for (k = j + 1; k < a->used; k ++) {
const buffer *key = a->data[a->sorted[k]]->key;
if (key->used < prefix->used) {
if (buffer_string_length(key) < buffer_string_length(prefix)) {
break;
}
if (memcmp(key->ptr, prefix->ptr, prefix->used - 1) != 0) {
if (memcmp(key->ptr, prefix->ptr, buffer_string_length(prefix)) != 0) {
break;
}
/* ok, they have same prefix. check position */
@ -151,22 +151,22 @@ PHYSICALPATH_FUNC(mod_alias_physical_handler) {
char *uri_ptr;
size_t k;
if (con->physical.path->used == 0) return HANDLER_GO_ON;
if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
mod_alias_patch_connection(srv, con, p);
/* not to include the tailing slash */
basedir_len = (con->physical.basedir->used - 1);
basedir_len = buffer_string_length(con->physical.basedir);
if ('/' == con->physical.basedir->ptr[basedir_len-1]) --basedir_len;
uri_len = con->physical.path->used - 1 - basedir_len;
uri_len = buffer_string_length(con->physical.path) - basedir_len;
uri_ptr = con->physical.path->ptr + basedir_len;
for (k = 0; k < p->conf.alias->used; k++) {
data_string *ds = (data_string *)p->conf.alias->data[k];
int alias_len = ds->key->used - 1;
int alias_len = buffer_string_length(ds->key);
if (alias_len > uri_len) continue;
if (ds->key->used == 0) continue;
if (buffer_is_empty(ds->key)) continue;