diff --git a/src/http.c b/src/http.c index 5296d75..ef4ea9a 100644 --- a/src/http.c +++ b/src/http.c @@ -168,7 +168,6 @@ http_response_write(struct http_response *r, int fd) { char *p; int i, ret; - /*r->keep_alive = 0;*/ r->out_sz = sizeof("HTTP/1.x xxx ")-1 + strlen(r->msg) + 2; r->out = calloc(r->out_sz + 1, 1); @@ -178,7 +177,7 @@ http_response_write(struct http_response *r, int fd) { if(!r->chunked) { if(r->code == 200 && r->body) { - char content_length[10]; + char content_length[22]; sprintf(content_length, "%zd", r->body_len); http_response_set_header(r, "Content-Length", content_length); } else { diff --git a/src/jansson/src/dump.c b/src/jansson/src/dump.c index 42eb256..a75dc65 100644 --- a/src/jansson/src/dump.c +++ b/src/jansson/src/dump.c @@ -78,7 +78,7 @@ static int dump_string(const char *str, int ascii, dump_func dump, void *data) while(1) { const char *text; - char seq[13]; + char seq[22]; int length; while(*end) diff --git a/src/jansson/src/load.c b/src/jansson/src/load.c index f05230b..a4c8e93 100644 --- a/src/jansson/src/load.c +++ b/src/jansson/src/load.c @@ -59,6 +59,13 @@ typedef struct { /*** error reporting ***/ +/* disable format truncation warnings for this function. + it's not a security issue; very long strings could just be truncated on error + */ +#if (defined(__GNUC__) && !defined(__clang__)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-truncation" +#endif static void error_set(json_error_t *error, const lex_t *lex, const char *msg, ...) @@ -101,6 +108,9 @@ static void error_set(json_error_t *error, const lex_t *lex, jsonp_error_set(error, line, col, "%s", result); } +#if (defined(__GNUC__) && !defined(__clang__)) +#pragma GCC diagnostic pop +#endif /*** lexical analyzer ***/ @@ -261,7 +271,7 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) /* control character */ lex_unget_unsave(lex, c); if(c == '\n') - error_set(error, lex, "unexpected newline", c); + error_set(error, lex, "unexpected newline"); else error_set(error, lex, "control character 0x%x", c); goto out; diff --git a/src/jansson/src/utf.c b/src/jansson/src/utf.c index 92484d0..eb20f78 100644 --- a/src/jansson/src/utf.c +++ b/src/jansson/src/utf.c @@ -51,7 +51,7 @@ int utf8_check_first(char byte) if(u < 0x80) return 1; - if(0x80 <= u && u <= 0xBF) { + if(/* 0x80 <= u && */u <= 0xBF) { /* second, third or fourth byte of a multi-byte sequence, i.e. a "continuation byte" */ return 0; @@ -60,16 +60,16 @@ int utf8_check_first(char byte) /* overlong encoding of an ASCII byte */ return 0; } - else if(0xC2 <= u && u <= 0xDF) { + else if(/*0xC2 <= u && */u <= 0xDF) { /* 2-byte sequence */ return 2; } - else if(0xE0 <= u && u <= 0xEF) { + else if(/*0xE0 <= u && */u <= 0xEF) { /* 3-byte sequence */ return 3; } - else if(0xF0 <= u && u <= 0xF4) { + else if(/*0xF0 <= u && */u <= 0xF4) { /* 4-byte sequence */ return 4; } diff --git a/src/pool.c b/src/pool.c index 262f9ba..706006b 100644 --- a/src/pool.c +++ b/src/pool.c @@ -97,7 +97,14 @@ pool_on_disconnect(const redisAsyncContext *ac, int status) { struct pool *p = ac->data; int i = 0; if (status != REDIS_OK) { - /* fprintf(stderr, "Error: %s\n", ac->errstr); */ + char format[] = "Error disconnecting: %s"; + size_t msg_sz = sizeof(format) - 2 + ((ac && ac->errstr) ? strlen(ac->errstr) : 6); + char *log_msg = calloc(msg_sz + 1, 1); + if(log_msg) { + snprintf(log_msg, msg_sz + 1, format, ((ac && ac->errstr) ? ac->errstr : "(null)")); + slog(p->w->s, WEBDIS_ERROR, log_msg, msg_sz-1); + free(log_msg); + } } if(p == NULL) { /* no need to clean anything here. */ diff --git a/src/server.c b/src/server.c index 39b4bbe..3ddd8ad 100644 --- a/src/server.c +++ b/src/server.c @@ -16,6 +16,7 @@ #include #include #include +#include /** * Sets up a non-blocking socket @@ -147,7 +148,7 @@ server_can_accept(int fd, short event, void *ptr) { * (taken from Redis) */ static void -server_daemonize(const char *pidfile) { +server_daemonize(struct server *s, const char *pidfile) { int fd; if (fork() != 0) exit(0); /* parent exits */ @@ -162,11 +163,25 @@ server_daemonize(const char *pidfile) { } /* write pidfile */ - if (pidfile) { - FILE *f = fopen(pidfile, "w"); - if (f) { - fprintf(f, "%d\n", (int)getpid()); - fclose(f); + if(pidfile) { + int pid_fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600); + if(pid_fd > 0) { + char pid_buffer[(CHAR_BIT * sizeof(int) / 3) + 3]; /* max length for int */ + int pid_sz = snprintf(pid_buffer, sizeof(pid_buffer), "%d\n", (int)getpid()); + ssize_t written; + int written_total = 0; + while((written = write(pid_fd, pid_buffer + written_total, pid_sz - written_total)) > 0 + && written_total < pid_sz) { + written_total += written; + } + close(pid_fd); + } else { + const char err_msg[] = "Failed to create PID file"; + slog(s, WEBDIS_ERROR, err_msg, sizeof(err_msg)-1); + if(errno) { + char *errno_msg = strerror(errno); + slog(s, WEBDIS_ERROR, errno_msg, strlen(errno_msg)); + } } } } @@ -211,8 +226,11 @@ server_start(struct server *s) { /* initialize libevent */ s->base = event_base_new(); + /* initialize logging before forking */ + slog_init(s); + if(s->cfg->daemonize) { - server_daemonize(s->cfg->pidfile); + server_daemonize(s, s->cfg->pidfile); /* sometimes event mech gets lost on fork */ if(event_reinit(s->base) != 0) { @@ -225,8 +243,6 @@ server_start(struct server *s) { signal(SIGPIPE, SIG_IGN); #endif - slog_init(s); - /* install signal handlers */ server_install_signal_handlers(s); diff --git a/src/websocket.c b/src/websocket.c index 2fdacbf..44ee6a6 100644 --- a/src/websocket.c +++ b/src/websocket.c @@ -355,7 +355,7 @@ ws_reply(struct cmd *cmd, const char *p, size_t sz) { memcpy(frame + 2, &sz16, 2); memcpy(frame + 4, p, sz); frame_sz = sz + 4; - } else if (sz > 65536) { + } else { /* sz > 65536 */ char sz64[8] = webdis_htonl64(sz); frame[1] = 127; memcpy(frame + 2, sz64, 8);