From 0467e4d9425b7dd129f6cfe90d7ef7d163bffe43 Mon Sep 17 00:00:00 2001 From: Prcuvu Date: Tue, 20 Jun 2017 21:39:27 +0800 Subject: [PATCH 1/3] Fix CMakeLists.txt for Win32 platform. --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5994132..cc329da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,7 @@ target_include_directories(${PROJECT_NAME} # install binary install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" ) From 184f2f0b1e16d46c1f002da1c0fa6a9573aac6e8 Mon Sep 17 00:00:00 2001 From: Prcuvu Date: Tue, 20 Jun 2017 21:39:52 +0800 Subject: [PATCH 2/3] Fixes for MSVC builds. --- src/base64.c | 3 +- src/cgi.c | 54 ++++++++++++++++++++++--- src/cookie.c | 14 +++++++ src/general.c | 18 +++++++-- src/list.c | 4 ++ src/session.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/string.c | 44 ++++++++++++-------- 7 files changed, 218 insertions(+), 28 deletions(-) diff --git a/src/base64.c b/src/base64.c index dd56fce..a3eb9d1 100644 --- a/src/base64.c +++ b/src/base64.c @@ -66,7 +66,8 @@ void decodeblock( unsigned char in[4], unsigned char out[3] ) char *str_base64_encode(char *str) { unsigned char in[3], out[4]; - unsigned int i, len, blocksout = 0, linesize = strlen(str); + unsigned int i, len, blocksout = 0; + size_t linesize = strlen(str); char *tmp = str; char *result = (char *)malloc((linesize + 3 - linesize % 3) * 4 / 3 + 1); diff --git a/src/cgi.c b/src/cgi.c index 904c207..69248b2 100644 --- a/src/cgi.c +++ b/src/cgi.c @@ -28,6 +28,22 @@ #include "cgi.h" #include "error.h" +#ifdef _MSC_VER +#define strcasecmp _stricmp + +char *strndup(const char *s, size_t n) +{ + size_t len = strnlen(s, n); + char *new = (char *)malloc(len + 1); + + if (new == NULL) + return NULL; + + new[len] = '\0'; + return (char *)memcpy(new, s, len); +} +#endif + // There's no reason to not have this initialised. static const char hextable[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -157,18 +173,32 @@ formvars *process_data(const char *query, formvars **start, formvars **last, formvars *cgi_process_form() { formvars *ret = NULL; - char *method = getenv("REQUEST_METHOD"); + char *method; +#ifdef _MSC_VER + size_t len; + _dupenv_s(&method, &len, "REQUEST_METHOD"); +#else + method = getenv("REQUEST_METHOD"); +#endif /* When METHOD has no contents, the default action is to process it as * GET method */ if (! method || ! strcasecmp("GET", method)) { - char *q = getenv("QUERY_STRING"); + char *q; +#ifdef _MSC_VER + _dupenv_s(&q, &len, "QUERY_STRING"); +#else + q = getenv("QUERY_STRING"); +#endif // Sometimes, GET comes without any data if (q && *q) ret = process_data(q, &formvars_start, &formvars_last, '=', '&'); +#ifdef _MSC_VER + free(q); +#endif } else if (! strcasecmp("POST", method)) { @@ -181,7 +211,11 @@ formvars *cgi_process_form() */ const unsigned long content_max = 1024UL * 1024UL; +#ifdef _MSC_VER + _dupenv_s(&length_str, &len, "CONTENT_LENGTH"); +#else length_str = getenv("CONTENT_LENGTH"); +#endif if (! length_str || ! *length_str) return NULL; @@ -201,9 +235,15 @@ formvars *cgi_process_form() '=', '&'); } +#ifdef _MSC_VER + free(length_str); +#endif free(post_data); } +#ifdef _MSC_VER + free(method); +#endif return ret; } @@ -259,10 +299,14 @@ int cgi_include(const char *path) if (stat (path, &fstats) == -1) goto err_input; - if (! (fcontents = malloc (fstats.st_size))) + if ((fcontents = malloc (fstats.st_size)) == NULL) goto err_memory; - if (! (fp = fopen (path, "r"))) +#ifdef _MSC_VER + if (fopen_s(&fp, path, "r") != 0) +#else + if ((fp = fopen (path, "r")) == NULL) +#endif goto err_input; if (fread (fcontents, sizeof(char), fstats.st_size, fp) != fstats.st_size) @@ -277,7 +321,7 @@ int cgi_include(const char *path) fclose (fp); free (fcontents); - return nwritten; + return (int)nwritten; err_input: libcgi_error(E_WARNING, "%s: file error: %s", __FUNCTION__, path); diff --git a/src/cookie.c b/src/cookie.c index 6e84c81..7f4342f 100644 --- a/src/cookie.c +++ b/src/cookie.c @@ -85,7 +85,13 @@ formvars *cgi_get_cookies() register size_t position; char *cookies, *aux, *str_unesc; +#ifdef _MSC_VER + size_t len; + _dupenv_s(&cookies, &len, "HTTP_COOKIE"); + if (cookies == NULL) +#else if ((cookies = getenv("HTTP_COOKIE")) == NULL) +#endif return NULL; str_unesc = cgi_unescape_special_chars(cookies); @@ -108,7 +114,11 @@ formvars *cgi_get_cookies() exit(EXIT_FAILURE); } +#ifdef _MSC_VER + strncpy_s(data->name, position + 1, cookies, position); +#else strncpy(data->name, cookies, position); +#endif data->name[position] = '\0'; position = 0; @@ -129,7 +139,11 @@ formvars *cgi_get_cookies() exit(-1); } +#ifdef _MSC_VER + strncpy_s(data->value, position + 1, cookies, position); +#else strncpy(data->value, cookies, position); +#endif data->value[position] = '\0'; slist_add(data, &cookies_start, &cookies_last); diff --git a/src/general.c b/src/general.c index 9662ece..08adb65 100644 --- a/src/general.c +++ b/src/general.c @@ -66,7 +66,7 @@ static int ncodes = sizeof(he) / sizeof(struct iso8859_15); char *htmlentities(const char *str) { char *buf; - int siz, len, i = 0, j; + size_t siz, len, i = 0, j; siz = strlen(str) + 1; @@ -83,7 +83,11 @@ char *htmlentities(const char *str) if (!buf) libcgi_error(E_MEMORY, "Failed to alloc memory at htmlentities, cgi.c"); +#ifdef _MSC_VER + strcpy_s(buf + i, siz - i, he[j].html); +#else strcpy(buf + i, he[j].html); +#endif i += len; break; } @@ -126,8 +130,12 @@ char **file(const char *filename, unsigned int *total) unsigned int lines, columms, char_count, i; char **str, *buf, ch; +#ifdef _MSC_VER + if (fopen_s(&fp, filename, "r") != 0) { +#else fp = fopen(filename, "r"); if (fp == NULL) { +#endif *total = 0; return NULL; @@ -157,7 +165,7 @@ char **file(const char *filename, unsigned int *total) libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__); while (!feof(fp)) { - ch = fgetc(fp); + ch = (char)fgetc(fp); // The next while() loop is to get all contents of actual line while ((ch != '\n') && (ch != EOF)) { @@ -172,7 +180,7 @@ char **file(const char *filename, unsigned int *total) } buf[i++] = ch; - ch = fgetc(fp); + ch = (char)fgetc(fp); } buf[i] = '\0'; @@ -184,7 +192,11 @@ char **file(const char *filename, unsigned int *total) exit(EXIT_FAILURE); } +#ifdef _MSC_VER + strncpy_s(str[lines - 1], char_count + 1, buf, char_count); +#else strncpy(str[lines - 1], buf, char_count); +#endif memset(buf, 0, char_count); lines++; diff --git a/src/list.c b/src/list.c index 43c17bd..af9de4f 100644 --- a/src/list.c +++ b/src/list.c @@ -28,6 +28,10 @@ #include "error.h" #include "cgi.h" +#ifdef _MSC_VER +#define strcasecmp _stricmp +#endif + // Add a new item to the list void slist_add(formvars *item, formvars **start, formvars **last) { diff --git a/src/session.c b/src/session.c index 981d544..739ea6b 100644 --- a/src/session.c +++ b/src/session.c @@ -60,17 +60,76 @@ #include #include #include +#ifdef _MSC_VER +#include +#else #include +#endif #include #include #include +#ifdef _MSC_VER +#include +#else #include +#endif #include #include "cgi.h" #include "session.h" #include "error.h" +#ifdef _MSC_VER +#include +#include + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) +#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else +#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + +int gettimeofday(struct timeval *tv, struct timezone *tz) +{ + FILETIME ft; + unsigned __int64 tmpres = 0; + static int tzflag = 0; + + if (tv != NULL) { + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + tmpres /= 10; + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + if (tz != NULL) { + if (!tzflag) { + _tzset(); + tzflag += 1; + } + long timezone; + _get_timezone(&timezone); + tz->tz_minuteswest = timezone / 60; + _get_daylight(&tz->tz_dsttime); + } + + return 0; +} + +#define unlink _unlink +#endif + // session id length #define SESS_ID_LEN 45 @@ -79,7 +138,7 @@ FILE *sess_file; static char sess_id[SESS_ID_LEN + 1]; static char *sess_fname = NULL; -static unsigned int save_path_len; +static size_t save_path_len; char SESSION_SAVE_PATH[255] = "/tmp/"; char SESSION_COOKIE_NAME[50] = "CGISID"; @@ -136,7 +195,7 @@ formvars *sess_list_last = NULL; void sess_generate_id() { static char table[] = "123456789abcdefghijlmnopqrstuvxzwyABCDEFGHIJLMOPQRSTUVXZYW"; - unsigned int len = strlen(table); + size_t len = strlen(table); register int i; save_path_len = strlen(SESSION_SAVE_PATH) + strlen(SESSION_FILE_PREFIX); @@ -162,8 +221,12 @@ int sess_create_file() srand(tv.tv_sec * tv.tv_usec * 100000); sess_generate_id(); +#ifdef _MSC_VER + if (fopen_s(&sess_file, sess_fname, "w") != 0) { +#else sess_file = fopen(sess_fname, "w"); if (!sess_file) { +#endif session_lasterror = SESS_CREATE_FILE; libcgi_error(E_WARNING, session_error_message[session_lasterror]); @@ -172,7 +235,11 @@ int sess_create_file() } // Changes file permission to 0600 +#ifdef _MSC_VER + _chmod(sess_fname, _S_IREAD | _S_IWRITE); +#else chmod(sess_fname, S_IRUSR|S_IWUSR); +#endif fclose(sess_file); return 1; @@ -217,9 +284,13 @@ int sess_file_rewrite() formvars *data; // Rewrites all data to session file +#ifdef _MSC_VER + if (fopen_s(&sess_file, sess_fname, "w") != 0) { +#else sess_file = fopen(sess_fname, "w"); if (!sess_file) { +#endif session_lasterror = SESS_OPEN_FILE; libcgi_error(E_WARNING, session_error_message[session_lasterror]); @@ -270,7 +341,11 @@ char *cgi_session_var(const char *var_name) **/ void cgi_session_cookie_name(const char *cookie_name) { +#ifdef _MSC_VER + strncpy_s(SESSION_COOKIE_NAME, sizeof SESSION_COOKIE_NAME, cookie_name, 49); +#else strncpy(SESSION_COOKIE_NAME, cookie_name, 49); +#endif } /** @@ -299,7 +374,11 @@ void cgi_session_cookie_name(const char *cookie_name) **/ void cgi_session_save_path(const char *path) { +#ifdef _MSC_VER + strncpy_s(SESSION_SAVE_PATH, sizeof SESSION_SAVE_PATH, path, 254); +#else strncpy(SESSION_SAVE_PATH, path, 254); +#endif } /** @@ -323,8 +402,12 @@ int cgi_session_register_var(const char *name, const char *value) } if (!cgi_session_var_exists(name)) { +#ifdef _MSC_VER + if (fopen_s(&sess_file, sess_fname, "a") != 0) { +#else sess_file = fopen(sess_fname, "a"); if (!sess_file) { +#endif session_lasterror = SESS_OPEN_FILE; libcgi_error(E_WARNING, session_error_message[session_lasterror]); @@ -348,10 +431,18 @@ int cgi_session_register_var(const char *name, const char *value) libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__); } +#ifdef _MSC_VER + strncpy_s(data->name, strlen(name) + 1, name, strlen(name)); +#else strncpy(data->name, name, strlen(name)); +#endif data->name[strlen(name)] = '\0'; +#ifdef _MSC_VER + strncpy_s(data->value, strlen(value) + 1, value, strlen(value)); +#else strncpy(data->value, value, strlen(value)); +#endif data->value[strlen(value)] = '\0'; if (!sess_list_last) @@ -380,7 +471,7 @@ int cgi_session_register_var(const char *name, const char *value) int cgi_session_alter_var(const char *name, const char *new_value) { register formvars *data; - unsigned int value_len; + size_t value_len; data = sess_list_start; while (data) { @@ -394,7 +485,11 @@ int cgi_session_alter_var(const char *name, const char *new_value) } +#ifdef _MSC_VER + strncpy_s(data->value, value_len + 1, new_value, value_len); +#else strncpy(data->value, new_value, value_len); +#endif data->value[value_len] = '\0'; sess_file_rewrite(); @@ -511,7 +606,11 @@ int cgi_session_start() sess_fname[SESS_ID_LEN + save_path_len] = '\0'; errno = 0; +#ifdef _MSC_VER + fopen_s(&fp, sess_fname, "r"); +#else fp = fopen(sess_fname, "r"); +#endif if (errno == ENOENT) { // The file doesn't exists. Create a new session if (sess_create_file()) { @@ -528,7 +627,11 @@ int cgi_session_start() } // Well, at this point we've the session ID +#ifdef _MSC_VER + strncpy_s(sess_id, sizeof sess_id, sid, SESS_ID_LEN); +#else strncpy(sess_id, sid, SESS_ID_LEN); +#endif sess_id[SESS_ID_LEN] = '\0'; // Now we need to read all the file contents diff --git a/src/string.c b/src/string.c index 410d58d..b68e743 100644 --- a/src/string.c +++ b/src/string.c @@ -53,7 +53,7 @@ char *addnslashes(char *s, int n) { char *tmp; - int len, j = 0; + size_t len, j = 0; if (s == NULL) return NULL; @@ -100,7 +100,7 @@ char *addnslashes(char *s, int n) */ char *addslashes(char *s) { - return addnslashes(s, strlen(s)); + return addnslashes(s, (int)strlen(s)); } /** @@ -157,7 +157,7 @@ char *stripnslashes(char *s, int n) */ char *stripslashes(char *str) { - return stripnslashes(str, strlen(str)); + return stripnslashes(str, (int)strlen(str)); } /** @@ -176,11 +176,11 @@ char *stripslashes(char *str) */ char * cgi_ltrim(char *str) { - char *r, *s; + char *r, *s; r = s = str; - /* nothing to do if str is NULL or zero-length */ + /* nothing to do if str is NULL or zero-length */ if (str && *str) { /* find first non-space character */ @@ -191,7 +191,7 @@ char * cgi_ltrim(char *str) * beyond them to the beginning of the source string */ if (s > r) - while ((*r++ = *s++)); + while ((*r++ = *s++) != '\0'); } return str; @@ -278,7 +278,11 @@ char *substr(char *src, const int start, const int count) return NULL; } +#ifdef _MSC_VER + strncpy_s(tmp, count + 1, src + start, count); +#else strncpy(tmp, src+start, count); +#endif tmp[count] = '\0'; return tmp; @@ -308,7 +312,7 @@ char **explode(char *src, const char *token, int *total) { char **str; register int i, j, count, item, start; - int len; + size_t len; if (!src || !token) { *total = 0; @@ -394,7 +398,7 @@ char **explode(char *src, const char *token, int *total) **/ char *str_nreplace(char *src, const char *delim, const char *with, int n) { - unsigned int w_len, i, n_len, counter; + size_t w_len, i, n_len, counter; char *buf; // w_len -> width length @@ -460,13 +464,13 @@ char *str_nreplace(char *src, const char *delim, const char *with, int n) **/ char *str_replace(char *str, const char *delim, const char *with) { - return str_nreplace(str, delim, with, strlen(str)); + return str_nreplace(str, delim, with, (int)strlen(str)); } // Just for compatibility with older versions of LibCGI char *replace(char *str, const char *delim, const char *with) { - return str_nreplace(str, delim, with, strlen(str)); + return str_nreplace(str, delim, with, (int)strlen(str)); } /** @@ -499,7 +503,7 @@ int strnpos(char *s, char *ch, unsigned int count) **/ int strpos(char *s, char *ch) { - return strnpos(s, ch, strlen(s)); + return strnpos(s, ch, (unsigned int)strlen(s)); } /** @@ -520,7 +524,7 @@ int strpos(char *s, char *ch) **/ char *strdel(char *s, int start, int count) { - register int i, len, contador = 0; + register size_t i, len, contador = 0; register char *tmp; len = strlen(s); @@ -564,7 +568,7 @@ char *recvline(FILE *s) if (i == siz) buf = realloc(buf, siz += BUFSIZ); - buf[i] = ch; + buf[i] = (char)ch; if (buf[i] == '\n') { buf[i] = '\0'; @@ -602,7 +606,7 @@ char *recvline(FILE *s) char *make_string(char *s, ...) { va_list ptr, bkp; - unsigned int len; + size_t len; char *str_return, *a, *str; str = s; @@ -632,7 +636,11 @@ char *make_string(char *s, ...) if (!str_return) libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__); +#ifdef _MSC_VER + vsprintf_s(str_return, len + 1, s, bkp); +#else vsprintf(str_return, s, bkp); +#endif va_end(ptr); va_end(bkp); @@ -645,18 +653,22 @@ char *make_string(char *s, ...) char *strcat_ex(const char *str1, const char *str2) { char *new_str; - unsigned int len; + size_t len; if (!str1 || !str2) return NULL; len = strlen(str1) + strlen(str2); - new_str = (char *)malloc((len + 1) * sizeof(char*)); + new_str = (char *)malloc((len + 1) * sizeof(char)); if (!new_str) libcgi_error(E_MEMORY, "%s, line %s", __FILE__, __LINE__); +#ifdef _MSC_VER + sprintf_s(new_str, len + 1, "%s%s", str1, str2); +#else sprintf(new_str, "%s%s", str1, str2); +#endif new_str[len] = '\0'; From 1195bcff433b192e2ec0267fc244259088e83ffe Mon Sep 17 00:00:00 2001 From: Prcuvu Date: Sat, 14 Jul 2018 19:06:07 +0800 Subject: [PATCH 3/3] Fix test/test.c for Windows --- test/test.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/test.c b/test/test.c index c315b5c..693d60d 100644 --- a/test/test.c +++ b/test/test.c @@ -3,7 +3,12 @@ #include #include #include +#ifdef _MSC_VER +#include +#define STDIN_FILENO _fileno(stdin) +#else #include +#endif #include "cgi_test.h" @@ -38,7 +43,11 @@ int main( int argc, char *argv[] ) /* require at least one argument to select test */ if ( argc < 2 ) return EXIT_FAILURE; +#ifdef _MSC_VER + check( !_pipe(pipe_, 1024, 0), "_pipe" ); +#else check( !pipe(pipe_), "pipe" ); +#endif check( STDIN_FILENO == dup2(pipe_[0], STDIN_FILENO), "dup2" ); return run_action( argv[1], actions, @@ -165,7 +174,9 @@ formvars *_post( const char *post_data ) "%zd", length); check( !putenv("REQUEST_METHOD=POST"), "putenv REQUEST_METHOD" ); +#ifndef _WIN32 check( !setenv("CONTENT_LENGTH", length_str, 1), "CONTENT_LENGTH" ); +#endif write(pipe_[1], post_data, length);