diff --git a/libhttp/http.h b/libhttp/http.h index 9bd2bf6..f1119eb 100644 --- a/libhttp/http.h +++ b/libhttp/http.h @@ -56,6 +56,8 @@ #define HTTP_SUSPEND 3 #define HTTP_PARTIAL_REPLY 4 +#define NO_MSG "\001" + #define NOINTR(x) ({ int i__; while ((i__ = (x)) < 0 && errno == EINTR); i__;}) typedef struct HashMap HashMap; diff --git a/libhttp/httpconnection.c b/libhttp/httpconnection.c index 7a6f619..af1ee03 100644 --- a/libhttp/httpconnection.c +++ b/libhttp/httpconnection.c @@ -63,8 +63,6 @@ #define MAX_HEADER_LENGTH (64<<10) #define CONNECTION_TIMEOUT (10*60) -static const char *NO_MSG; - static int httpPromoteToSSL(struct HttpConnection *http, const char *buf, int len) { if (http->ssl->enabled && !http->sslHndl) { @@ -1253,7 +1251,7 @@ void httpSendReply(struct HttpConnection *http, int code, char *body; char *title = code != 200 ? stringPrintf(NULL, "%d %s", code, msg) : NULL; char *details = NULL; - if (fmt != NULL) { + if (fmt != NULL && strcmp(fmt, NO_MSG)) { va_list ap; va_start(ap, fmt); details = vStringPrintf(NULL, fmt, ap); @@ -1274,7 +1272,7 @@ void httpSendReply(struct HttpConnection *http, int code, "%s\n" "\n" "\n", - title ? title : msg, fmt ? details : msg); + title ? title : msg, fmt && strcmp(fmt, NO_MSG) ? details : msg); free(details); free(title); char *response = NULL; diff --git a/libhttp/httpconnection.h b/libhttp/httpconnection.h index dfe210c..2c1e9cd 100644 --- a/libhttp/httpconnection.h +++ b/libhttp/httpconnection.h @@ -60,6 +60,8 @@ #define HTTP_SUSPEND 3 #define HTTP_PARTIAL_REPLY 4 +#define NO_MSG "\001" + struct HttpConnection { struct Server *server; struct ServerConnection *connection; diff --git a/libhttp/server.c b/libhttp/server.c index 0ae92b2..92de1b3 100644 --- a/libhttp/server.c +++ b/libhttp/server.c @@ -68,8 +68,6 @@ // API should be used, instead. #define MAX_PAYLOAD_LENGTH (64<<10) -static const char *NO_MSG; - time_t currentTime; struct PayLoad { diff --git a/libhttp/ssl.c b/libhttp/ssl.c index af01bff..f098e47 100644 --- a/libhttp/ssl.c +++ b/libhttp/ssl.c @@ -335,8 +335,9 @@ static int sslSNICallback(SSL *sslHndl, int *al, struct SSLSupport *ssl) { if (context == NULL) { check(context = SSL_CTX_new(SSLv23_server_method())); check(ssl->sniCertificatePattern); - char *certificate = stringPrintf(NULL, ssl->sniCertificatePattern, - serverName); + char *certificate = stringPrintfUnchecked(NULL, + ssl->sniCertificatePattern, + serverName); if (!SSL_CTX_use_certificate_file(context, certificate, SSL_FILETYPE_PEM)|| !SSL_CTX_use_PrivateKey_file(context, certificate, SSL_FILETYPE_PEM) || !SSL_CTX_check_private_key(context)) { diff --git a/logging/logging.c b/logging/logging.c index a386fd0..555464d 100644 --- a/logging/logging.c +++ b/logging/logging.c @@ -178,3 +178,6 @@ char *stringPrintf(char *buf, const char *fmt, ...) { va_end(ap); return s; } + +char *stringPrintfUnchecked(char *buf, const char *fmt, ...) + __attribute__((alias("stringPrintf"))); diff --git a/logging/logging.h b/logging/logging.h index 28d8f76..b96d856 100644 --- a/logging/logging.h +++ b/logging/logging.h @@ -89,5 +89,6 @@ void logSetLogLevel(int level); char *vStringPrintf(char *buf, const char *fmt, va_list ap); char *stringPrintf(char *buf, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +char *stringPrintfUnchecked(char *buf, const char *fmt, ...); #endif /* LOGGING_H__ */ diff --git a/shellinabox/externalfile.c b/shellinabox/externalfile.c index b7548c9..f16287c 100644 --- a/shellinabox/externalfile.c +++ b/shellinabox/externalfile.c @@ -59,8 +59,6 @@ #include "libhttp/server.h" #include "logging/logging.h" -static const char *NO_MSG; - static int externalFileHttpHandler(HttpConnection *http, void *arg, const char *buf, int len) { checkGraveyard(); diff --git a/shellinabox/shellinaboxd.c b/shellinabox/shellinaboxd.c index 3186709..18ac50f 100644 --- a/shellinabox/shellinaboxd.c +++ b/shellinabox/shellinaboxd.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -75,8 +76,6 @@ #define PORTNUM 4200 #define MAX_RESPONSE 2048 -static const char *NO_MSG; - static int port; static int portMin; static int portMax; @@ -155,6 +154,18 @@ static char *jsonEscape(const char *buf, int len) { return result; } +static int printfUnchecked(const char *format, ...) { + // Some Linux distributions enable -Wformat=2 by default. This is a + // very unfortunate decision, as that option generates a lot of false + // positives. We try to work around the problem by defining an unchecked + // version of "printf()" + va_list ap; + va_start(ap, format); + int rc = vprintf(format, ap); + va_end(ap); + return rc; +} + static int completePendingRequest(struct Session *session, const char *buf, int len, int maxLength) { // If there is no pending HTTP request, save the data and return @@ -970,7 +981,7 @@ int main(int argc, char * const argv[]) { "X-ShellInABox-Pid: %d\r\n" "Content-type: text/html; charset=utf-8\r\n\r\n", port, pid); - printf(cgiRoot, port, cgiSessionKey); + printfUnchecked(cgiRoot, port, cgiSessionKey); fflush(stdout); free(cgiRoot); check(!NOINTR(close(fds[1])));